将HTTP流插入AVMutableComposition

Til*_*ill 14 iphone avfoundation ios avplayer avcomposition

我试图插入指明了AVPlayerItem的AVURLAsset AVPlayerItemStatusReadyToPlayAVMutableComposition这样:

composition_ = [[AVMutableComposition alloc] init];
insertionPoint_ = kCMTimeZero;
item_ = [[AVPlayerItem playerItemWithURL:[NSURL URLWithString:@"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"]] retain];
[item_ addObserver:self forKeyPath:@"status" options:0 context:nil];
player_ = [[AVPlayer playerWithPlayerItem:item_] retain];
[player_ addObserver:self forKeyPath:@"currentItem.duration" options:0 context:nil];


/**
 * append a player-item to our composition 
 */
- (void)addItemToComposition:(AVPlayerItem *)item
{
    NSError *error = nil;
    VTRACE(@"item duration: %g", CMTimeGetSeconds(item.duration));
    if (![composition_ insertTimeRange:CMTimeRangeMake(kCMTimeZero, item.duration) 
                              ofAsset:item.asset
                               atTime:insertionPoint_ 
                                error:&error]) 
    {
        VTRACE(@"error: %@", error);
    }
}

/**
 * simplified value observer callback
 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([object isKindOfClass:[AVPlayerItem class]])
    {
        AVPlayerItem *item = (AVPlayerItem *)object;
        //playerItem status value changed?
        if ([keyPath isEqualToString:@"status"])
        {   //yes->
            switch(item.status)
            {
                case AVPlayerItemStatusFailed:
                    VTRACE(@"player item status failed");
                break;
                case AVPlayerItemStatusReadyToPlay:
                    VTRACE(@"player item status is ready to play");
                    [self addItemToComposition:player_.currentItem];
                break;
                case AVPlayerItemStatusUnknown:
                    VTRACE(@"player item status is unknown");
                break;
            }
        }
    }
    else if([object isKindOfClass:[AVPlayer class]])
    {
        if ([keyPath isEqualToString:@"currentItem.duration"])
        {   //yes->
            VTRACE(@"player item duration available");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,我得到的只是来自尝试调用的糟糕错误消息 AVMutableComposition insertTimeRange:ofAsset:atTime:error:

2011-11-29 22:24:59.446 XXX [13626:10703] - [XXX addItemToComposition:] - 错误:错误Domain = AVFoundationErrorDomain Code = -11800"操作无法完成"UserInfo = 0x7699f30 {NSLocalizedFailureReason =未知发生错误(-12780),NSUnderlyingError = 0xd124dd0"操作无法完成.(OSStatus错误-12780.)",NSLocalizedDescription =操作无法完成}

我错过了什么?

为什么不能将项目插入合成中?

在检查AVURLAsset时,AVPlayerItem我还注意到轨道数组已分配但为空.这可能是原因,如果是这样,我如何AVURLAsset才能正确地保持有效的曲目?

Til*_*ill 13

好吧,我从另一个来源得到答案,我不喜欢它......

显然只能将本地项目(资产)插入到AVMutableComposition远程项目(如HTTP视频流)中才能工作.

文档没有这样说的事实以及我收到的错误消息无用的事实似乎是Apple的遗漏.我确实提交了一份错误报告来改善这种情况.

Apple Radar Bug Id:10517711

打开Radar bug报告.

  • 还开着。但实际上,不仅是本地项目与`AVComposition` 一起工作,而是 HLS (.m3u8) 没有,大概是因为它是自适应的,所以有多个视频轨道可供选择,并且可以随时更改。因此,如果您的服务器上有一个 .mp4 可以正常工作,但不是 .m3u8。 (2认同)