使用AVMutableVideoComposition时,AVMutableComposition的怪异行为被冻结

我正在尝试使用AVMutableComposition合并多个video。 我面对的问题是,每当我尝试添加任何AVMutableVideoComposition来应用任何指令时,我的播放会在AVPlayer以6秒的时间间隔冻结。

另一个有趣的事情是,如果我使用相同的videoComposition导出后在iPad的照片应用程序中播放它,它会发挥很好。 那么为什么它在AVPlayer 6秒钟冻结?

码:

 AVMutableComposition *mutableComposition = [AVMutableComposition composition]; AVMutableCompositionTrack *videoCompositionTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; AVMutableCompositionTrack *audioCompositionTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; for (AVURLAsset *asset in assets) { AVAssetTrack *assetTrack; assetTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; AVAssetTrack *audioAssetTrack = [asset tracksWithMediaType:AVMediaTypeAudio].firstObject; NSError *error; [videoCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, assetTrack.timeRange.duration ) ofTrack:assetTrack atTime:time error:&error]; if (error) { NSLog(@"asset url :: %@",assetTrack.asset); NSLog(@"Error1 - %@", error.debugDescription); } [audioCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAssetTrack.timeRange.duration) ofTrack:audioAssetTrack atTime:time error:&error]; if (error) { NSLog(@"Error2 - %@", error.debugDescription); } time = CMTimeAdd(time, assetTrack.timeRange.duration); if (CGSizeEqualToSize(size, CGSizeZero)) { size = assetTrack.naturalSize;; } } AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; AVMutableVideoCompositionLayerInstruction *videoTrackLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoCompositionTrack]; mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, time); mainInstruction.layerInstructions = [NSArray arrayWithObjects:videoTrackLayerInstruction, nil]; AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition]; mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction]; mainCompositionInst.frameDuration = CMTimeMake(1, 30); mainCompositionInst.renderSize = size; pi = [AVPlayerItem playerItemWithAsset:mutableComposition]; pi.videoComposition = mainCompositionInst; 

另外,我知道问题大多是videoComposition因为如果我删除了videoComposition ,那么它在AVPlayer上播放的很好。

更新1 :我发现,当它冻结6秒后,如果我拖回滑块(即使用seekToTime ),它开始正常播放没有任何进一步的冻结。

即使video被冻结,audio也能继续播放。

更新2 :如果我只是继续使用具有相同AVMutableComposition导出它,并从导出的video加载资产,它工作正常。 所以就在我直接玩AVMutableComposition ,就出现了问题。

最后,我得到了解决这个问题的解决scheme。

playerItem的状态更改为.ReadyToPlay后,您应该播放。

请看下面。

 func startVideoPlayer() { let playerItem = AVPlayerItem(asset: self.composition!) playerItem.videoComposition = self.videoComposition! let player = AVPlayer(playerItem: playerItem) player.actionAtItemEnd = .None videoPlayerLayer = AVPlayerLayer(player: player) videoPlayerLayer!.frame = self.bounds /* add playerItem's observer */ player.addObserver(self, forKeyPath: "player.currentItem.status", options: .New, context: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerItemDidReachEnd:", name: AVPlayerItemDidPlayToEndTimeNotification, object: playerItem); self.layer.addSublayer(videoPlayerLayer!) } override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { if keyPath != nil && keyPath! == "player.currentItem.status" { if let newValue = change?[NSKeyValueChangeNewKey] { if AVPlayerStatus(rawValue: newValue as! Int) == .ReadyToPlay { playVideo() /* play after status is changed to .ReadyToPlay */ } } } else { super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context) } } func playerItemDidReachEnd(notification: NSNotification) { let playerItem = notification.object as! AVPlayerItem playerItem.seekToTime(kCMTimeZero) playVideo() } func playVideo() { videoPlayerLayer?.player!.play() }