【问题标题】:AVAssetWiter status failed when appending audio sample buffer to AVAssetwriterInput - OSX, Swift将音频样本缓冲区附加到 AVAssetwriterInput 时 AVAssetWiter 状态失败 - OSX,Swift
【发布时间】:2021-03-28 00:04:25
【问题描述】:

我正在尝试使用 AVFoundation 在 OSX 中录制带有音频的屏幕,当我录制视频时效果很好。但是当添加音频输入并将其附加到 AVAssetWriterInput 时,资产编写器状态更改为 .failed。

if let sampleBuffer = sampleBuffer {
            if CMSampleBufferDataIsReady(sampleBuffer) {
                if assetWriter.status == .unknown {
                    let startTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
                    assetWriter.startWriting()
                    assetWriter.startSession(atSourceTime: startTime)
                }
                if assetWriter.status == .failed {
                    print("writer error \(String(describing: assetWriter.error?.localizedDescription))")
                    return false
                }
                if isVideo {
                    if videoInputWriter.isReadyForMoreMediaData {
                        videoInputWriter.append(sampleBuffer)
                        return true
                    }
                } else {
                    if audioInputWriter.isReadyForMoreMediaData {
                        audioInputWriter.append(sampleBuffer)
                        return true
                    }
                }
            }
        }

错误信息是

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

【问题讨论】:

    标签: swift macos avfoundation avassetwriter avassetwriterinput


    【解决方案1】:

    欢迎!

    我猜,但您似乎正在使用相同的回调来处理音频和视频样本。问题可能是音频和视频样本将在不同的队列(线程)中同时传递,这意味着assetWriter.startSession(atSourceTime: startTime) 可能会在不同的线程中意外执行多次——这是不允许的。

    您需要以某种方式(原子地)保护该调用,例如通过使用单独的同步队列。或者,您可以只使用到达的第一个视频缓冲区开始会话,并忽略之前的任何音频缓冲区(这也可以防止视频开头出现意外黑帧)。

    【讨论】:

    • assetWriter.startSession(atSourceTime: startTime) 它将被调用一次,因为当我启动 assetWriter.StartWriting 时资产写入器状态将变为写入。另外,我正在为视频和音频使用调度队列。所以不会有对这个对象的并发访问。是的,我只有在收到视频缓冲区时才开始写作。所以不会有黑框。
    • 我得到了黑框。你是怎么解决的?
    猜你喜欢
    • 2014-11-14
    • 2023-01-24
    • 2014-04-03
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多