13

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

当我导出包含 283 张不同持续时间的图像时,导出工作正常,但是当我尝试导出 803 中的一张时,我得到了可怕的“操作无法完成”错误(AKA“我们不知道刚刚发生了什么,因为AVFoundation 错误报告很糟糕”)。

当我尝试使用 my 添加第 754 帧(始终为第 754 帧)AVAssetWriterInputPixelBufferAdaptor时,appendPixelBuffer:withPresentationTime:返回NOAVAssetWriter状态为失败,其错误是:

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不知道,macerror说不存在这样的东西,这个用于搜索 SDK 标头的 Python 脚本什么也没找到。它也不是像某些 OSStatus 错误那样的四字符代码(除非我搞砸了检查)。

我已经排除了我发现的“操作无法完成”错误的所有常见原因。它与文件系统权限或覆盖无关,没有两个调用appendPixelBuffer具有相同的呈现时间。

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

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

有谁知道这可能是什么?

4

2 回答 2

22

好的。终于想通了。

由于四舍五入(将较小的持续时间值四舍五入到 30 FPS 的时间尺度,这导致它们变为 0/30),在特定情况下appendPixelBuffer:withPresentationTime:被调用了两次。presentationTimeAVFoundation 直到 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 可以防止这种特殊情况四舍五入到零持续时间,但一般的解决方案是丢弃持续时间四舍五入为零的帧。

于 2015-12-24T06:47:12.383 回答
0

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

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

于 2021-10-30T13:33:40.563 回答