使用 AVAssetWriter 时未知的底层 OSStatus 错误 -16364

Unknown underlying OSStatus error -16364 when using AVAssetWriter

我正在为我的一个应用程序构建视频导出功能。本质上,该视频是六个不同图像之一的系列,持续时间不同(短)。

当我导出包含 283 张不同持续时间图像的内容时,导出工作正常,但是当我尝试导出 803 张图像中的一张时,我遇到了可怕的 "The operation could not be completed" 错误(A.K.A。"we have no idea what just blew up because AVFoundation error reporting is awful").

当我尝试使用 AVAssetWriterInputPixelBufferAdaptorappendPixelBuffer:withPresentationTime: returns NO 添加第 754 帧(总是第 754 帧)时,AVAssetWriter' s 的状态是失败的,它的错误是这样的:

Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x17ab2050 {Error Domain=NSOSStatusErrorDomain Code=-16364 "(null)"}, NSLocalizedFailureReason=An unknown error occurred (-16364)}

我这辈子都弄不明白那个潜在错误 (OSStatus -16364) 是什么。 www.osstatus.com has no idea, macerror says no such thing exists, and this Python 用于搜索 SDK headers 的脚本没有找到任何结果。它也不是像一些 OSStatus 错误那样的四字符代码(除非我搞砸了检查这个)。

我已经排除了我发现的 "The operation cannot be completed" 错误的所有常见原因。它与文件系统权限或覆盖无关,appendPixelBuffer 的两次调用没有相同的显示时间。

这不是内存问题(视频导出期间内存使用率保持在 165MB),CPU 保持在接近 3%。

如果它有任何重要性,我会一遍又一遍地重复使用相同的 6 个 CVPixelBuffer 来制作 6 张图片,而不是每次都从 UIImage 中创建新的图片。这似乎有助于提高性能,并且每次将其更改为新的似乎并没有改变任何东西(除了让它在第 753 帧上失败),但谁知道呢。

有人知道这是什么吗?

好的。终于想通了。

由于四舍五入(将小的持续时间值四舍五入到 30 FPS 的时间尺度,这导致它们变成 0/30),appendPixelBuffer:withPresentationTime: 在特定情况下被相同的 presentationTime 调用了两次. AVFoundation 直到 7 帧后抛出错误时才注意到问题:

Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x17ab2050 {Error Domain=NSOSStatusErrorDomain Code=-16364 "(null)"}, NSLocalizedFailureReason=An unknown error occurred (-16364)}

使用 60 FPS 代替 30 FPS 可以防止这种特殊情况四舍五入为零持续时间,但一般的解决方案是丢弃持续时间四舍五入为零的帧。

在我的例子中,它发生了然后 append(buffer: buffer, with: time) 被调用 time(在一个线程中被视为 CACurrentMediaTime())低于先前添加的帧使用的 time .当图像在并发线程中生成并且似乎以错误的顺序完成时会发生这种情况。

我添加了一张支票 self!.lastTime! < time,它很有帮助。