使用AVMutableComposition iPhone

我正在使用下面的代码,顺序stream式传输两个video。 但它没有在模拟器中显示任何video,它完全空白。

另外我怎样才能通过这两个video寻求。 就像,如果一个video是2分钟,第二个是3分钟。 现在我需要得到这些video的总时间,并通过它们来寻找。 当我将滑杆滑动到4分钟时,第二个video应该从第2分钟开始播放。

可能吗?

- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. NSURL *url1 = [NSURL URLWithString:@"http://www.tools4movies.com/dvd_catalyst_profile_samples/Harold%20Kumar%203%20Christmas%20bionic.mp4"]; NSURL *url2 = [NSURL URLWithString:@"http://www.tools4movies.com/dvd_catalyst_profile_samples/Harold%20Kumar%203%20Christmas%20tablet.mp4"]; NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey]; AVMutableComposition *composition = [[AVMutableComposition alloc] init]; asset1 = [[AVURLAsset alloc] initWithURL:url1 options:options]; AVURLAsset * asset2 = [[AVURLAsset alloc]initWithURL:url2 options:options]; CMTime insertionPoint = kCMTimeZero; NSError * error = nil; composition = [AVMutableComposition composition]; if (![composition insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset1.duration) ofAsset:asset1 atTime:insertionPoint error:&error]) { NSLog(@"error: %@",error); } insertionPoint = CMTimeAdd(insertionPoint, asset1.duration); if (![composition insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset2.duration) ofAsset:asset2 atTime:insertionPoint error:&error]) { NSLog(@"error: %@",error); } AVPlayerItem * item = [[AVPlayerItem alloc] initWithAsset:composition]; player = [AVPlayer playerWithPlayerItem:item]; AVPlayerLayer * layer = [AVPlayerLayer playerLayerWithPlayer:player]; [layer setFrame:CGRectMake(0, 0, 320, 480)]; [[[self view] layer] addSublayer:layer]; [player play]; } 

任何人都可以告诉我,我的代码中有什么错误?

模拟器不能显示video。 内build的UIImagePickerController或任何video控制器都不会工作。 它没有实现,并且大部分在iOS模拟器上显示为黑色或红色。 您必须在iOS目标上进行debugging。 有时debugging将无法正常工作。 使用NSLog()方法。 这将始终工作(即如果您编译时没有使用“发布”代码的debugging信息)

你可以寻求使用该播放器:

如果mp是你的媒体播放器:

 [mp pause]; CMTime position = mp.currentTime; // maybe replace something [mp replaceCurrentItemWithPlayerItem:[AVPlayerItem playerItemWithAsset:self.composition]]; [mp seekToTime:length]; [mp play]; 

概要:
编辑:使用组合和播放器项目
寻求:使用球员

这里是一个简短的例子,如何做到这一点(并已经线程安全):

 AVMutableComposition *_composition = [AVMutableComposition composition]; // iterate though all files // And build mutable composition for (int i = 0; i < filesCount; i++) { AVURLAsset* sourceAsset = nil; NSURL* movieURL = [NSURL fileURLWithPath:[paths objectAtIndex:i]]; sourceAsset = [AVURLAsset URLAssetWithURL:movieURL options:nil]; // calculate time CMTimeRange editRange = CMTimeRangeMake(CMTimeMake(0, 600), sourceAsset.duration); NSError *editError; BOOL result = [_composition insertTimeRange:editRange ofAsset:sourceAsset atTime:_composition.duration error:&editError]; dispatch_sync(dispatch_get_main_queue(), ^{ // maybe you need a progress bar self.loaderBar.progress = (float) i / filesCount; [self.loaderBar setNeedsDisplay]; }); } // make the composition threadsafe if you need it later self.composition = [[_composition copy] autorelease]; // Player wants mainthread? dispatch_sync(dispatch_get_main_queue(), ^{ mp = [AVPlayer playerWithPlayerItem:[[[AVPlayerItem alloc] initWithAsset:self.composition] autorelease]]; self.observer = [mp addPeriodicTimeObserverForInterval:CMTimeMake(60, 600) queue:nil usingBlock:^(CMTime time){ // this is our callback block to set the progressbar if (mp.status == AVPlayerStatusReadyToPlay) { float actualTime = time.value / time.timescale; // avoid division by zero if (time.value > 0.) { CMTime length = mp.currentItem.asset.duration; float lengthTime = length.value / length.timescale; if (lengthTime) { self.progressBar.value = actualTime / lengthTime; } else { self.progressBar.value = 0.0f; } }]; }); // the last task must be on mainthread again dispatch_sync(dispatch_get_main_queue(), ^{ // create our playerLayer self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:mp]; self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; self.playerLayer.frame = [self view].layer.bounds; // insert into our view (make it visible) [[self view].layer insertSublayer:self.playerLayer atIndex:0]; }); // and now do the playback, maybe mp is global (self.mp) // this depends on your needs [mp play]; }); 

我希望这有帮助。