我的视频处理应用程序中发生了一次奇怪的崩溃.它使用AVFoundation处理视频和视频.用于过滤的音频和GPU
Image.我自己从未遇到过这个问题,但在将它发布到App Store之后,它经常出现在Crashlytics中.这是崩溃的日志:
Thread : Crashed: AVPlayerItemOutput queue 0 libobjc.A.dylib 0x00000001986f80b4 objc_retain + 20 1 libsystem_blocks.dylib 0x0000000198d79bf8 _Block_object_assign + 320 2 AVFoundation 0x0000000186895a34 __copy_helper_block_171 + 36 3 libsystem_blocks.dylib 0x0000000198d79738 _Block_copy_internal + 384 4 libdispatch.dylib 0x0000000198d252fc _dispatch_Block_copy + 36 5 libdispatch.dylib 0x0000000198d2685c dispatch_async + 68 6 AVFoundation 0x00000001868959ac -[AVPlayerItemVideoOutput _dispatchOutputSequenceWasFlushed] + 112 7 libdispatch.dylib 0x0000000198d2536c _dispatch_client_callout + 16 8 libdispatch.dylib 0x0000000198d2e6e8 _dispatch_barrier_sync_f_invoke + 76 9 AVFoundation 0x00000001868940a8 AVPlayerItemVideoOutput_figVCSequentialAvailable + 196 10 MediaToolBox 0x000000018a3c16f8 FigVisualContextImageAvailableSequential + 108 11 MediaToolBox 0x000000018a348ce8 itemremote_postNotificationWithPayload + 3996 12 MediaToolBox 0x000000018a342d60 FigPlayerRemoteCallbacksServer_SendNotifyPing + 924 13 MediaToolBox 0x000000018a342998 _XSendNotifyPing + 60 14 MediaToolBox 0x000000018a33f0d4 figmoviecallbacks_server + 112 15 MediaToolBox 0x000000018a33f018 fpr_ClientPortCallBack + 208 16 CoreFoundation 0x0000000187f44ce0 __CFMachPortPerform + 180 17 CoreFoundation 0x0000000187f598fc __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 56 18 CoreFoundation 0x0000000187f5985c __CFRunLoopDoSource1 + 436 19 CoreFoundation 0x0000000187f577dc __CFRunLoopRun + 1640 20 CoreFoundation 0x0000000187e851f4 CFRunLoopRunSpecific + 396 21 GraphicsServices 0x00000001910135a4 GSEventRunModal + 168 22 UIKit 0x000000018c7b6784 UIApplicationMain + 1488 23 MerryVideoEditor 0x000000010024b804 main (main.m:16) 24 libdyld.dylib 0x0000000198d4ea08 start + 4
这就是我将AVFoundation连接到GPUImage的方法:
class ProjectEditorViewController: UIViewController { private var videoPlayerView = VideoPlayerView() private var movieFile: GPUImageMovie! private var currentComposition: AVComposition! //...and other properties } // MARK: - Filtering & Playback extension ProjectEditorViewController{ func updatePlayer() { currentFilter.removeAllTargets() movieFile?.removeAllTargets() movieFile?.endProcessing() let time = self.videoPlayerView.player?.currentItem.currentTime() ?? kCMTimeZero let (composition,audioMix) = compositionBuilder.buildCompositionFromTimeLine(timeLine) videoPlayerView.setAsset(composition) videoPlayerView.playerItem.audioMix = audioMix movieFile = GPUImageMovie(playerItem: videoPlayerView.player.currentItem) currentFilter.applyFromOutput(movieFile,toInput: gpuPlayerView) movieFile.startProcessing() addSyncLayerIfNeededForComposition(composition) videoPlayerView.player.seekToTime(time,toleranceBefore: kPlayerToleranceSeekTime,toleranceAfter: kPlayerToleranceSeekTime) currentComposition = composition } func updatePlayerFilter(){ if movieFile != nil{ movieFile.removeAllTargets() currentFilter.applyFromOutput(movieFile,toInput: gpuPlayerView) if(!videoPlayerView.isPlaying) { movieFile.startProcessing() } addSyncLayerIfNeededForComposition(currentComposition) }else{ updatePlayer() } } }
解决方法
这是GPUImageMovie中的一个问题 – 当实例将自身添加为AVPlayerItemVideoOutput委托时:
[playerItemOutput setDelegate:self queue:videoProcessingQueue],当GPUImageMovie实例解除分配时,playerItemOutput不释放其委托.稍后,这会导致来自释放对象的方法调用(outputSequenceWasFlushed :),然后您就会崩溃.这是在NSZombie探测器的帮助下找到的,我通过在GPUImageMovie dealloc方法中添加它来修复它:[playerItemOutput setDelegate:nil queue:nil];
[playerItemOutput setDelegate:self queue:videoProcessingQueue],当GPUImageMovie实例解除分配时,playerItemOutput不释放其委托.稍后,这会导致来自释放对象的方法调用(outputSequenceWasFlushed :),然后您就会崩溃.这是在NSZombie探测器的帮助下找到的,我通过在GPUImageMovie dealloc方法中添加它来修复它:[playerItemOutput setDelegate:nil queue:nil];
祝你好运,尼基塔;)