Inserting an HTTP stream into a AVMutableCompositi

2019-02-04 13:58发布

问题:

I am trying to insert an AVURLAsset of a AVPlayerItem that states AVPlayerItemStatusReadyToPlay into an AVMutableComposition like this:

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");
        }
    }
}

Unfortunately, all I get is this lousy error message from the attempt to invoke AVMutableComposition insertTimeRange:ofAsset:atTime:error:

2011-11-29 22:24:59.446 XXX[13626:10703] -[XXX addItemToComposition:] -- error: Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo=0x7699f30 {NSLocalizedFailureReason=An unknown error occurred (-12780), NSUnderlyingError=0xd124dd0 "The operation couldn’t be completed. (OSStatus error -12780.)", NSLocalizedDescription=The operation could not be completed}

What am I missing?

Why is it not possible to insert the item into the composition?

When inspecting the AVURLAsset of that AVPlayerItem I also noticed that the tracks array is allocated but empty. Could that be the reason, and if so, how do I get the AVURLAsset to properly hold valid tracks?

回答1:

Well, I got an answer from another source and I do not like it ...

It is apparently only possible to insert local items (assets) into an AVMutableComposition, remote items (like HTTP video streams) will not work.

The fact that the documentation does not say so and the fact that the error-message I am receiving is useless seems to be an omission by Apple. I did file a bug-report to improve that situation.

Apple Radar Bug Id: 10517711

Open Radar bug report.