Ios AvasseTraderTrackOutput挂起在copyNextSampleBuffer上

Ios AvasseTraderTrackOutput挂起在copyNextSampleBuffer上,ios,avfoundation,Ios,Avfoundation,我用avassetwitter解决了这个问题。有时,我的视频写作会话会挂起。在检查了当前在我的设备上运行的线程之后,我发现整个视频处理都在等待copyNextSampleBuffer返回。我不知道是什么导致了这个问题。有人成功地克服了这个问题吗 下面是从仪器捕获的线程转储。它结束于mach\u msg\u trap。 视频处理环路 更新 资产读取器的源资产是AVMutableComposition,它由几个指向照片库的avurlaste(即url=“assets-library://asset

我用
avassetwitter
解决了这个问题。有时,我的视频写作会话会挂起。在检查了当前在我的设备上运行的线程之后,我发现整个视频处理都在等待
copyNextSampleBuffer
返回。我不知道是什么导致了这个问题。有人成功地克服了这个问题吗

下面是从仪器捕获的线程转储。它结束于
mach\u msg\u trap

视频处理环路 更新 资产读取器的源资产是
AVMutableComposition
,它由几个指向照片库的
avurlaste
(即url=“assets-library://asset/asset.MOV?id=4CA9A2C6-F2D4-4FDF-AAEC-6335B9BD840A&ext=MOV”)。从每个源资产开始,从源资产0.6秒后开始,持续2秒。如果所有源资源都从0开始,则视频处理永远不会挂起

总结
主要问题是:什么条件会导致
copyNextSampleBuffer
永远等待退出。文档中没有提到这种情况。

我看不出您在代码中将输入标记为已完成并结束了会话,如下所示。你给这些终结器打电话了吗

//Finish the session:
[writerInput markAsFinished];
[videoWriter endSessionAtSourceTime:totalDuration];

[videoWriter finishWritingWithCompletionHandler:^{

// Handle videoWriter.status here

}];

此错误也可能出现在
AVPlayer
avassetextortsession
上。我的解决方案可用于
AVPlayerItem
AVAssetExportSession

我花了一段时间才明白发生了什么。我仍然不能百分之百确定,但这就是我发现的:

问题在于视频的源时间和目标时间映射。如果您选中
videoTrack.segments
(例如,第一个)
segment.timeMapping.source.start
将不等于
segment.timeMapping.target.start
。默认情况下,在内部,
AVVideoComposition
将从composition中的原始资源继承
sourceTrackIDForFrameTiming
,以及有关计时、帧速率等的所有内容,这将导致错误。如果您不将视频合成设置为导出,它将执行相同的操作。我可以猜测,asset reader的某些内部逻辑将打破这个特定案例的时间计算

因此,对于修复,您可以为
AVVideoComposition
设置
sourceTrackIDForFrameTiming

assetradervideooutput
时,您应该使用
avassetradervideocompositionoutput
,并将
videoComposition
分配给它

您可以像这样创建视频合成,例如:

    let videoComposition = AVMutableVideoComposition(propertiesOf: mutableComposition)

    //MARK: - The most important thing
    videoComposition.sourceTrackIDForFrameTiming = kCMPersistentTrackID_Invalid

    videoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30)
    videoComposition.renderScale  = 1.0
    videoComposition.renderSize = CGSize(width: 720.0, height: 1280.0)
    
    let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: compositionVideoTrack)
    
    let mainInstruction = AVMutableVideoCompositionInstruction()
    mainInstruction.timeRange = CMTimeRange(start: .zero, duration: composition.duration)
    mainInstruction.layerInstructions = [layerInstruction]
    
    videoComposition.instructions = [mainInstruction]
在此处根据您的需要更改硬编码值。您还可以使用
let videoComposition=AVMutableVideoComposition()
初始值设定项,而无需设置sourceTrackIDForFrameTiming,在我的测试中,这同样有效。将
videoComposition
分配给
assetradervideooutput
。出口


就这样

你在github上有一个重现问题的小项目吗?没有,我没有这样的项目:(如果你能做一个就太好了)你在这里有过进步吗?我有同样的问题,只是读取要在AVSampleBufferDisplayLayer中显示的示例缓冲区(没有写入)
    let videoComposition = AVMutableVideoComposition(propertiesOf: mutableComposition)

    //MARK: - The most important thing
    videoComposition.sourceTrackIDForFrameTiming = kCMPersistentTrackID_Invalid

    videoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30)
    videoComposition.renderScale  = 1.0
    videoComposition.renderSize = CGSize(width: 720.0, height: 1280.0)
    
    let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: compositionVideoTrack)
    
    let mainInstruction = AVMutableVideoCompositionInstruction()
    mainInstruction.timeRange = CMTimeRange(start: .zero, duration: composition.duration)
    mainInstruction.layerInstructions = [layerInstruction]
    
    videoComposition.instructions = [mainInstruction]