如何使用ffmpeg在视频中添加新音频(不混音)?


131

我使用了如下命令:

ffmpeg -i video.avi -i audio.mp3 -vcodec codec -acodec codec output_video.avi -newaudio

在最新版本中用于向视频添加新的音轨(不混合)。

但是我将ffmpeg更新为最新版本(ffmpeg版本git-2012-06-16-809d71d),现在在此版本中该参数-newaudio无效。

请告诉我如何使用可以将新音频添加到视频中(而不是混音)ffmpeg


@Kiquenet是的,您是对的。并且答案已经给出。只需阅读此线程即可。这个问题5岁了。
Vetalll

添加新音频意味着替换音频,对吗?我可能会编辑您的问题以使其清楚。
tommy.carstensen

Answers:


295

向视频添加音频:流复制

ffmpeg -i video.avi -i audio.mp3 -codec copy -shortest output.avi
  • 省略该-map选项将使用默认的流选择。如果您的视频输入没有音频,这将起作用。
  • 本示例使用-codec copy流拷贝(再编码没有;质量被保留,这是快)。
  • -shortest选项output.avi的持续时间与最短的输入相同。

将音频添加到视频:重新编码

如果您的输出不喜欢原始格式,或者要更改格式,则可以指定编码器:

ffmpeg -i video.avi -i audio.mp3 -c:v libx264 -c:a libvorbis -shortest output.mkv

手动选择特定流

有时默认的流选择不会给您想要的结果。在此示例中,video.mp4具有视频音频,并且audio.m4a仅具有音频。用于-map从中选择视频video.mp4和音频audio.m4a

ffmpeg -i video.mp4 -i audio.m4a -map 0:v -map 1:a -c copy -shortest output.mp4
  • -map 0:v–从输入0(第一个输入为video.mp4)中选择v意识流。
  • -map 1:a–从输入1(第二个输入为audio.m4a)中选择audio流。

将两个音频输入混合/合并为一个

从中获取视频video.webm,然后使用合并过滤器合并来自video.webm和的音频audio.oga

ffmpeg -i video.webm -i audio.oga -filter_complex \
"[0:a][1:a]amerge=inputs=2[a]" \
-map 0:v -map "[a]" -c:v copy -c:a libvorbis -ac 2 -shortest out.webm

产生静音音频

您可以使用anullsrc过滤器制作无声音频流。滤波器允许您选择所需的通道布局(单声道,立体声,5.1等)和采样率。

ffmpeg -i video.mp4 -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 \
-c:v copy -shortest output.mp4

另见


5
起初这对我不起作用,但是使用-map 0:0 -map 1:0代替代替-map 0 -map 1对我有用。谢谢!
yonix

这将在开头插入一个空框架。
Lenar Hoyt

我已经尝试过此命令,但是我丢失了视频音频。我的视频格式是mp4
Allan

@ Allan.Chan原始问题不希望来自视频输入的音频,但是我添加了另一个示例:请参见“ 混合/组合另一个音频输入”示例。
llogan

没有-shortest选项的第一种解决方案对我来说效果更好。
mmj

24

mp3音乐到wav

ffmpeg -i music.mp3 music.wav

截断以适合视频

ffmpeg -i music.wav -ss 0 -t 37 musicshort.wav

混合音乐和视频

ffmpeg -i musicshort.wav -i movie.avi final_video.avi

3
我记得,最后一个变体将用新的音频替换旧的音频。
Vetalll 2012年

是否可以将新音频与旧音频合并?
Iqbal Malik

1
@jwilson我已经尝试过此命令,但是我丢失了视频音频。我的视频格式是mp4
Allan

@Allan不输的解决方案?
Kiquenet

20

如果输入视频具有多个音轨,并且您需要再添加一个音轨,请使用以下命令:

ffmpeg -i input_video_with_audio.avi -i new_audio.ac3 -map 0 -map 1 -codec copy output_video.avi

-map 0表示从第一个输入文件(input_video_with_audio.avi)复制(包括)所有流,并且-map 1意味着包括第二个输入文件(new_audio.ac3)的所有流(在这种情况下为一个)。


我认为,这个答案一定是最好的答案。
纳比·卡兹

3

这些解决方案都不适合我。我的原始音频被覆盖,或者由于更复杂的“合并”示例而出现诸如“无法映射内存”之类的错误。看来我需要-filter_complex amix。

ffmpeg -i videowithaudioyouwanttokeep.mp4 -i audiotooverlay.mp3 -vcodec copy -filter_complex amix -map 0:v -map 0:a -map 1:a -shortest -b:a 144k out.mkv

1

没有什么对我有用(我认为这是因为我的输入的.mp4视频没有任何音频),所以我发现这对我有用:

ffmpeg -i input_video.mp4 -i balipraiavid.wav -map 0:v:0 -map 1:a:0 output.mp4


0

如果您使用的是FFMPEG的旧版本,并且无法升级,则可以执行以下操作:

ffmpeg -i PATH/VIDEO_FILE_NAME.mp4 -i PATH/AUDIO_FILE_NAME.mp3 -vcodec copy -shortest DESTINATION_PATH/NEW_VIDEO_FILE_NAME.mp4

注意,我使用了-vcodec


0

使用ffmpeg将音频添加到视频的代码。

如果音频长度大于视频长度,则会将音频剪切为视频长度。如果要在视频中获得完整音频,请从cmd中删除-shortest。

String[] cmd = new String[]{"-i", selectedVideoPath,"-i",audiopath,"-map","1:a","-map","0:v","-codec","copy", ,outputFile.getPath()};

private void execFFmpegBinaryShortest(final String[] command) {



            final File outputFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/videoaudiomerger/"+"Vid"+"output"+i1+".mp4");




            String[] cmd = new String[]{"-i", selectedVideoPath,"-i",audiopath,"-map","1:a","-map","0:v","-codec","copy","-shortest",outputFile.getPath()};


            try {

                ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {
                    @Override
                    public void onFailure(String s) {
                        System.out.println("on failure----"+s);
                    }

                    @Override
                    public void onSuccess(String s) {
                        System.out.println("on success-----"+s);
                    }

                    @Override
                    public void onProgress(String s) {
                        //Log.d(TAG, "Started command : ffmpeg "+command);
                        System.out.println("Started---"+s);

                    }

                    @Override
                    public void onStart() {


                        //Log.d(TAG, "Started command : ffmpeg " + command);
                        System.out.println("Start----");

                    }

                    @Override
                    public void onFinish() {
                        System.out.println("Finish-----");


                    }
                });
            } catch (FFmpegCommandAlreadyRunningException e) {
                // do nothing for now
                System.out.println("exceptio :::"+e.getMessage());
            }


        }

什么Environment.getExternalStorageDirectory().getAbsolutePath()+"/videoaudiomerger/"+"Vid"+"output"+i1+".mp4");
Kiquenet
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.