需求:
将一首歌mp3格式,和一段无声音录屏mp4格式,合成到一起,使播放视频时能听到这首歌。
实现原理:
打开mp3音频,解析出输入音频流,再打开mp4视频,解析出输入视频流。
然后打开输出环境,创建2个输出流,分别对应音频输入流和视频输入流。
最后循环交替从音频流和视频流读取AVPacket,依次写入输出环境。
使用ffmpeg命令实现音视频混合很简单:
ffmpeg -i xxx1.mp3 -i xxx2.mp4 out.mp4
要点:
1 AVPacket::stream_index
将AVPacket写入输出环境时,音频和视频的stream_index不能相等,如果音频的stream_index等于0,那么视频的stream_index需要等于1,可以手动改。出现这种情况的原因是输入的xxx1.mp3可能包含2个流,一个是音频,另一个是视频,音频流索引是0,视频流索引是1。这里的视频实际上是播放音乐时显示的一张图片。输入的xxx2.mp4至少包含2个流,一个是音频,另一个是视频,而这里视频流索引是0,音频流索引是1。画个图:
xxx1.mp3
- stream0(audio)
- stream1(video)
xxx2.mp4
- stream0(video)
- stream1(audio)
出现这种情况,从xxx1.mp3解析出来的AVPacket和xxx2.mp4解析出来的AVPacket的stream_index都为0,如果不改直接写到输出环境,ffmpeg就会报错。
2 void av_packet_rescale_ts(AVPacket *pkt, AVRational tb_src, AVRational tb_dst);
* Convert valid timing fields (timestamps / durations) in a packet from one
* timebase to another. Timestamps with unknown values (AV_NOPTS_VALUE) will be
* ignored.
将从输入流解析出的AVPacket的跟时间相关字段,从当前的输入流时基对应的值转为输出流时基对应的值。音频和视频都是用这个函数。这样合成后的音频和视频就能有序播放。
3 别犯低级错误,比如成员变量pkg与pkg2混淆导致出问题。
附上调试学习研究用的代码
文件名xxx.c(cpp会编不过)
包含目录,ffmpeg头文件所在的目录
C:\work\env\msys2\usr\local\include;
包含库目录,ffmpeg静态库所在的目录
C:\work\env\msys2\usr\local\lib;
依赖的静态库
libavcodec.a
libavdevice.a
libavfilter.a
libavformat.a
libavutil.a
libswresample.a
libswscale.a
SDL2.lib
SDL2main.lib
mfuuid.lib
ole32.lib
strmiids.lib
user32.lib
psapi.lib
uuid.lib
ole


728

被折叠的 条评论
为什么被折叠?



