MPMoviePlayerController 播放器偶现闪退bug修复

MPMoviePlayerController在播放在线视频时出现闪退

闪退出现的时机

当频繁切换视频或者网络不好时,播放在线视频就会出现闪退情况。bugly日志如下:

0 CoreFoundation 0x216862eb ___exceptionPreprocess + 127
1 libobjc.A.dylib 0x20e52dff objc_exception_throw + 31
2 AVFoundation 0x26baa613 -[AVPlayerItem _attachToPlayer:] + 319
3 AVFoundation 0x26b9a2b9 -[AVPlayer _insertItem:afterItem:] + 149
4 MediaPlayer 0x28f58097 -[MPQueuePlayer insertItem:afterItem:] + 51
5 MediaPlayer 0x28ed084b -[MPAVQueueCoordinator _syncPlayerItems] + 1495
6 MediaPlayer 0x28ed0067 -[MPAVQueueCoordinator _syncItemsWithPreviousItems:] + 1563
7 MediaPlayer 0x28ecef9b -[MPAVQueueCoordinator reloadItemsKeepingCurrentItem:] + 791
8 MediaPlayer 0x28f27d6b -[MPAVPlaylistManager connectPlayer] + 519
9 MediaPlayer 0x28e599d9 -[MPAVController _connectAVPlayer] + 217
10 MediaPlayer 0x28e5a9ed ___42-[MPAVController _serverConnectionDidDie:]_block_invoke + 45
11 libdispatch.dylib 0x21223dd7 __dispatch_call_block_and_release + 11
12 libdispatch.dylib 0x21223dc3 __dispatch_client_callout + 23
13 libdispatch.dylib 0x21228671 _dispatch_main_queue_callback_4CF + 1531
14 CoreFoundation 0x21648fc5 ___CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
15 CoreFoundation 0x216474bf ___CFRunLoopRun + 1591
16 CoreFoundation 0x21599bb9 CFRunLoopRunSpecific + 515
17 CoreFoundation 0x215999ad CFRunLoopRunInMode + 103

抛出的异常为
An AVPlayerItem cannot be associated with more than one instance of AVPlayer

闪退的分析

按照异常的描述,应该是尝试实例化多个播放器造成的。但是代码中已经其封装为单例模式,并且是线程安全的单例。然后推测会不会时一个播放源还没结束时去加载了另外一个播放源,从上面的日志栈中可以看到有队列MPQueuePlayer,所以推测setContentURL是添加到对应的queue中,而不是立即播放,所以应该不会出现实例化两个播放器的问题。再来看抛出的异常信号为NSInvalidArgumentException(SIGABRT)无效的参数,说明播放器在初始化或者播放的时候数据上出了问题。

解决方式

在MPMoviePlayerController中有一个属性movieSourceType来指定要播放的类型。官方文档中关于movieSourceType的描述:

The default value of this property is MPMovieSourceTypeUnknown . This property provides a clue to the playback system as to how it should download and buffer the movie content. If you know the source type of the movie, setting the value of this property before playback begins can improve the load times for the movie content. If you do not set the source type explicitly before playback, the movie player controller must gather this information, which might delay playback.

如果不指定movieSourceType会花费更多的时间来判断对应的视频类型,如果在网络不好的情况下,很可能加载不全造成了判断上的错误,造成了无效的参数异常。
设置对应的视频源类型即可解决:

self.player.movieSourceType = MPMovieSourceTypeStreaming;
self.player.contentURL = url;

你可能感兴趣的:(MPMoviePlayerController 播放器偶现闪退bug修复)