记录一个iOS实现视频分片缓存拖拽快进不能播放的问题
代码现状
首先来看一下我们将视频数据塞给请求的代码
- (void)finishLoadingWithLoadingRequest:(IdiotResourceTask *)task {// printf("哈哈执行到这里执行到到这里\n");printf("哈哈哈数量数量%ld\n", self.taskList.count);//填充信息task.loadingRequest.contentInformationRequest.contentType = @"video/mp4";task.loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES;task.loadingRequest.contentInformationRequest.contentLength = task.resource.fileLength;if (task.resource.fileLength <= 0) {NSLog(@"requestTask.fileLength <= 0");}printf("哈哈哈1111执行执行执行%lld点 %lld 一 %lld %p %p\n", task.loadingRequest.dataRequest.requestedOffset,task.loadingRequest.dataRequest.currentOffset, task.resource.requestOffset, task.loadingRequest, task);//读文件,填充数据long long cacheLength = task.resource.cacheLength;long long requestedOffset = task.loadingRequest.dataRequest.requestedOffset;if (task.loadingRequest.dataRequest.currentOffset != 0) {requestedOffset = task.loadingRequest.dataRequest.currentOffset;}if (requestedOffset < task.resource.requestOffset) {/*这里是说明视频请求对象的offset小于当前任务的resouce 的offset注意:task.resouce,是一开始播放创建的resouce或者拖拽之后创建的resouce即一段连续不中断的资源对应一个resouce,如果当前当前视频请求的offset小于task.resouce.offset,说明该resouce 和当前request没有重合部分,要返回注意这里不能加上 请求的.dataRequest.requestedLength 然后和task.resouce.requestoffset比较,因为填充数据要从请求的开头就是offset开始填充*/printf("哈哈哈返回111111 \n");return;}long long paddingOffset = requestedOffset - task.resource.requestOffset;long long canReadLength = cacheLength - paddingOffset;if (canReadLength <= 0) {printf("哈哈哈返回222222 %lld\n", canReadLength);return;}long long respondLength = MIN(canReadLength, task.loadingRequest.dataRequest.requestedLength);NSFileHandle * handle = [IdiotFileManager fileHandleForReadingAtPath:task.resource.cachePath];[handle seekToFileOffset:paddingOffset];[task.loadingRequest.dataRequest respondWithData:[handle readDataOfLength:[[NSNumber numberWithLongLong:respondLength] unsignedIntegerValue]]];
// printf("哈哈哈匹配到匹配到的长度%lld %lld %lld %lld %lld\n",respondLength,task.loadingRequest.dataRequest.requestedLength, task.loadingRequest.dataRequest.requestedOffset, task.loadingRequest.dataRequest.currentOffset, task.resource.requestOffset);[handle closeFile];//如果完全响应了所需要的数据,则完成long long nowendOffset = requestedOffset + canReadLength;long long reqEndOffset = task.loadingRequest.dataRequest.requestedOffset + task.loadingRequest.dataRequest.requestedLength;printf("哈哈哈哈差别差别%lld\n",reqEndOffset - nowendOffset);if (nowendOffset >= reqEndOffset) {[task.loadingRequest finishLoading];printf("哈哈哈主动删除%lld %lld %p\n",nowendOffset, reqEndOffset, task);[self removeLoadingRequest:task.loadingRequest];return;}}
遇到的问题
拖拽之后的操作
- (void)seekToTime:(NSTimeInterval)time completionHandler:(void (^ __nullable)(BOOL finished))completionHandler {if (self.totalTime > 0) {CMTime seekTime = CMTimeMake(time, 1);WEAKSELF[_player seekToTime:seekTime toleranceBefore:kCMTimeZero toleranceAfter:CMTimeMake(1, 1) completionHandler:^(BOOL finished) {// 视频跳转回调[weakSelf play];} else {self.seekTime = time;}
}
操作之后的结果发现视频不能播放了
查看执行的流程如下



后来经过多次调试发现,是我们seek的时候没有暂停,造成原来的请求还在,就会获取一个offset很小的请求,从而移除拖动之后的请求,造成无法播放
解决方法
修改之后的代码
就是seek之前 pause
- (void)seekToTime:(NSTimeInterval)time completionHandler:(void (^ __nullable)(BOOL finished))completionHandler {self.resourceLoader.seek = YES;if (self.totalTime > 0) {[self.player pause];CMTime seekTime = CMTimeMake(time, 1);WEAKSELF[_player seekToTime:seekTime toleranceBefore:CMTimeMake(1,1) toleranceAfter:CMTimeMake(1,1) completionHandler:^(BOOL finished) {[weakSelf play];}];} else {self.seekTime = time;}
}
表现
拖拽之后,视频可以正常播放

相关文章:
记录一个iOS实现视频分片缓存拖拽快进不能播放的问题
代码现状 首先来看一下我们将视频数据塞给请求的代码 - (void)finishLoadingWithLoadingRequest:(IdiotResourceTask *)task {// printf("哈哈执行到这里执行到到这里\n");printf("哈哈哈数量数量%ld\n", self.taskList.count);//填充信息task.loadingRe…...
如何解决 503 Service Temporarily Unavailable?
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🐅🐾猫头虎建议程序员必备技术栈一览表📖: 🛠️ 全栈技术 Full Stack: 📚…...
keil报错:Flash Download failed - Could not load file‘..\..\Output\Template.axf
keil报错:Flash Download failed - Could not load file’…\Output\Template.axf,如下图所示: 原因是很多.h文件没有定义位置,可以按照下图操作: 而且,如果是想使用压缩包,那一定要关闭keil后…...
从一到无穷大 #16 ByteSeries,思考内存时序数据库的必要性
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。 引言 在[3]中我基于Gorilla讨论了时序数据库设置cache的可行性,最后得出结论&…...
分支和远程仓库
分支 查看分支 git branch -v 创建分支 git branch 分支名 切换分支 git checkout 分支名 合并分支 git merge 分支名 把指定的分支合并到当前分支上 查看当前所有远程地址别名: git remote -v 起别名: git remote add 别名 远程地址推送本地分支上的…...
编译原理 —— 编译器
文章目录 编译原理阶段词法分析器语法分析器语义分析器中间代码生成器代码优化器代码生成器 编译原理阶段 编译器分为9个阶段来将我们所编写的高级代码编译为计算机可执行的机器码 源程序词法分析器语法分析器语义分析器中间代码生成器独立于机器的代码优化器代码生成器依赖于…...
Python灰帽编程——错误异常处理与面向对象
文章目录 错误异常处理与面向对象1. 错误和异常1.1 基本概念1.1.1 Python 异常 1.2 检测(捕获)异常1.2.1 try except 语句1.2.2 捕获多种异常1.2.3 捕获所有异常 1.3 处理异常1.4 特殊场景1.4.1 with 语句 1.5 脚本完善 2. 内网主机存活检测程序2.1 scap…...
【每日一题】154. 寻找旋转排序数组中的最小值 II
154. 寻找旋转排序数组中的最小值 II - 力扣(LeetCode) 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums [0,1,4,4,5,6,7] 在变化后可能得到࿱…...
Linux中如何获取输入设备(如触摸屏、按键等)的事件信息
Linux中如何获取输入设备(如触摸屏、按键等)的事件信息 在Linux中,可以使用getevent命令来获取输入设备(如触摸屏、按键等)的事件信息。如果你想在C程序中获取输入设备事件,可以使用以下步骤: …...
Java学习day05:排序,选择、冒泡、快速、二分、杨辉三角
声明:该专栏本人重新过一遍java知识点时候的笔记汇总,主要是每天的知识点题解,算是让自己巩固复习,也希望能给初学的朋友们一点帮助,大佬们不喜勿喷(抱拳了老铁!) Java学习day05:排序࿰…...
Mybatis的mapper.xml批量插入、修改sql
今天要有个功能,要进行一批数据的插入和修改,为了不频繁调用数据库,所以想到了批量插入和修改,因为从毕业后,就没写过批量插入和批量修改,所以在这里记录一下,避免后续再遇到忘记怎么写了 批量…...
Centos7部署单机版MongoDB
目录 Centos7部署单机版MongoDBMongoDB介绍数据模型索引分布式高可用性查询语言驱动和社区用途缺点 下载并解压安装包创建相关文件夹和文件编辑mongod.conf文件启动mongodb创建管理员用户终止MongoDB服务配置自启动服务关闭SELinux编辑自启动服务文件mongodb服务命令 Centos7部…...
Docker实战-第一章欢迎来到Docker世界
Docker基础 什么是Docker docker是包括一个命令行程序、后台守护进程和一组远程服务,它简化了安装、运行、发布和删除软件的工作。docker实现的基础是UNIX的容器技术。所以在docker出世之前已经有容器的概念,而且像谷歌一类公司也在探索自己的容器&…...
初识C语言——详细入门一(系统性学习day4)
目录 前言 一、C语言简单介绍、特点、基本构成 简单介绍: 特点: 基本构成: 二、认识C语言程序 标准格式: 简单C程序: 三、基本构成分类详细介绍 (1)关键字 (2…...
python 学习笔记(6)—— Flask 、MySql
目录 Flask 1、起步 2、渲染项目的首页 3、处理无参数的 GET 请求 4、处理有 query 参数的 GET 请求 6、处理 params 参数的 get 请求 6、处理 application/json 类型请求体的 POST 请求 7、根据参数渲染模板页面 8、上传文件 数据库操作(mysql࿰…...
Deepin下vsftp服务安装配置虚拟用户
1. 系统环境 Deepin20.9 2. 在线安装 # apt install -y vsftp //安装ftp服务软件 # apt install -y db-util //安装虚拟用户密码库处理软件 3. 离线安装 3.1 下载依赖包 # apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests --n…...
OpenpyxlWriter‘ object has no attribute ‘save‘
问题 将实验结果保存为EXCEL,报错“OpenpyxlWriter‘ object has no attribute ‘save‘” data_df pd.DataFrame(Experiment_result) #关键1,将ndarray格式转换为DataFrame writer pd.ExcelWriter(./results/ args.model_num _args.data_name …...
ES6(三)
文章目录 Promise概念作用回调地狱Promise使用对象的状态Promise.allPromise.race Generator 函数概念基本语法异步流程 Class语法类的写法getter与setter静态属性和静态方法继承模块化 Promise 概念 Promise 是异步编程的一种解决方案,比传统的解决方案回调函数,…...
Android 数据库封装(SQLite)
Android 数据库操作(SQLite) Android 数据库操作(SQLite)动态预览使用初始化生成表实体类插入数据批量插入删除数据删除全部修改数据查找(列表)查找(单条)条件查找(列表&…...
Git从入门到起飞(详细)
Git从入门到起飞 Git从入门到起飞什么是Git?使用git前提(注册git)下载Git在Windows上安装Git在macOS上安装Git在Linux上安装Git 配置Git配置全局用户信息配置文本编辑器 创建第一个Git仓库初始化仓库拉取代码添加文件到仓库提交更改推送 Git基本操作查看提交历史比较…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...
