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

posted on 2016-05-02 21:14  ACM_Someone like you  阅读(2609)  评论(0编辑  收藏  举报

导航