Comportamiento extraño de congelación de AVMutableComposition mientras usa AVMutableVideoComposition

Estoy intentando combinar varios videos usando AVMutableComposition . El problema que me enfrento es que cada vez que trato de agregar cualquier AVMutableVideoComposition para aplicar cualquier instrucción, mi reproducción se congela en AVPlayer con una duración de 6 segundos exactos.

Otra cosa interesante es que funciona bien si lo juego en la aplicación Fotos del iPad después de exportar usando la misma videoComposition . Entonces, ¿por qué se congela en AVPlayer a los 6 segundos?

Código:

 AVMutableComposition *mutableComposition = [AVMutableComposition composition]; AVMutableCompositionTrack *videoCompositionTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo prefernetworkingTrackID:kCMPersistentTrackID_Invalid]; AVMutableCompositionTrack *audioCompositionTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio prefernetworkingTrackID: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; 

Además, sé que el problema es sobre todo videoComposition porque si videoComposition la videoComposition del videoComposition , entonces se reproduce bien en AVPlayer .

ACTUALIZACIÓN 1 : Acabo de descubrir que cuando se congela después de 6 segundos, si arrastro el control deslizante hacia atrás o hacia adelante (es decir, uso seekToTime ), comienza a reproducirse normalmente de nuevo sin más congelación.

También el audio sigue funcionando bien incluso cuando el video está congelado.

ACTUALIZACIÓN 2 : Si simplemente avance y lo exporte usando AVAssetExportSession con la misma AVMutableComposition , y cargue el activo del video exportado, funciona bien. Entonces, justo cuando juego AVMutableComposition directamente, surge el problema.

Finalmente, obtuve la solución para solucionar esto.

Deberías jugar después de que el estado playerItem se cambie a .ReadyToPlay.

Vea a continuación.

 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() }