Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play AVMutableComposition with AVPlayer?

I'm trying to get two videos to play sequentially. I've tried AVQueuePlayer but there's a huge "burp" between the two clips. I need to them to play without interruption.

So I'm trying to use AVMutableComposition and an AVPlayer but can't get it right.

Here's my code (ignore memory leaks, just testing in an empty project..):

composition = [[AVMutableComposition alloc] init];

NSString * path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"mp4"];
NSURL * url = [NSURL fileURLWithPath:path];
AVURLAsset * asset = [[AVURLAsset alloc] initWithURL:url options:nil];

NSError * error = NULL;
[composition insertTimeRange:CMTimeRangeMake(CMTimeMake(0,1000),CMTimeMake(4,1000)) ofAsset:asset atTime:CMTimeMake(0,1000) error:&error];
if(error) NSLog(@"error: %@",error);

path = [[NSBundle mainBundle] pathForResource:@"chug1" ofType:@"mp4"];
url = [NSURL fileURLWithPath:path];
asset = [[AVURLAsset alloc] initWithURL:url options:nil];

error = NULL;
[composition insertTimeRange:CMTimeRangeMake(CMTimeMake(0,1000),CMTimeMake(3,1000)) ofAsset:asset atTime:CMTimeMake(4.1,1000) error:&error];
if(error) NSLog(@"error: %@",error);

AVPlayerItem * item = [[AVPlayerItem alloc] initWithAsset:composition];
AVPlayer * player = [AVPlayer playerWithPlayerItem:item];
AVPlayerLayer * layer = [AVPlayerLayer playerLayerWithPlayer:player];

[layer setFrame:CGRectMake(0, 0, 320, 480)];
[[[self view] layer] addSublayer:layer];
[player play];

The code seems right to me. The first frame of each video is actually rendered to the screen. But the video doesn't play at all. I'm I missing something? Do I need to figure out how to use the MutableTrack stuff?

like image 584
gngrwzrd Avatar asked Oct 15 '11 01:10

gngrwzrd


1 Answers

Maybe you're using the wrong time insertion points and durations, both depends on actual video assets. I'd write something like this:

CMTime insertionPoint = kCMTimeZero;
NSError * error = nil;
composition = [AVMutableComposition composition];
asset = /* obtain asset #1 */
if (![composition insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) 
                          ofAsset:asset 
                           atTime:insertionPoint 
                            error:&error]) 
{
    NSLog(@"error: %@",error);
}
insertionPoint = CMTimeAdd(insertionPoint, asset.duration);

asset = /* obtain asset #2 */
if (![composition insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) 
                          ofAsset:asset 
                           atTime:insertionPoint 
                            error:&error]) 
{
    NSLog(@"error: %@",error);
}
...
/* playback stuff */
like image 65
djromero Avatar answered Nov 01 '22 03:11

djromero