关于 AVPlayerViewController 的自动播放

2018-06-28  本文已影响90人  喝杯开水压压惊

问题:由于新需求需要类似于淘宝那种:如果商品有视频,点击商品打开播放器直接播放。
需求确认,只要简单的播放下视频就行,我就不用三方了,直接用系统自带的AVPlayerViewController了

用过AVPlayerViewController的,应该遇到过,这东西它加载好视频后,不会自动播放。

解决思路:监听AVPlayer中的status,在AVPlayerStatusReadyToPlay时候调用播放。

1.继承AVPlayerViewController(Apple的文档说不要继承这东西,会出现未知错误),监听下status就行。

2.未知错误,还是有点担心的,那就不继承了,在AVPlayerViewController的category中去实现监听

注意(在category中):
由于需要对status进行监听,在category中实现(observeValueForKeyPath:ofObject:change:context:)时,AVPlayerViewController(自身也监听了一些东西)本身就有实现(observeValueForKeyPath:ofObject:change:context:)

1.在category实现的(observeValueForKeyPath:ofObject:change:context:)中,需要判断:如果是我们写的监听,那就做自己处理,如果是AVPlayerViewController自身的监听,那就调用AVPlayerViewController的(observeValueForKeyPath:ofObject:change:context:)。

2.我们需要知道:分类中实现的方法(包括相同的方法),它会插入到该类/实例的方法列表里(相同方法并不会覆盖,而是插入到列表的前面,category中的会比原类中的排的靠前)。所以在category中如果只是简单的 [self observeValueForKeyPath:keyPath ofObject:object change:change context:context] 那么它实际上在往category的(observeValueForKeyPath:ofObject:change:context:)发消息,这就循环了。

解决:通过runtime 获取该类/实例的方法列表,遍历出靠后的那个(observeValueForKeyPath:ofObject:change:context:)就是AVPlayerViewController实现的。

坑:通过runtime 获取该类/实例的方法列表时,不要直接拿到AVPlayerViewController (observeValueForKeyPath:ofObject:change:context:的SEL ,直接通过SEL去执行。因为SEL类似于一个标签/编号,直接通过SEL去执行实际还是找到的是category中的实现,这样就回到了上面说的循环了,要通过SEL去获取方法的IMP(这个自己去百度),通过IMP去执行。

最后:千万记得销毁自己的监听,别在category 中的dealloc销毁(AVPlayerViewController中是否实现了dealloc 你不知道),最好在viewDidDisappear中销毁。

上一篇下一篇

猜你喜欢

热点阅读