首页 文章

ffmpeg:合并/合并多个mp4视频不起作用,输出只包含第一个视频

提问于
浏览
43

这是我用来组合多个视频的命令:

ffmpeg -i 75_540_38HQ2.mp4 -i 76_70_20.mp4 -i 76_173_80.mp4 -i 81_186_35.mp4 -vcodec copy -acodec copy Mux1.mp4

生成的 Mux1.mp4 不包含所有视频 . 只有第一个视频( 75_540_38HQ2.mp4 ) . 源和结果视频的文件大小在下面(如您所见,生成的视频略大于第一个视频):

$ ls -lh
-rw-r--r-- 1 dbaker dbaker  42M 2011-03-24 11:59 75_540_38HQ2.mp4
-rw-r--r-- 1 dbaker dbaker 236M 2011-03-24 12:09 76_173_80.mp4
-rw-r--r-- 1 dbaker dbaker  26M 2011-03-24 12:05 76_70_20.mp4
-rw-r--r-- 1 dbaker dbaker  54M 2011-03-24 12:15 81_186_35.mp4
-rw-r--r-- 1 dbaker dbaker  44M 2011-03-24 14:48 Mux1.mp4

这是 ffmpeg 命令的输出 . 对我来说它看起来没问题,显示了多个源输入和单个输出 .

FFmpeg version SVN-r26402, Copyright (c) 2000-2011 the FFmpeg developers
  built on Mar 21 2011 18:05:32 with gcc 4.4.5
  configuration: --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable-libfaac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxvid --enable-x11grab
  libavutil     50.36. 0 / 50.36. 0
  libavcore      0.16. 1 /  0.16. 1
  libavcodec    52.108. 0 / 52.108. 0
  libavformat   52.93. 0 / 52.93. 0
  libavdevice   52. 2. 3 / 52. 2. 3
  libavfilter    1.74. 0 /  1.74. 0
  libswscale     0.12. 0 /  0.12. 0
  libpostproc   51. 2. 0 / 51. 2. 0
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '75_540_38HQ2.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 1970-01-01 00:00:00
    encoder         : Lavf52.93.0
  Duration: 00:00:29.99, start: 0.000000, bitrate: 11517 kb/s
    Stream #0.0(eng): Video: h264, yuv420p, 1280x960 [PAR 1:1 DAR 4:3], 11575 kb/s, 29.94 fps, 29.97 tbr, 30k tbn, 59.94 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
    Stream #0.1(eng): Audio: aac, 48000 Hz, stereo, s16, 127 kb/s
    Metadata:
      creation_time   : 1970-01-01 00:00:00
Input #1, mov,mp4,m4a,3gp,3g2,mj2, from '76_70_20.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 1970-01-01 00:00:00
    encoder         : Lavf52.93.0
  Duration: 00:00:19.98, start: 0.000000, bitrate: 10901 kb/s
    Stream #1.0(eng): Video: h264, yuv420p, 1280x960 [PAR 1:1 DAR 4:3], 10804 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
    Stream #1.1(eng): Audio: aac, 48000 Hz, stereo, s16, 128 kb/s
    Metadata:
      creation_time   : 1970-01-01 00:00:00
Input #2, mov,mp4,m4a,3gp,3g2,mj2, from '76_173_80.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 1970-01-01 00:00:00
    encoder         : Lavf52.93.0
  Duration: 00:03:09.99, start: 0.000000, bitrate: 10393 kb/s
    Stream #2.0(eng): Video: h264, yuv420p, 1280x960 [PAR 1:1 DAR 4:3], 10321 kb/s, 29.96 fps, 29.97 tbr, 30k tbn, 59.94 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
    Stream #2.1(eng): Audio: aac, 48000 Hz, stereo, s16, 128 kb/s
    Metadata:
      creation_time   : 1970-01-01 00:00:00

Seems stream 0 codec frame rate differs from container frame rate: 119.88 (120000/1001) -> 30000.00 (30000/1)
Input #3, mov,mp4,m4a,3gp,3g2,mj2, from '81_186_35.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 1970-01-01 00:00:00
    encoder         : Lavf52.93.0
  Duration: 00:00:35.00, start: 0.000000, bitrate: 12700 kb/s
    Stream #3.0(eng): Video: h264, yuv420p, 1280x720 [PAR 1:1 DAR 16:9], 12620 kb/s, 59.91 fps, 30k tbr, 60k tbn, 119.88 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
    Stream #3.1(eng): Audio: aac, 48000 Hz, stereo, s16, 128 kb/s
    Metadata:
      creation_time   : 1970-01-01 00:00:00
Output #0, mp4, to 'Mux1.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 1970-01-01 00:00:00
    encoder         : Lavf52.93.0
    Stream #0.0(eng): Video: libx264, yuv420p, 1280x960 [PAR 1:1 DAR 4:3], q=2-31, 11575 kb/s, 30k tbn, 29.97 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
    Stream #0.1(eng): Audio: libfaac, 48000 Hz, stereo, 128 kb/s
    Metadata:
      creation_time   : 1970-01-01 00:00:00
Stream mapping:
  Stream #0.0 -> #0.0
  Stream #2.1 -> #0.1
Press [q] to stop encoding
frame=  883 fps=632 q=-1.0 Lsize=   44730kB time=29.40 bitrate=12465.1kbits/s    
video:41678kB audio:2969kB global headers:0kB muxing overhead 0.184548%

我在这里做一些令人眼花缭乱的事吗?

源视频来自视频摄像头,是 ffmpeg -i bigfile.mp4 -ss 20 -t 10 -vcodec copy etc.. 拍摄的小片段

谢谢堆!戴夫


编辑:无法解决它所以我只使用avidemux GUI工具 . 它似乎附加了MP4就好了 .

一定是MP4的问题,或者只是gopro相机的问题 .

8 回答

  • 12

    您必须将它们转换为可以轻松连接的MPEG格式 . 下面是我使用的脚本,并为我的GoPro视频调用“ffcat” . 它基本上运行了几个“ffmpeg -i”命令,这些命令产生可连接的MPEG,它通过管道输出到ffmpeg命令,然后将它们转换为H.264 mp4文件 .

    它还将视频大小调整为720p,但您可能不希望这样 .

    "h264options"是我最近在互联网上找到的标志h264.code-shop.com

    希望这会有所帮助,里德


    cmd="( "
    
    h264options="-vcodec libx264 -b 512k -flags +loop+mv4 -cmp 256 \
     -partitions +parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 \
     -me_method hex -subq 7 -trellis 1 -refs 5 -bf 3 \
     -flags2 +bpyramid+wpred+mixed_refs+dct8x8 -coder 1 -me_range 16 \
       -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -qmin 10\
     -qmax 51 -qdiff 4"
    
    outfile="out-`date +%F-%H%M.%S`.mp4"
    
    for i; do
        cmd="${cmd}ffmpeg -i $i -ab 256000 -vb 10000000 -mbd rd -trellis 2 -cmp 2 -subcmp 2 -g 100 -f mpeg -; "
    done
    cmd="${cmd} ) | ffmpeg -y -i - -threads 8 ${h264options} -vb 10000000 -acodec libfaac -ar 44100 -ab 128k -s 1280x720 ${outfile}"
    echo "${cmd}"
    eval ${cmd}
    
  • 7

    假设您要连接电影,可以使用以下命令:

    ffmpeg -f concat -i inputs.txt -vcodec copy -acodec copy Mux1.mp4
    

    使用inputs.txt中的以下文本:

    file 75_540_38HQ2.mp4 
    file 76_70_20.mp4 
    file 76_173_80.mp4
    file 81_186_35.mp4
    

    Note :某些发行版(如Ubuntu)在其存储库中没有ffmpeg,而是将ffmpeg定义为avconv的别名 . 这对avconv不起作用,所以在这种情况下你必须自己编译ffmpeg . 您可以通过运行ffmpeg并检查第一个输出行是否以"the FFmpeg developers"结尾来检查您是否拥有真正的ffmpeg .

  • 3

    忘记FFmpeg,改用MP4Box,它简单快捷:

    mp4box -add video1.mp4 -cat video2.mp4 -cat video3.mp4 output.mp4
    

    它适用于Windows,Linux和OS X:http://www.videohelp.com/tools/mp4box

    如果你在Windows上,你可以使用YAMB,它是MP4Box的GUI,效果很好:http://www.videohelp.com/tools/YAMB

    UPDATE Jun-2016: FFmpeg添加了一个串联过滤器,更多信息请点击此处:https://stackoverflow.com/a/11175851/218418

  • 3

    从ffmpeg手册页“示例”部分:

    您可以在输出中放置许多相同类型的流:

    ffmpeg -i test1.avi -i test2.avi -vcodec copy -acodec copy \ -vcodec copy -acodec copy test12.avi -newvideo -newaudio
    

    除了第一个视频和音频流之外,生成的输出文件test12.avi将包含在输入流列表中找到的第二个视频和第二个音频流 .

    必须在要添加它们的输出文件的名称后面立即指定“-newvideo”,“ - newaudio”和“-newsubtitle”选项 .

    如果你想要连接它们,FAQ有说明 .

    我不确定这个问题/答案是否属于SuperUser .

  • 4

    如果所有输入视频具有相同的编解码器,并且您希望输出视频也在同一编解码器中,则简单concat适用于mp4和mkv文件 . https://trac.ffmpeg.org/wiki/Concatenate
    你需要创建一个像这样的文本文件

    # this is a comment
    file '/path/to/file1'
    file '/path/to/file2'
    file '/path/to/file3'
    

    然后使用命令

    ffmpeg -f concat -i mylist.txt -c copy output.mp4
    

    我使用了相同参考页面中的示例,它运行得很好 . 唯一的问题是视频未正确捕获 . 它可能会引入音频视频同步问题,因为它只是将PTS和DTS信息从源视频复制到目标视频 .
    要获得完整的校对解决方案,您需要逐个数据包读取视频,然后将所有数据包放在一个视频中,并进行自定义优化,例如丢弃重复的PTS数据包并保持单调的PTS值 .

  • 0

    我一直非常成功地使用这个脚本 . 结果很完美,因为它使用的是原始视频 .

    http://trac.ffmpeg.org/wiki/How%20to%20concatenate%20%28join,%20merge%29%20media%20files

    确保编辑EXTRA OPTIONS字符串 .

    #!/bin/bash
    
    ################################################################################
    #
    # Script name: MultiMedia Concat Script (mmcat)
    # Author: burek (burek021@gmail.com)
    # License: GNU/GPL, see http://www.gnu.org/copyleft/gpl.html
    # Date: 2012-07-14
    #
    # This script concatenates (joins, merges) several audio/video inputs into one
    # final output (just like as if all the inputs were played in a playlist, one
    # after another).
    #
    # All input files must have at least one audio and at least one video stream.
    # If not, you can easily add audio silence, using FFmpeg. Just search the
    # internet for "ffmpeg add silence".
    #
    # The script makes use of FFmpeg tool (www.ffmpeg.org) and is free for use under
    # the GPL license. The inspiration for this script came from this FAQ item:
    # http://ffmpeg.org/faq.html#How-can-I-join-video-files_003f
    #
    # If you find any bugs, please send me an e-mail so I can fix it.
    #
    ################################################################################
    #
    # General syntax: mmcat <input1> <input2> <input3> ... <output>
    #
    # For example: mmcat file1.flv file2.flv output.flv
    # would create "output.flv" out of "file1.flv" and "file2.flv".
    #
    ################################################################################
    
    # change this to what you need !!!
    EXTRA_OPTIONS='-vcodec libx264 -crf 23 -preset medium -acodec aac -strict experimental -ac 2 -ar 44100 -ab 128k'
    
    ################################################################################
    #
    # NO NEED TO TOUCH ANYTHING AFTER THIS LINE!
    #
    ################################################################################
    
    # the version of the script
    VERSION=1.3
    
    # location of temp folder
    TMP=/tmp
    
    ################################################################################
    
    echo "MultiMedia Concat Script v$VERSION (mmcat) - A script to concatenate multiple multimedia files."
    echo "Based on FFmpeg - www.ffmpeg.org"
    echo "Don't forget to edit this script and change EXTRA_OPTIONS"
    echo ""
    
    ################################################################################
    # syntax check (has to have at least 3 params: infile1, infile2, outfile
    ################################################################################
    if [ -z $3 ]; then
        echo "Syntax: $0 <input1> <input2> <input3> ... <output>"
        exit 1
    fi
    
    ################################################################################
    # get all the command line parameters, except for the last one, which is output
    ################################################################################
    # $first  - first parameter
    # $last   - last parameter (output file)
    # $inputs - all the inputs, except the first input, because 1st input is
    #           handled separately
    ################################################################################
    first=${@:1:1}
    last=${@:$#:1}
    len=$(($#-2))
    inputs=${@:2:$len}
    
    # remove all previous tmp fifos (if exist)
    rm -f $TMP/mcs_*
    
    ################################################################################
    # decode first input differently, because the video header does not have to be
    # kept for each video input, only the header from the first video is needed
    ################################################################################
    mkfifo $TMP/mcs_a1 $TMP/mcs_v1
    
    ffmpeg -y -i $first -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a1 2>/dev/null </dev/null &
    ffmpeg -y -i $first -an -f yuv4mpegpipe -vcodec rawvideo $TMP/mcs_v1 2>/dev/null </dev/null &
    
    # if you need to log the output of decoding processes (usually not necessary)
    # then replace the "2>/dev/null" in 2 lines above with your log file names, like this:
    #ffmpeg -y -i $first -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a1 2>$TMP/log.a.1 </dev/null &
    #ffmpeg -y -i $first -an -f yuv4mpegpipe -vcodec rawvideo $TMP/mcs_v1 2>$TMP/log.v.1 </dev/null &
    
    ################################################################################
    # decode all the other inputs, remove first line of video (header) with tail
    # $all_a and $all_v are lists of all a/v fifos, to be used by "cat" later on
    ################################################################################
    all_a=$TMP/mcs_a1
    all_v=$TMP/mcs_v1
    i=2
    for f in $inputs
    do
        mkfifo $TMP/mcs_a$i $TMP/mcs_v$i
    
        ffmpeg -y -i $f -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a$i 2>/dev/null </dev/null &
        { ffmpeg -y -i $f -an -f yuv4mpegpipe -vcodec rawvideo - 2>/dev/null </dev/null | tail -n +2 > $TMP/mcs_v$i ; } &
    
        # if you need to log the output of decoding processes (usually not necessary)
        # then replace the "2>/dev/null" in 2 lines above with your log file names, like this:
        #ffmpeg -y -i $f -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a$i 2>$TMP/log.a.$i </dev/null &
        #{ ffmpeg -y -i $f -an -f yuv4mpegpipe -vcodec rawvideo - 2>$TMP/log.v.$i </dev/null | tail -n +2 > $TMP/mcs_v$i ; } &
    
        all_a="$all_a $TMP/mcs_a$i"
        all_v="$all_v $TMP/mcs_v$i"
        let i++
    done
    
    ################################################################################
    # concatenate all raw audio/video inputs into one audio/video
    ################################################################################
    mkfifo $TMP/mcs_a_all
    mkfifo $TMP/mcs_v_all
    cat $all_a > $TMP/mcs_a_all &
    cat $all_v > $TMP/mcs_v_all &
    
    ################################################################################
    # finally, encode the raw concatenated audio/video into something useful
    ################################################################################
    ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i $TMP/mcs_a_all \
           -f yuv4mpegpipe -vcodec rawvideo -i $TMP/mcs_v_all \
        $EXTRA_OPTIONS \
        $last
    
    ################################################################################
    # remove all fifos
    ################################################################################
    rm -f $TMP/mcs_*
    
  • 4

    Concat demuxer

    concat demuxer被添加到ffmpeg 1.1中 . 如果您的ffmpeg版本为旧版本, get the newest static binary from here: http://www.ffmpeg.org/download.html

    说明

    创建一个文件 mylist.txt ,其中包含您希望以下列形式连接的所有文件(忽略以短划线开头的行):

    # this is a comment
    file '/path/to/file1'
    file '/path/to/file2'
    file '/path/to/file3'
    

    请注意,这些可以是相对路径或绝对路径 . 然后你可以使用以下代码编码文件:

    ffmpeg -f concat -i mylist.txt -c copy output
    

    可以使用bash for循环或使用printf生成此列表文件 . 以下任一项都会生成一个包含工作目录中每个* .wav的列表文件:

    for f in ./*.wav; do echo "file '$f'" >> mylist.txt; done
    printf "file '%s'\n" ./*.wav > mylist.txt
    

    资料来源:ffmpeg wiki

  • 13

    MP4Box可以在不破坏音频的情况下工作 . 我做了以下以取得好成绩:

    示例命令行:

    MP4Box -force-cat -add in1.mp4 -cat in2.mp4 -cat in3.mp4 ... out.mp4
    

    一些小评论:

    • 以上方式很重要,因为与Linux Mint 13一起发布的MP4Box的最新版本是错误的,并且确实导致音频损坏 .

    • -force-cat 很重要,因为视频格式标签在没有它的情况下从AVC更改为avc3 .

相关问题