如何同时使用 AVAssetReader 和 AVAssetWriter 处理多个轨道(音频和视频)?
我知道如何使用 AVAssetReader
和 AVAssetWriter
,并成功使用它们从一部电影中获取视频轨道并将其转码为另一部电影。不过,我也想用音频来做到这一点。完成初始转码后是否必须创建 AVAssetExportSession
,或者是否有某种方法可以在写入会话期间在轨道之间切换?我不想处理 AVAssetExportSession
的开销。
我问这个问题是因为,使用拉式方法 - while ([assetWriterInput isReadyForMoreMediaData]) {...}
- 假设仅一个轨道。它如何用于多个轨道,即音频轨道和视频轨道?
I know how to use AVAssetReader
and AVAssetWriter
, and have successfully used them to grab a video track from one movie and transcode it into another. However, I'd like to do this with audio as well. Do I have to create and AVAssetExportSession
after I've done with the initial transcode, or is there some way to switch between tracks while in the midst of a writing session? I'd hate to have to deal with the overhead of an AVAssetExportSession
.
I ask because, using the pull style method - while ([assetWriterInput isReadyForMoreMediaData]) {...}
- assumes one track only. How could it be used for more than one track, i.e. both an audio and a video track?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
AVAssetWriter
将自动交错关联的AVAssetWriterInput
上的请求,以便将不同的轨道集成到输出文件中。只需为您拥有的每个轨道添加一个AVAssetWriterInput
,然后在每个AVAssetWriterInput
上调用requestMediaDataWhenReadyOnQueue:usingBlock:
即可。这是我调用
requestMediaDataWhenReadyOnQueue:usingBlock:
的方法。我从对我拥有的输出/输入对的数量的循环中调用此方法。 (单独的方法不仅有利于代码的可读性,而且还因为与循环不同,每个调用都会为该块设置一个单独的堆栈帧。)您只需要一个
dispatch_queue_t
并且可以将其重用于所有轨道。请注意,您绝对不应该从块中调用dispatch_async
,因为requestMediaDataWhenReadyOnQueue:usingBlock:
期望块阻塞,直到它填满AVAssetWriterInput
将获取尽可能多的数据。在那之前你不想回来。AVAssetWriter
will automatically interleave requests on its associatedAVAssetWriterInput
s in order to integrate different tracks into the output file. Just add anAVAssetWriterInput
for each of the tracks that you have, and then callrequestMediaDataWhenReadyOnQueue:usingBlock:
on each of yourAVAssetWriterInput
s.Here's a method I have that calls
requestMediaDataWhenReadyOnQueue:usingBlock:
. I call this method from a loop over the number of output/input pairs I have. (A separate method is good both for code readability and also because, unlike a loop, each call sets up a separate stack frame for the block.)You only need one
dispatch_queue_t
and can reuse it for all of the tracks. Note that you definitely should not calldispatch_async
from your block, becauserequestMediaDataWhenReadyOnQueue:usingBlock:
expects the block to, well, block until it has filled in as much data as theAVAssetWriterInput
will take. You don't want to return before then.您是否尝试过使用两个 AVAssetWriterInputs 并将样本推送到工作队列?这是一个粗略的草图。
Have you tried using two AVAssetWriterInputs and pushing the samples through a worker queue? Here is a rough sketch.
您可以使用调度组!
查看 MacOSX 的 AVReaderWriter 示例...
我直接引用示例 RWDocument.m:
You can use dispatch groups!
Check out the AVReaderWriter example for MacOSX...
I am quoting directly from the sample RWDocument.m: