本文重点介绍用FFmpeg实现使用一段音频覆盖另一段音频的某个区域的功能,大概示意图如下:
要实现这样的效果,分析后主要需要以下步骤:
- 将音频A的30s拆分成三段:
- 需要播放出来的第1段
- 即将被覆盖的第2段
- 需要播放出来的第3段,将时间戳整体后移20秒
- 将音频B的时间戳整体后移到覆盖位置,比如10秒位置开始覆盖
- 将音频A的前十秒和音频B进行混音操作
- 将音频A和音频B混音后的数据与音频A的后10秒进行混音操作
下面看一下命令行怎么操作的:
命令行部分
StevenLiu:~ StevenLiu$ ./ffmpeg -i b.mp3 -filter_complex "amovie=a.mp3,asplit=2[a0][a1];[0:a]atrim=10:20,adelay=10000|10000|10000[in1];[a0]atrim=0:10[a00];[a1]atrim=20:30,adelay=20000|20000|20000[a11];[in1][a00]amix[o0];[o0][a11]amix[oo0];[oo0]asetnsamples=1024" x.mp3" c.mp3
为了让各位喷命令行太LowB的大佬能够顺利的Copy代码,将代码修改部分贴上来,以供Ctrl+C Ctrl+V,其实差别不大,和以往一样,直接把字符串传递进去就好。
代码部分:
StevenLiu:ffmpeg StevenLiu$ git diff
diff --git a/doc/examples/transcoding.c b/doc/examples/transcoding.c
index e48837cbd2..a8d7f08543 100644
--- a/doc/examples/transcoding.c
+++ b/doc/examples/transcoding.c
@@ -393,7 +393,7 @@ static int init_filters(void)
if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
filter_spec = "null"; /* passthrough (dummy) filter for video */
else
- filter_spec = "anull"; /* passthrough (dummy) filter for audio */
+ filter_spec = "amovie=a.mp3,asplit=2[a0][a1];[in]atrim=10:20,adelay=10000|10000|10000[in1];[a0]atrim=0:10[a00];[a1]atrim=20:30,adelay=20000|20000|20000[a11];[in1][a00]amix[o0];[o0][a11]amix[oo0];[oo0]asetnsamples=1024"; /* passthrough (dummy) filter for audio */
ret = init_filter(&filter_ctx[i], stream_ctx[i].dec_ctx,
stream_ctx[i].enc_ctx, filter_spec);
if (ret)
StevenLiu:ffmpeg StevenLiu$
到这里,用一段音频覆盖另一个音频的某一段的实现介绍完毕。
作者:悟空 ;公众号:流媒体技术
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。