Inserting an HTTP stream into a AVMutableComposition
Asked Answered
A

1

16

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?

Aleen answered 29/11, 2011 at 22:7 Comment(0)
A
14

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.

Aleen answered 2/12, 2011 at 10:57 Comment(2)
Report status is still Open, since 2011Reseda
Still open. But actually it's not only local items that work with AVComposition, rather it's HLS (.m3u8) that doesn't, presumably because it's adaptive so has multiple video tracks to choose from and can change at any time. So if you have a .mp4 on a server that will work ok, but not a .m3u8.Schifra

© 2022 - 2024 — McMap. All rights reserved.