源码地址:https://github.com/bookzhan/bzmedia (BackgroundMusicUtil.cpp)
在处理视频背景音乐的时候一般有两种方案:
- 在视频原声的基础上添加背景音乐
- 用背景音乐替换掉视频原声
方案一,在视频原声的基础上添加背景音乐,同时支持调整视频原声与背景音乐声音的大小:
思路用FFmpeg调用命令行的方式来做就好了,但是需要区分视频是否有音频,这个需要分开处理,这种对输入的背景音乐格式没有严格的要求,取决于FFmpeg编译的时候选择支持的音频格式。为了达到好的效果用这个命令之前最好把音频长度处理成和视频长度一样。这种方式涉及到对音频的编解码以及重采样性能低于第二种方式,命令如下:
1.有音频的视频:
char mergeCmd[1024] = {0};
sprintf(mergeCmd,
"ffmpeg -y -i \"%s\" -i \"%s\" -c:v copy -filter_complex [0:a]aformat=fltp:44100:stereo,volume=%.2f,apad[0a];[1]aformat=fltp:44100:stereo,volume=%.2f[1a];[0a][1a]amerge[a] -map 0:v -map [a] -ac 2 %s",
inputPath, musicPath, srcMusicVolume, bgMusicVolume, outputPath);
2.没有音频的视频:
char mergeCmd[1024] = {0};
sprintf(mergeCmd,
"ffmpeg -y -i \"%s\" -i \"%s\" -map 0:v -vcodec copy -map 1:a -af volume=%.2f \"%s\"",
inputPath, finalMusicPath, bgMusicVolume, outputPath);
方案二,用背景音乐替换掉视频原声
我们知道MP4的音频流编码方式是AAC, 而m4a编码方式也是AAC,那么就用一个m4a的音频文件直接替换掉视频的音频流就好了,也就是说只是支持m4a的文件,在实际使用过程中可以把产品给的音频文件转换成m4a传到服务器上使用。同样使用之前也需要把音频长度处理成和视频一样长
char mergeCmd[1024] = {0};
sprintf(mergeCmd,
"ffmpeg -y -i \"%s\" -i \"%s\" -map 0:v -vcodec copy -map 1:a -acodec copy %s",
videoPath, musicPath, outputPath);
这些我都已经实现了并且封装好了,使用方式:
BZMedia.java
/**
* @param srcMusicVolume 0~1
* @param bgMusicVolume 0~1
* @return >=0 successful, <0 fail
*/
public static native int addBackgroundMusic(String inputPath, String outputPath,
String musicPath, float srcMusicVolume, float bgMusicVolume, OnActionListener onActionListener);
/**
* If only replacing background music, this function is more efficient than addBackgroundMusic
*
* @param musicPath The format must be m4a, and the encoding method must be aac
* @return >=0 successful, <0 fail
*/
public static native int replaceBackgroundMusic(String videoPath, String musicPath, String outputPath, OnActionListener onActionListener);