我在一个个人项目中使用FFmpeg库,需要关于一件事情的帮助。我有一个立体声音乐文件,想要将其转换为单声道音乐。这个库是否可以实现?是否有内置函数可以完成这项工作?我的项目是用C/C++编写的。
我在FFmpeg官网上的Doxygen文档和论坛中搜索过,但没有找到有趣的内容。
谢谢阅读!
你可以直接使用ffmpeg。为此目的提供了直接命令-
ffmpeg -i stereo.flac -ac 1 mono.flac
会将你的立体声文件转换为单声道。了解更多细节,请查看此页面-
find . -name '*.mp4' -exec ./convert.sh {} \;
- Marco Arrudaconvert.sh
文件内: - Marco Arrudaffmpeg -i $1 -ac 1 $1.mono.mp4
- Marco Arrudaffmpeg
пәЊи·іиү‡convert.sh
文件пәЊе‘Ң令如下пәљ find . -name '*.mp4' -exec ffmpeg -i '{}' -ac 1 '{}.mono.mp4' \;
гЂ‚иҮӨе‘Ң令将жџӨж‰ң所有扩展еђҚдёғ.mp4
的文件пәЊе№¶й’€еҮ№жҮЏдёҒ文件иүђиҰЊffmpeg
е‘Ң令пәЊд»Өе°†е…¶иҢ¬жҚұдёғеҚ•еӘ°йЃ“ж әеәЏ{}.mono.mp4
гЂ‚ - joshtch-ac 1
会将立体声混音为单声道,这可能不是您想要的,特别是如果它只是“错误地以立体声录制的单声源”。在这种情况下,可以像这样丢弃一个通道:ffmpeg -i INPUT -filter_complex '[0:a]channelsplit=channel_layout=stereo:channels=FL[left]' -map '[left]' OUTPUT
(当然,请替换INPUT
和OUTPUT
)。这将选择左声道,如果您想要右声道,请使用FR
和[right]
。 - scyswr_convert
进行格式转换。类似这样的操作:#include "libswresample/swresample.h"
au_convert_ctx = swr_alloc();
out_channel_layout = AV_CH_LAYOUT_MONO;
out_sample_fmt = AV_SAMPLE_FMT_S16;
out_sample_rate = 44100;
out_channels = av_get_channel_layout_nb_channels(out_channel_layout);
in_sample_fmt = pCodecCtx->sample_fmt;
in_channel_layout=av_get_default_channel_layout(pCodecCtx->channels);
au_convert_ctx=swr_alloc_set_opts(au_convert_ctx,out_channel_layout, out_sample_fmt, out_sample_rate,
in_channel_layout, in_sample_fmt, pCodecCtx->sample_rate, 0, NULL);
swr_init(au_convert_ctx);
//Generate your frame of original audio, then use swr_convert to convert to mono,
//converted number of samples will now be in out_buffer.
int converted = swr_convert(au_convert_ctx, &out_buffer, MAX_AUDIO_FRAME_SIZE, (const uint8_t **)&pFrame->data , pFrame->nb_samples);
//...
swr_free(&au_convert_ctx);
以下是一些可以帮助您入门的内容。这将把原始格式转换为44100kHz单声道。您也可以使用pCodecCtx->sample_rate
作为输出采样率。
这是最灵活、最简便的解决方案。
正如我在评论中提到的,您可以自行重新采样。这取决于您已经拥有什么以及使用的格式是什么。我无法为您提供立即可用的代码,但会给您一个示例(伪/真代码混合)。
在编码帧之后,并完成必须要做的事情后,您的数据缓冲区将填充音频。现在这取决于您的格式是什么(参见此处)以及您有多少声道。让我们假设它是有符号16位立体声,则您的缓冲区将如下所示:
+-----+-----+-----+-----+-----+
| LS1 | RS1 | LS2 | RS2 | ... |
+-----+-----+-----+-----+-----+
// LS = LEFT SAMPLE 16 Bit
// RS = RIGHT SAMPLE 16 Bit
for(int i=0; i<sample_size; i+=2) {
auto r = (static_cast<int32_t>(buffer[i]) + buffer[i+1]) / 2;
buffer[i] = buffer[i+1] = r;
}