FFmpeg 音频处理实战:音频剪切、混音与采样率转换的命令行与 API 实现
操作命令行核心参数API 核心组件音频剪切-ss-t+ 时间戳过滤混音amix滤波器amix采样率转换-arSwrContext注意:API 实现需处理错误检查、内存释放等细节,此处聚焦核心逻辑。实际开发建议参考 FFmpeg 官方文档及示例代码(如目录)。
·
FFmpeg 音频处理实战
FFmpeg 是强大的多媒体处理工具,支持命令行操作和编程接口(API)。以下从音频剪切、混音及采样率转换三方面,分别给出命令行与 C API 实现的关键方法。
1. 音频剪切
目标:截取音频片段(如从第 10 秒开始,持续 5 秒)。
命令行实现:
ffmpeg -i input.mp3 -ss 00:00:10 -t 5 -c:a copy output_clip.mp3
-ss 10:从第 10 秒开始-t 5:持续 5 秒-c:a copy:直接复制音频流(无损剪切)
API 实现(C 语言):
AVFormatContext *fmt_ctx = NULL;
avformat_open_input(&fmt_ctx, "input.mp3", NULL, NULL);
// 定位到指定时间点(单位:微秒)
int64_t seek_target = 10 * AV_TIME_BASE;
avformat_seek_file(fmt_ctx, -1, 0, seek_target, seek_target, 0);
// 创建输出上下文
AVFormatContext *out_ctx;
avformat_alloc_output_context2(&out_ctx, NULL, NULL, "output_clip.mp3");
// 复制音频流并设置持续时间
AVStream *in_stream = fmt_ctx->streams[0];
AVStream *out_stream = avformat_new_stream(out_ctx, NULL);
avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar);
// 处理数据包(仅复制目标时长内的包)
AVPacket pkt;
int64_t end_pts = seek_target + 5 * AV_TIME_BASE;
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
if (pkt.pts > end_pts) break;
av_interleaved_write_frame(out_ctx, &pkt);
av_packet_unref(&pkt);
}
关键点:
- 使用
avformat_seek_file定位起始点 - 通过时间戳过滤数据包(
pkt.pts)
2. 音频混音
目标:将两段音频混合为单声道/立体声输出。
命令行实现:
ffmpeg -i input1.mp3 -i input2.mp3 -filter_complex "amix=inputs=2:duration=longest" output_mix.mp3
amix:混音滤波器inputs=2:混合两个输入源duration=longest:以较长音频为输出时长
API 实现(C 语言):
// 创建滤波器图
AVFilterGraph *graph = avfilter_graph_alloc();
// 定义输入源
AVFilterContext *src1_ctx, *src2_ctx;
avfilter_graph_create_filter(&src1_ctx, avfilter_get_by_name("abuffer"), "src1", NULL, NULL, graph);
avfilter_graph_create_filter(&src2_ctx, avfilter_get_by_name("abuffer"), "src2", NULL, NULL, graph);
// 创建混音滤波器
AVFilterContext *mix_ctx;
avfilter_graph_create_filter(&mix_ctx, avfilter_get_by_name("amix"), "mix", "inputs=2", NULL, graph);
// 连接滤波器:src1 → mix, src2 → mix
avfilter_link(src1_ctx, 0, mix_ctx, 0);
avfilter_link(src2_ctx, 0, mix_ctx, 1);
// 创建输出接收器
AVFilterContext *sink_ctx;
avfilter_graph_create_filter(&sink_ctx, avfilter_get_by_name("abuffersink"), "sink", NULL, NULL, graph);
avfilter_link(mix_ctx, 0, sink_ctx, 0);
// 输入音频帧并处理
AVFrame *frame1 = decode_audio("input1.mp3"); // 自定义解码函数
AVFrame *frame2 = decode_audio("input2.mp3");
av_buffersrc_add_frame(src1_ctx, frame1);
av_buffersrc_add_frame(src2_ctx, frame2);
// 从 sink 获取混合后的帧并编码输出
AVFrame *mixed_frame = av_frame_alloc();
av_buffersink_get_frame(sink_ctx, mixed_frame);
encode_audio(mixed_frame, "output_mix.mp3"); // 自定义编码函数
关键点:
- 使用滤波器图(
AVFilterGraph)连接abuffer→amix→abuffersink - 通过
av_buffersrc_add_frame输入源数据
3. 采样率转换
目标:将音频采样率从 44.1kHz 转换为 48kHz。
命令行实现:
ffmpeg -i input.wav -ar 48000 output.wav
-ar 48000:指定输出采样率
API 实现(C 语言):
// 创建重采样上下文
SwrContext *swr = swr_alloc();
av_opt_set_int(swr, "in_sample_rate", 44100, 0);
av_opt_set_int(swr, "out_sample_rate", 48000, 0);
av_opt_set_sample_fmt(swr, "in_sample_fmt", AV_SAMPLE_FMT_FLTP, 0);
av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_FLTP, 0);
swr_init(swr);
// 输入帧(44.1kHz)
AVFrame *in_frame = decode_audio("input.wav");
// 计算输出帧大小
int out_samples = swr_get_out_samples(swr, in_frame->nb_samples);
AVFrame *out_frame = av_frame_alloc();
out_frame->sample_rate = 48000;
out_frame->format = AV_SAMPLE_FMT_FLTP;
av_frame_get_buffer(out_frame, 0);
// 执行重采样
swr_convert(swr, out_frame->data, out_samples, (const uint8_t**)in_frame->data, in_frame->nb_samples);
// 编码输出(48kHz)
encode_audio(out_frame, "output.wav");
关键点:
- 使用
swr_convert转换采样率 - 通过
swr_get_out_samples计算输出样本数
总结
| 操作 | 命令行核心参数 | API 核心组件 |
|---|---|---|
| 音频剪切 | -ss + -t |
avformat_seek_file + 时间戳过滤 |
| 混音 | amix 滤波器 |
AVFilterGraph + amix |
| 采样率转换 | -ar |
SwrContext + swr_convert |
注意:API 实现需处理错误检查、内存释放等细节,此处聚焦核心逻辑。实际开发建议参考 FFmpeg 官方文档及示例代码(如
doc/examples目录)。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)