iOS AVPlayer 学习
1 .使用环境:
在实际开发过程中 有需要展示流媒体的模块 ,需求非常简单 :播放 和 暂停 ,其实这个时候有很多选择 ,可以选择 MPMoviePlayerController(MediaPlayer.framework), AVAudioPlayer(AVFunction.framework)
但是考虑到扩展性,高度自定义性 我选择使用 AVPlayer. 事实是对的 后来需求又增加了, 还需要展示播放进度,缓冲进度,变化时间,视频时长等,还有对UI有要求,甚至不为过的说 要苹果手机那个AVPlayer app的播放效果.
其实 我是拒绝的 基因里带的反抗心理 但是还得去做啊 一天天的 就被产品虐待
2.关键核心代码
2.1 三个监听
2.1.1监听视频状态 key : “status” 是不是一个可播放状态 还是正在缓冲 还是加载失败等错误
2.1.2监听视频播放完成 :endTime这个时候 根据需求 做触发响应 要重播 那就做重播处理的方法 或者需要弹框 或者其他什么的方法
2.1.3监听视频播放过程: timeObserver 用来实时更新播放状态,播放进度 缓冲进度等
重点:
视频从播放开始 timeObserver 创建 停止播放 一定要有 timeObserver 的移除 防止空监听
同理 “status”,endTime 在切换视频 或者 disappear 视频控制器页面 时候 都要取消监听
保证”observer first :创建或重新创建 需要先release旧的对象 再add 并且结束使用 移除对应监听 防止空监听”
判断是否取消 “status”,endTime条件,我是判断 当前player 和 AVPlayerItem是否存在 存在则 取消. 但是 有时候 一些视频流本身的意外错误 ,用枚举也没拦住的话 很有可能意外 中的意外执行 ,也许会取消一个空监听,这个时候 我特意给取消监听加上了 try catch 目的很简单 防止崩溃啊,并且它和上下文关联的程度并不大,不会出现一个小错误滚啊滚滚成大错误的意外发生.
2.2 几个重要类
AVAsset:主要用于获取多媒体信息,是一个抽象类,不能直接使用。
AVURLAsset:AVAsset的子类,可以根据一个URL路径创建一个包含媒体信息的AVURLAsset对象。
AVPlayerItem:一个媒体资源管理对象,管理者视频的一些基本信息和状态,一个AVPlayerItem对应着一个视频资源。
(1)- (void)loadValuesAsynchronouslyForKeys:(NSArray<NSString *> *)keys completionHandler:(nullable void (^)(void))handler NS_AVAILABLE(10_7, 4_2); 该方法使用 获取 到 AVKeyValueStatus keyStatus 状态
typedef NS_ENUM(NSInteger, AVKeyValueStatus) {
AVKeyValueStatusUnknown,
AVKeyValueStatusLoading,
AVKeyValueStatusLoaded,
AVKeyValueStatusFailed,
AVKeyValueStatusCancelled
};
拦截错误failed 做提示 就不用再往下做多余执行了
如果 asset.playable 是真 则可以添加 status (先移除 上一次的响应监听 如果存在的话)
(2)监听status
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
typedef NS_ENUM(NSInteger, AVPlayerStatus) {
AVPlayerStatusUnknown,
AVPlayerStatusReadyToPlay,
AVPlayerStatusFailed
};
if([playerItem status] == AVPlayerStatusReadyToPlay) 是可以播放的状态,其他情况 按需求做提示 或者其他一些必要处理
(3)AVPlayerStatusReadyToPlay 可播放状态 如果 执行播放了 要添加timeObserver (先移除timeObserver 有必要的话), 然后处理UI 需要展示的相关视频信息
(4) 展示播放进度 用 UISlider 展示缓冲进度用UIProgressive. 然后 先 add slider 再add progressive 这里 特别要讲的是 如果 没有对视频触摸有特别要求 可以把他们都放在一个toolbarView上 方便集中处理 但是如果有特殊需求的话,还是建议 把他们直接add在视频存在的那个自定义View上. 我的处理 是add 在 视频的 那个View上 因为 还有一个 快进快退的功能
UISlider 高度 要通过 继承UISlider 的slider重写
(CGRect)trackRectForBounds:(CGRect)bounds 来设置 不然就是默认高度 (UIPorgressive 也是)
并且slider 原生的UI是圆角 现在要求是扁平化方角,处理办法 是用图片代替 设置进度颜色 就可以了
其次 是 拖动进度条的圆点 焦点区域过小不敏感,这个也是通过重写方法来扩大焦点区域的
//自定义 UISlider - Increase “hot spot(焦点区域)” size
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event {
CGRect bounds = self.bounds;
bounds = CGRectInset(bounds, -10, -15);//左右扩宽 10 像素 上下扩宽 15像素
return CGRectContainsPoint(bounds, point);
}
(4)快进与快退
关键有二
(1)触发时间点 ,我这里给sldier 添加了 两个方法 一个 touchDown 作为拖拽开始的响应方法 一个 touchUpinside 作为拖拽结束的响应 debug测过了 逻辑基本满足需求.如果 你想一直监听拖拽过程什么 也是可以的
这两个方法 保证了快进快退后 再恢复正常播放的业务逻辑,非常关键,此处你要考虑 timeObserver状态 展示进度时间的变化 拖拽slider的value变化
(2)在 touchUpinside 时候 要处理 视频的seekToTime问题 这个我的”CMTimeMake 和 CMTimeMakeWithSeconds”特地区分了 这两个创建一个CMTime的关键.
在拖拽结束后 seekToTime方法:
-(void)seekToTime:(CMTime)time toleranceBefore:(CMTime)toleranceBefore toleranceAfter:(CMTime)toleranceAfter completionHandler:(void (^)(BOOL finished))completionHandler NS_AVAILABLE(10_7, 5_0);
还有其他的seekToTime方法 但是在我的工程项目里 这个 是精准度最高的 不论视频的长短,拖拽都不会出现拖动按钮跳动(实际的问题就是精准度或者时间误差很大造成的)的问题
我处理这个精准度的问题花了好久,网上资源 丰富 不代表没有错误啊,我才发现我在slack flow上还没有评论他人的功能,资历尚浅,只得在下边添加了我对问题的评论.
所以我对 一个 seekToTime的问题是这么回答的 (其实我楼上的楼上 写错了 但是仍然获得了五个赞)
至此 顺利结束开发任务 好开心
后记:
其实流媒体的水很深, 比如相关的问题 还有 录视频 直播视频什么的 涉及HTTP Live Streaming(HLS)技术 慢慢学吧 路很长. 其实 我特别讨厌一些面试官问你 什么会不会的时候 当你说 不会 然后 他像抓到你小把柄似的 嘲笑你.我觉得 这样的人道行一定不会很深,很深的人往往不会这么筛选技术伙伴.也许他比你强,但也只是暂时的问题了.我觉得,有可持续的学习能力很重要,并且能在有效的时间解决问题.这个才是重点:不会,但是在规定时间内,我可以通过各种途径把目标技能 get了.这也就好了啊.我也没听过哪个大牛 上来大而全 什么都会啊.
但是面试的时候 作为我们应聘者 还是吃亏的 因为要谈钱啊 所以我们得有自我学习的驱动力不断增加自己的砝码.
致敬所有 在奋斗的IT同行们, 今天 我看到一篇新闻说 一个IT 带病工作 然后肺部感染 都好多个洞洞了 .突然有点心疼 . 大家都 要好好爱自己 ,健康最重要. 哈哈
不错的一篇概要,至少能让你基本了解几种播放操作流媒体的使用场景
http://www.cnblogs.com/kenshincui/p/4186022.html
HLS
http://www.cnblogs.com/haibindev/archive/2013/01/30/2880764.html
iOS AVPlayer 学习的更多相关文章
- IOS基础学习-2: UIButton
IOS基础学习-2: UIButton UIButton是一个标准的UIControl控件,UIKit提供了一组控件:UISwitch开关.UIButton按钮.UISegmentedContro ...
- iOS阶段学习第一天笔记(Mac终端的操作)
前言部分 原本从事的是.NET开发,一直在要不要转iOS 中犹豫徘徊,经过复杂的内心挣扎终于鼓起勇气辞职脱产学习iOS;希望通过四个月的 学习后能够拿到理想的薪资.以下是学习过程中的学习笔记,为了方便 ...
- ios网络学习------4 UIWebView的加载本地数据的三种方式
ios网络学习------4 UIWebView的加载本地数据的三种方式 分类: IOS2014-06-27 12:56 959人阅读 评论(0) 收藏 举报 UIWebView是IOS内置的浏览器, ...
- ios网络学习------6 json格式数据的请求处理
ios网络学习------6 json格式数据的请求处理 分类: IOS2014-06-30 20:33 471人阅读 评论(3) 收藏 举报 #import "MainViewContro ...
- iOS之学习资源收集--很好的IOS技术学习网站
点击图片也能打开相关的网站: https://boxueio.com/skill/swift http://ios.b2mp.cn/ http://gold.xitu.io/welcome/?utm_ ...
- ios开发之OC基础-ios开发学习路线图
本系列的文章主要来自于个人在学习前锋教育-欧阳坚老师的iOS开发教程之OC语言教学视频所做的笔记,边看视频,边记录课程知识点.建议大家先过一遍视频,在看视频的过程中记录知识点关键字,把把握重点,然后再 ...
- iOS手势学习UIGestureRecognizer & cocos2d 手势推荐
iOS手势学习UIGestureRecognizer & cocos2d 手势推荐 手势识别类型: UILongPressGestureRecognizer // 长按UIPanGestur ...
- 开源中国iOS客户端学习
开源中国iOS客户端学习 续写前言 <开源中国iOS客户端学习>续写前系列博客 http://blog.csdn.net/column/details/xfzl-kykhd.html ...
- 原 iOS深入学习(Block全面分析)http://my.oschina.net/leejan97/blog/268536
原 iOS深入学习(Block全面分析) 发表于1年前(2014-05-24 16:45) 阅读(26949) | 评论(14) 39人收藏此文章, 我要收藏 赞21 12月12日北京OSC源创会 ...
随机推荐
- iOS10开发需要注意的一些问题(转)
兼容iOS 10 资料整理笔记 2016-09-17 判若两人丶 CocoaChina ▲点击上方“CocoaChina”关注即可免费学习iOS开发 原文链接:http://www.jianshu.c ...
- WebException获取详细内容 记录
http://bbs.csdn.net/topics/390883361 来自此处. 问题.某个接口.返回错误消息用的是400.所以必须知道具体的内容. using System; using Sys ...
- POI Excel 冷冻线
冷冻线 Sheet.createFreezePane data bar and color scale SheetConditionalFormatting scf = sheet.getSheet ...
- java 证书 .cer 和 .pfx
作为文件形式存在的证书一般有这几种格式: 1.带有私钥的证书 由Public Key Cryptography Standards #12,PKCS#12标准定义,包含了公钥和私钥的二进制格式的证书形 ...
- javascript拼接html代码
转自开源中国社区:http://www.oschina.net/code/snippet_94055_21640经常做jsp开发的朋友可能遇到一个情况,显示列表数据不是table,而是div或者其他很 ...
- Python简单的线程池
class ThreadPool(object): def __init__(self, max_num=20): # 创建一个队列,队列里最多只能有10个数据 self.queue = queue. ...
- 12个十分实用的JavaScript小技巧
12个非常实用的JavaScript小技巧 在这篇文章中将给大家分享12个有关于JavaScript的小技巧.这些小技巧可能在你的实际工作中或许能帮助你解决一些问题. 使用!!操作符转换布尔值 有时候 ...
- php中使用curl来post一段json数据
场景:在调用第三方接口时经常需要使用到curl进行数据交互,在初次使用时遇到一些小问题,记录下来随时查阅. 封装curl相关方法便于使用,方法如下: /** * @param $url * @para ...
- Android开发:《Gradle Recipes for Android》阅读笔记1.2
在android开发中会需要配置使用app的android SDK的最低版本和目标版本,这个是bulidl.gradle的android模块设置.默认有以下几个设置: applicationId,这个 ...
- [Docker]学习笔记--搭建gitlab
Gitlab 是一个用于仓库管理系统的开源项目.使用Git作为代码管理工具,并在此基础上搭建起来的web服务. 详细介绍可以参照官网,https://about.gitlab.com/ 今天主要是通过 ...