gpt4 book ai didi

ios - 将音频缓冲区 [从文件] 添加到 'live' 音频缓冲区 [录制到文件]

转载 作者:可可西里 更新时间:2023-11-01 03:32:19 25 4
gpt4 key购买 nike

我正在尝试做的事情:
录制指定持续时间的音频/视频,其中生成的输出文件将添加来自外部音频文件的预定义背景音乐 - 录制后无需进一步编码/导出 .
就像您使用 iPhone 的相机应用程序录制视频一样,“相机胶卷”中的所有录制视频都有背景歌曲。结束录音后不导出或加载,也不在单独的 AudioTrack 中。

我如何努力实现这一目标:
通过使用 AVCaptureSession ,在传递( CMSampleBufferRef )样本缓冲区的委托(delegate)方法中,我将它们推送到 AVAssetWriter 以写入文件。由于我不希望输出文件中有多个音轨,因此我无法通过单独的 AVAssetWriterInput 传递背景音乐。 ,这意味着我必须在录音时将背景音乐添加到录音中的每个样本缓冲区,以避免在录音后合并/导出。
背景音乐是​​一个特定的、预定义的音频文件(格式/编解码器:m4a aac),不需要时间编辑,只需在整个录音下方添加,从头到尾。录音永远不会长于背景音乐文件。
在开始写入文件之前,我还准备了一个 AVAssetReader ,读取指定的音频文件。
一些伪代码 (不包括线程):

-(void)startRecording
{
/*
Initialize writer and reader here: [...]
*/

backgroundAudioTrackOutput = [AVAssetReaderTrackOutput
assetReaderTrackOutputWithTrack:
backgroundAudioTrack
outputSettings:nil];

if([backgroundAudioReader canAddOutput:backgroundAudioTrackOutput])
[backgroundAudioReader addOutput:backgroundAudioTrackOutput];
else
NSLog(@"This doesn't happen");

[backgroundAudioReader startReading];

/* Some more code */

recording = YES;
}
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
if(!recording)
return;

if(videoConnection)
[self writeVideoSampleBuffer:sampleBuffer];
else if(audioConnection)
[self writeAudioSampleBuffer:sampleBuffer];
}
AVCaptureSession已经在流式传输摄像机视频和麦克风音频,并且正在等待 BOOL recording设置为 YES .这不完全是我这样做的方式,而是一个简短的、以某种方式等效的表示。当委托(delegate)方法收到 CMSampleBufferRef音频类型,我调用自己的方法 writeAudioSamplebuffer:sampleBuffer .如果这是正常完成的,没有我想要做的背景音轨,我会简单地输入这样的内容: [assetWriterAudioInput appendSampleBuffer:sampleBuffer];而不是调用我的方法。不过就我而言,我需要 重叠 写入之前的两个缓冲区:
-(void)writeAudioSamplebuffer:(CMSampleBufferRef)recordedSampleBuffer
{
CMSampleBufferRef backgroundSampleBuffer =
[backgroundAudioTrackOutput copyNextSampleBuffer];

/* DO MAGIC HERE */
CMSampleBufferRef resultSampleBuffer =
[self overlapBuffer:recordedSampleBuffer
withBackgroundBuffer:backgroundSampleBuffer];
/* END MAGIC HERE */

[assetWriterAudioInput appendSampleBuffer:resultSampleBuffer];
}

问题:
我必须将本地文件中的增量样本缓冲区添加到传入的实时缓冲区中。我创建的方法名为 overlapBuffer:withBackgroundBuffer:现在没有做太多事情。 我知道 如何提取 AudioBufferList , AudioBuffermData等来自 CMSampleBufferRef ,但我不确定如何将它们实际加在一起 ​​- 然而 - 我无法测试不同的方法来做到这一点,因为真正的问题发生在此之前。前 魔术应该发生,我有两个 CMSampleBufferRef s,一个从麦克风收到,一个从文件中读取,这就是问题所在:
从背景音乐文件收到的样本缓冲区与我从录音 session 收到的缓冲区不同。 好像是打给 [self.backgroundAudioTrackOutput copyNextSampleBuffer];接收大量样本。我意识到这对某些人来说可能是显而易见的,但我以前从未达到过这种媒体技术水平。我现在明白,打电话 copyNextSampleBuffer是一厢情愿的想法。每次我从 session 中收到一个 sampleBuffer,但我不知道何时/何地放置它。
据我所知,录音 session 给出了 每个样本缓冲区中的音频样本,而文件阅读器给出 多个 每个样本缓冲区中的样本。我可以以某种方式创建一个计数器来计算每个接收到的记录样本/缓冲区,然后使用第一个 file-sampleBuffer 来提取每个样本,直到当前的 file-sampleBuffer 没有更多样本“提供”,然后调用 [..copyNext ..],并对那个缓冲区做同样的事情?
因为我可以完全控制录音和文件的编解码器、格式等,所以我是 希望这样的解决方案不会破坏音频的“对齐”/同步。鉴于两个样本具有相同的采样率,这仍然是一个问题吗?

笔记
我什至不确定这是否可能,但我看不出为什么不应该这样做的直接原因。
还值得一提的是,当我尝试使用视频文件而不是音频文件,并尝试不断拉取视频样本缓冲区时,它们会完美对齐。

最佳答案

我不熟悉 AVCaptureOutput,因为我所有的声音/音乐 session 都是使用 AudioToolbox 而不是 AVFoundation 构建的。但是,我想您应该能够设置记录捕获缓冲区的大小。如果没有,并且您仍然只得到一个样本,我建议您将从捕获输出中获得的每个单独数据存储在辅助缓冲区中。当辅助缓冲区与文件读取缓冲区大小相同时,调用 [self overlapBuffer:auxiliarSampleBuffer withBackgroundBuffer:backgroundSampleBuffer];
我希望这会帮助你。如果没有,我可以提供有关如何使用 CoreAudio 执行此操作的示例。使用 CoreAudio 我已经能够从麦克风捕获和文件读取中获得 1024 个 LCPM 样本缓冲区。所以重叠是直接的。

关于ios - 将音频缓冲区 [从文件] 添加到 'live' 音频缓冲区 [录制到文件],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25943011/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com