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

flvtvl50  于 2023-08-08  发布在  iOS
关注(0)|答案(5)|浏览(294)

我遇到了一个奇怪的问题,希望有人能帮助我。
在我的iOS应用程序中,我使用MutableComposition创建了一个带有自定义配乐的视频,方法是将用户照片库中的视频和应用程序包中的音频文件结合起来。然后,我使用一个AVPlayerAVPlayerItem来使用我制作的自定义视频播放器向用户播放视频。
每次创建一个新的组合时,资产,播放器和组合都被清除,释放,它基本上从一个干净的初始化状态开始。
所有工作正常,直到4成功的视频创建后,每一个其他尝试创建播放器失败与错误Cannot Decode。它并不重要,如果它的相同的视频,我重新创建,有没有关系的大小/长度的视频或音频文件,它只是总是失败,正是在第五次尝试,像发条。一旦失败,就永远失败!
这很奇怪,因为它只是解码了同一个视频四次都没有问题,所以突然就失败了?如果有人有线索,请告诉我。

ecr0jaav

ecr0jaav1#

好吧,各位,我有这个问题的答案直接从苹果。我使用了我的一个开发人员TSI生命线来问这个问题,我将总结回答。
对于AVFoundation允许的并发视频播放器的数量存在限制。这是由于iOS硬件的限制。当前设备的限制是4个玩家。如果您创建了第5个播放器,则会出现“无法解码”错误。它并不限制AVPlayer或AVPlayerItem的示例数。更确切地说,是AVPlayerItem与AVPlayer的关联创建了一个“渲染管道”,您只能使用其中的4个。例如,这会产生新的渲染管缐:

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

字符串
我还被警告说,你不能假设你将有4条管道可供你使用。另一个应用程序可能正在使用一个或多个。的确,我在iPad上见过这种情况,但不清楚是哪个应用在使用管道。
所以,你看,这是完全没有记录的,但这是故事。

eit6fx6z

eit6fx6z2#

我在创建4个AVPlayer示例后遇到了相同的错误消息,但在我的情况下修复并不完全相同。也许这会帮助任何遇到这个问题的人。
我最终发现的是,AVPlayers并没有被释放时,我曾认为他们是。在我的情况下,我把我的AVPlayer视图控制器推到导航控制器上。即使我一次只创建一个AVPlayer示例,当视图控制器从导航控制器弹出时,它们也不会立即释放。在旧的View Controllers被清理之前,我很容易达到4个AVPlayer示例。
直到我确定之前的玩家都被释放了,这个问题才消失。为了完成,我释放了AVPlayerItem,AVPlayer,并在释放之前将AVPlayerLayer上的播放器设置为nil。
我想知道是否有一些限制AVPlayer示例,无意或没有。来自docs的相关信息:https://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/02_Playback.html
“多重玩家层次:您可以从单个AVPlayer示例创建任意多个AVPlayerLayer对象,但只有最近创建的此类层才会在屏幕上显示任何视频内容。

fv2wmkja

fv2wmkja3#

这一个绝对是杀了我,直到我想通了,从这个线程和其他一些线索。我的代码中最大的一个问题是,每次我想播放视频时,我都要示例化我的视频播放器控制器。现在,它在主控制器中被示例化 * 一次 *(在本例中,是我的DetailViewContoller):

@interface DetailViewController () {
    VideoPlayerViewController *videoPlayerViewController;
}

- (void) viewDidLoad
{
    [super viewDidLoad];

    videoPlayerViewController = [[VideoPlayerViewController alloc] initWithNibName: nil bundle: nil];
}

字符串
当我想显示一个视频时,我调用我的DetailViewController的startVideoPlayback方法:

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


(NOTE:我传递给它'videoUID' --一个唯一的标识符,用于在应用程序的另一部分创建视频。
在VideoPlayerViewController中(主要是从Apple的AVPlayerDemo示例中抄袭而来),一次性屏幕设置(初始化AVPlayer,设置工具栏等)在viewDidLoad中完成-现在只调用 * 一次 *,所有每个视频的设置都在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]]];
        }
    }
}

jogvjijk

jogvjijk4#

好的,我想出了一个解决方案,我希望这对任何可能偶然发现类似这个问题的人有帮助。
我的解决方案是在主线程上初始化AVPlayer和AVPlayerItem的资产,并确保在playerItem和播放器对象返回状态“ReadyToPlay”之前没有创建实际的AVPlayerLayer。
这被证明是棘手的隔离,我仍然不知道为什么它的工作的前4次,然后失败一贯的第5次。
直到,我不能真正包括代码,这不是一个问题的一行,甚至几个函数。这是一个复杂的问题,我无法从一开始就孤立出来。谢谢你的评论。

qxgroojn

qxgroojn5#

看起来这个问题可以由任何解码任务引起,而不仅仅是实际的玩家。
当我用generateCGImagesAsynchronously实现一个后台任务从当前播放的视频中提取帧时,我偶然遇到了这个问题
我需要在屏幕上显示4个视频,竞争条件有时会导致帧提取在视频开始播放之前开始,我会永远等待isReadyForDisplay
如果你不能在第一时间避免这种情况,我不确定什么是好的恢复策略,我可能会尝试replaceCurrentItem

相关问题