AVPlayerItem失败,AVStatusFailed和错误代码“无法解码”

我遇到了一个奇怪的问题,我希望有人可以帮忙。

在我的iOS应用程序中,我通过将来自用户照片库的video与应用程序包中的audio文件相结合,使用MutableComposition创build一个带有自定义配乐的video。 然后,我使用AVPlayerAVPlayerItem使用我制作的自定义video播放器将video播放回给用户。

每次创build一个新的作品,资产,玩家和作品都被清除,释放,它基本上从干净的初始状态开始。

所有的工作正常,直到完全成功的4个video创build这种方式后,每隔一个尝试创build播放器失败,错误Cannot Decode 。 没有关系,如果它正在重新创build相同的video,没有关系的video或audio文件的大小/长度,它总是在第五次尝试,就像发条一样完全失败。 一旦失败,它将永远失败!

这很奇怪,因为它只是解码了同一个video四次没有问题,所以突然失败了? 所以,如果有人有线索,请让我知道。

好吧,我从苹果公司得到了这个答案。 我用我的一个开发人员TSI生​​命线来问这个问题,我会总结一下回应。

AVFoundation允许的并发video播放器数量有限制。 这是由于iOS硬件的限制。 目前设备的限制是4名玩家。 如果你创build了第五个播放器,你会得到“无法解码”的错误。 这不是对AVPlayer或AVPlayerItem的实例数量的限制。 相反,它是AVPlayerItem与创build“渲染pipe道”的AVPlayer的关联,并且您仅限于其中的4个。 例如,这会导致一个新的渲染pipe道:

 AVPlayer *player = [AVPlayer playerWithPlayerItem:somePlayerItem]; // assuming the AVPlayerItem is ready to go with an AVAsset that has been loaded 

我也被告知,你不能假设你将有4条pipe道可供你使用。 另一个应用程序可能会使用一个或多个。 事实上,我已经看到这发生在iPad上,但是不清楚哪个应用正在使用pipe线。

所以,你去了,这是完全没有文件,但这是故事。

创build了4个AVPlayer实例后,我碰到了同样的错误信息,但是我的情况并不完全一样。 也许这会帮助遇到这个问题的其他人。

我最终发现的是,当我以为他们是AVPlayers没有被释放。 在我的情况下,我推动我的AVPlayer视图控制器到导航控制器。 尽pipe我一次只创build一个AVPlayer实例,但是当视图控制器popup导航控制器时,它们不会立即被释放。 在清理旧的视图控制器之前,我很容易达到4个AVPlayer实例。

直到我确定之前的玩家被释放后,这个问题才消失。 为了完成,我发布了AVPlayerItem,AVPlayer,并将AVPlayerLayer上的播放器设置为零。

我不得不怀疑AVPlayer实例是否有一些限制,无意或无意。 来自文档的相关信息: https : //developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/02_Playback.html

“多个播放器层:您可以从一个AVPlayer实例创build任意多个AVPlayerLayer对象,但是只有最近创build的这样的层才能在屏幕上显示任何video内容。

好的,我想出了一个解决scheme,希望对任何可能遇到类似问题的人都有帮助。

在我的情况下,解决scheme是初始化AVPlayer的资产和主线程上的AVPlayerItem,并确保在playerItem和播放器对象返回状态“ReadyToPlay”之前,我不创build实际的AVPlayerLayer。

这被certificate是孤立的棘手,我仍然不知道为什么它前4次工作,然后在第五次一致失败。

直到我不能包含代码,这不是一行甚至几个函数的问题。 这是一个复杂的问题,我不能孤立开始。 感谢您的意见。

这个绝对是杀了我,直到我找出来,从这个线索和其他一些线索中找出线索。 我的代码中最大的一个问题就是我每次想要播放video的时候都会实例化我的video播放器控制器。 现在,它在主控制器(在这种情况下,我的DetailViewContoller)实例化一次

 @interface DetailViewController () { VideoPlayerViewController *videoPlayerViewController; } - (void) viewDidLoad { [super viewDidLoad]; videoPlayerViewController = [[VideoPlayerViewController alloc] initWithNibName: nil bundle: nil]; } 

当我想要显示video时,我调用了我的DetailViewController的startVideoPlayback方法:

 - (void) startVideoPlayback: (NSString *)videoUID { videoPlayerViewController.videoUID = videoUID; [self presentModalViewController: videoPlayerViewController animated: YES]; } 

(注意:我将它传递给'videoUID' – 一个唯一标识,用于在应用程序的另一部分创buildvideo。)

在VideoPlayerViewController(很大程度上来自Apple的AVPlayerDemo示例)中,一次性屏幕设置(初始化AVPlayer,设置工具栏等)在viewDidLoad中完成 – 现在只调用一次 ,video设置在viewWillAppear中完成,然后调用prepareToPlay

 - (void) prepareToPlay { [self initScrubberTimer]; [self syncPlayPauseButtons]; [self syncScrubber]; NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; //*** Retrieve and play video at associated with this videoUID NSString *destinationPath = [documentsDirectory stringByAppendingFormat: @"/%@.mov", videoUID]; if ([self fileExists: destinationPath]) { //*** Show the activity indicator spinny thing [pleaseWait startAnimating]; [self setURL: [NSURL fileURLWithPath: destinationPath]]; //*** Get things going with the first video in this session if (isFirst) { isFirst = NO; //*** Subseqeunt videos replace the first one } else { [self.mPlayer replaceCurrentItemWithPlayerItem: [AVPlayerItem playerItemWithURL: [NSURL fileURLWithPath: destinationPath]]]; } } }