swift - 将音频样本缓冲区附加到 AVAssetwriterInput 时 AVAssetWiter 状态失败 - OSX,Swift
问题描述
我正在尝试使用 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)"}}
解决方案
欢迎!
我猜,但您似乎正在使用相同的回调来处理音频和视频样本。问题可能在于音频和视频样本将在不同的队列(线程)中同时传递,这意味着assetWriter.startSession(atSourceTime: startTime)
可能会在不同的线程中意外执行多次——这是不允许的。
您需要以某种方式(原子地)保护该调用,例如通过使用单独的同步队列。或者,您可以只使用到达的第一个视频缓冲区开始会话,并忽略之前的任何音频缓冲区(这也可以防止视频开头出现意外的黑帧)。
推荐阅读
- svn - 在 SVN 存储库中提交后,Phinx 迁移未在服务器上运行
- python - 当带有 extract() 的 Scrapy 选择器返回 None 时如何设置默认值?
- python - 使用线程 python 终止脚本
- npm - 如何更新全局安装的 npm 包
- c++ - 使用聚合初始化器初始化类的模板(聚合类型)成员,但没有额外的括号
- spring - 多个 Spring Security 过滤器
- c# - 将多边形点保存到mysql数据库c#
- c - 第一次评估后始终具有相同值的 if 语句的优化
- python - counting specific weekday between two dates
- javascript - 如何在 React Native 中更新配置文件(displayName)firebase?