ffmpeg: Combine/merge multiple mp4 videos not working, output only contains the first video

107,202

Solution 1

You have to convert them into an MPEG format that can be easily concatenated. Below is a script I use and call "ffcat" for my GoPro videos. It essentially runs several "ffmpeg -i" commands which produce concatenate-able MPEG, which is piped to an ffmpeg command that then converts them to an H.264 mp4 file.

It also sizes the videos to 720p but you may not want that.

The "h264options" are flags I recently found on the internet at h264.code-shop.com

Hope this helps, Reid


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}

Solution 2

Assuming you want to concatenate the movie, you can use the following command:

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

With the following text in inputs.txt:

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

Note: some distributions (like Ubuntu) do not have ffmpeg in their repository and instead define ffmpeg to be an alias of avconv. This won't work with avconv, so in such a case you have to compile ffmpeg yourself. You can check whether you have the real ffmpeg by running ffmpeg and checking if the first output line ends with "the FFmpeg developers".

Solution 3

Forget about FFmpeg, use MP4Box instead, it is easy and faster:

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

It is available for Windows, Linux and OS X: http://www.videohelp.com/tools/mp4box

If you are on Windows you can use YAMB which is a GUI for MP4Box that works great: http://www.videohelp.com/tools/YAMB

UPDATE Jun-2016: FFmpeg has added a concatenation filter, more info here: https://stackoverflow.com/a/11175851/218418

Solution 4

From the ffmpeg man page "Examples" section:

You can put many streams of the same type in the output:

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

In addition to the first video and audio streams, the resulting output file test12.avi will contain the second video and the second audio stream found in the input streams list.

The "-newvideo", "-newaudio" and "-newsubtitle" options have to be specified immediately after the name of the output file to which you want to add them.

If you meant you want to concatenate them, the FAQ has instructions.

I'm not sure if this question/answer belongs on SuperUser.

Solution 5

Simple concat works for mp4 and mkv files if all the input videos have the same codec and you want output video also in same codec. https://trac.ffmpeg.org/wiki/Concatenate
you need to creat a text file like

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

And then use command

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

I have used the example from the same reference page, it works pretty well. The only issue comes when video is not properly captured. It might introduce audio video sync issues because it just copies the PTS and DTS information from the source videos to the destination video.
To get a full proof solution you need to read video packet-by-packet and then put together all the packets in one video with customized optimizations like dropping repeating PTS packets and maintaining monotonic PTS values.

Share:
107,202
dtbaker
Author by

dtbaker

Hey I'm Dave

Updated on August 18, 2021

Comments

  • dtbaker
    dtbaker almost 3 years

    Here is the command I am using to combine multiple videos:

    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

    The resulting Mux1.mp4 does not contain all videos. Only the first video (75_540_38HQ2.mp4). The file size of the source and resulting video is below (as you can see, resulting video is slightly larger than first vid):

    $ 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
    

    Here is the output of the ffmpeg command. To me it looks ok, showing the multiple source inputs and the single output.

    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%
    

    Am I doing something blindingly stupid here?

    The source videos came from a video camera, and are small snippets taken with ffmpeg -i bigfile.mp4 -ss 20 -t 10 -vcodec copy etc..

    Thanks heaps!! Dave


    Edit: couldn't solve it so I just use avidemux GUI tool. It seemed to append the MP4's just fine.

    Must be a problem with MP4's or just the ones that come off a gopro camera.