0

Is it possible to concatenate many videos with different aspect ratio? So in the end every video segment maintains the original aspect ratio.

I've tried the following FFmpeg command:

ffmpeg -i 1.mp4 -i 2.mp4 -y -filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=unsafe=1:n=2:v=1:a=1 [v] [a]" -map "[v]" -map "[a]" out.mp4

I'm using unsafe=1 which works almost perfect.

The only issue is that some videos stretch. So, how can I concatenate different videos while maintaining the original quality and aspect ratio?

Bonus: Is something wrong with using unsafe=1?. The param name 'unsafe' implies that maybe I should trust it only under certain conditions.

UPDATE


I tried @llogan answer but it still produces the same result. Command I tried is

 ffmpeg -i 1.mp4 -i 2.mp4 -filter_complex "[0]scale=720:576:force_original_aspect_ratio=decrease,pad=720:576:(ow-iw)/2:(oh-ih)/2,setsar=1[v0];[1]scale=720:576:force_original_aspect_ratio=decrease,pad=720:576:(ow-iw)/2:(oh-ih)/2,setsar=1[v1];[v0][0:a:0][v1][1:a:0]concat=n=2:v=1:a=1[v][a]" -map "[v]" -map "[a]" out.mp4

Complete log:

ffmpeg version N-94862-g944d76a3e0 Copyright (c) 2000-2019 the FFmpeg developers built with gcc 9.1.1 (GCC) 20190807 configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf libavutil 56. 35.100 / 56. 35.100 libavcodec 58. 56.101 / 58. 56.101 libavformat 58. 32.104 / 58. 32.104 libavdevice 58. 9.100 / 58. 9.100 libavfilter 7. 58.102 / 7. 58.102 libswscale 5. 6.100 / 5. 6.100 libswresample 3. 6.100 / 3. 6.100 libpostproc 55. 6.100 / 55. 6.100 [mov,mp4,m4a,3gp,3g2,mj2 @ 0000028a5a96a180] st: 0 edit list: 2 Missing key frame while searching for timestamp: 0 [mov,mp4,m4a,3gp,3g2,mj2 @ 0000028a5a96a180] st: 0 edit list 2 Cannot find an index entry before timestamp: 0. Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '1.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 creation_time : 2019-06-04T10:36:32.000000Z Duration: 00:01:47.31, start: 0.080000, bitrate: 1354 kb/s Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 720x576 [SAR 64:45 DAR 16:9], 1194 kb/s, 24.96 fps, 25 tbr, 1k tbn, 20000k tbc (default) Metadata: creation_time : 2019-06-04T10:36:32.000000Z handler_name : FOUNDATION MEDIA HANDLER Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 152 kb/s (default) Metadata: creation_time : 2019-06-04T10:36:32.000000Z handler_name : FOUNDATION MEDIA HANDLER Input #1, mov,mp4,m4a,3gp,3g2,mj2, from '2.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 title : 914153178930195 encoder : Lavf56.40.101 Duration: 00:00:54.73, start: 0.000000, bitrate: 155 kb/s Stream #1:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 224x400 [SAR 190:189 DAR 76:135], 120 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc (default) Metadata: handler_name : VideoHandler Stream #1:1(und): Audio: aac (HE-AACv2) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 31 kb/s (default) Metadata: handler_name : SoundHandler File 'out.mp4' already exists. Overwrite ? [y/N] y Stream mapping: Stream #0:0 (h264) -> scale Stream #0:1 (aac) -> concat:in0:a0 Stream #1:0 (h264) -> scale Stream #1:1 (aac) -> concat:in1:a0 concat:out:v0 -> Stream #0:0 (libx264) concat:out:a0 -> Stream #0:1 (aac) Press [q] to stop, [?] for help [swscaler @ 0000028a5bd91600] Warning: data is not aligned! This can lead to a speed loss [libx264 @ 0000028a5aa1e600] using SAR=1/1 [libx264 @ 0000028a5aa1e600] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX [libx264 @ 0000028a5aa1e600] profile High, level 3.0, 4:2:0, 8-bit [libx264 @ 0000028a5aa1e600] 264 - core 158 r2984 3759fcb - H.264/MPEG-4 AVC codec - Copyleft 2003-2019 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00 Output #0, mp4, to 'out.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf58.32.104 Stream #0:0: Video: h264 (libx264) (avc1 / 0x31637661), yuv420p(progressive), 720x576 [SAR 1:1 DAR 5:4], q=-1--1, 25 fps, 12800 tbn, 25 tbc (default) Metadata: encoder : Lavc58.56.101 libx264 Side data: cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default) Metadata: encoder : Lavc58.56.101 aac frame= 4043 fps=127 q=-1.0 Lsize= 17387kB time=00:02:41.78 bitrate= 880.4kbits/s speed= 5.1x video:14740kB audio:2512kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.781354% [libx264 @ 0000028a5aa1e600] frame I:27 Avg QP:19.86 size: 31123 [libx264 @ 0000028a5aa1e600] frame P:1424 Avg QP:23.10 size: 7119 [libx264 @ 0000028a5aa1e600] frame B:2592 Avg QP:26.01 size: 1588 [libx264 @ 0000028a5aa1e600] consecutive B-frames: 4.5% 24.6% 16.2% 54.7% [libx264 @ 0000028a5aa1e600] mb I I16..4: 14.8% 42.4% 42.7% [libx264 @ 0000028a5aa1e600] mb P I16..4: 2.2% 3.8% 1.7% P16..4: 32.9% 13.8% 6.4% 0.0% 0.0% skip:39.0% [libx264 @ 0000028a5aa1e600] mb B I16..4: 0.2% 0.2% 0.1% B16..8: 28.5% 4.3% 0.7% direct: 1.1% skip:65.0% L0:40.5% L1:53.2% BI: 6.3% [libx264 @ 0000028a5aa1e600] 8x8 transform intra:47.2% inter:58.6% [libx264 @ 0000028a5aa1e600] coded y,uvDC,uvAC intra: 46.9% 56.9% 18.1% inter: 9.6% 11.2% 0.3% [libx264 @ 0000028a5aa1e600] i16 v,h,dc,p: 47% 29% 9% 16% [libx264 @ 0000028a5aa1e600] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 28% 18% 28% 4% 4% 5% 4% 5% 4% [libx264 @ 0000028a5aa1e600] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 37% 19% 11% 5% 6% 8% 5% 7% 4% [libx264 @ 0000028a5aa1e600] i8c dc,h,v,p: 50% 21% 24% 5% [libx264 @ 0000028a5aa1e600] Weighted P-Frames: Y:2.3% UV:0.6% [libx264 @ 0000028a5aa1e600] ref P L0: 67.3% 16.4% 11.9% 4.4% 0.1% [libx264 @ 0000028a5aa1e600] ref B L0: 89.6% 9.0% 1.4% [libx264 @ 0000028a5aa1e600] ref B L1: 98.6% 1.4% [libx264 @ 0000028a5aa1e600] kb/s:746.65 [aac @ 0000028a5a9a1e00] Qavg: 1320.561

0

1 Answer 1

3

how can I concatenate different videos while maintaining the original quality and aspect ratio?

using concat demuxer

Make text file containing:

file '1.mp4'
file '2.mp4'

Run ffmpeg:

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

This is fast and does not re-encode, so it will maintain the original quality, but it may not be supported or play correctly by your player or device. This assumes both inputs have the same formats, number of streams, timebase, etc, and the only difference is width x height and duration.

using concat filter

Use this if the first method doesn't work or if you have to re-encode anyway.

Add the scale, pad, setsar filters, and choose the desired output width x height. Example for 1280x720:

ffmpeg -i 1.mp4 -i 2.mp4 -filter_complex "[0]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1[v0];[1]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1[v1];[v0][0:a:0][v1][1:a:0]concat=n=2:v=1:a=1[v][a]" -map "[v]" -map "[a]" out.mp4

If you would rather crop instead of pad and/or avoid upscaling see examples in Resizing videos with ffmpeg to fit specific size.

As for "original quality" you would have to use a lossless encoder, not a lossy encoder. Add -crf 0 to enable lossless when encoding with libx264, but note the files will be huge. If you mean "visually, but not technically lossless" then use -crf 18. See FFmpeg Wiki: H.264.

unsafe

Is something wrong with using unsafe=1?. The param name 'unsafe' implies that maybe I should trust it only under certain conditions.

Without unsafe it will fail if segments have a different format or vary in some attributes, but with unsafe it will not fail but the resulting output may not be compatible or playable with your player or device.

12
  • Video still stretches. Small aspect ratio works fine but videos with big aspect ratios stretch. The result is the same as with the command of the question(unsafe=1). I'm thinking maybe if small aspect ratio adds padding, maybe that would work.
    – Oliver
    Dec 12, 2019 at 17:05
  • @Antony Provide your command and the complete log.
    – llogan
    Dec 12, 2019 at 18:12
  • Updated my question
    – Oliver
    Dec 13, 2019 at 18:28
  • @Antony I was lazy and assumed square pixels. Try "[0]scale=iw*sar:ih,setsar=1[ref];[1][ref]scale2ref=w=oh*mdar:h=ih[s][v0];[s]pad=1024:576:(ow-iw)/2:(oh-ih)/2,setsar=1[v1];[v0][0:a:0][v1][1:a:0]concat=n=2:v=1:a=1[v][a]" It can be also done without needing to enter any WxH values, but that can be dealt with later.
    – llogan
    Dec 13, 2019 at 23:50
  • Works! Please update your answer so I can accept it. If WxH values could be skipped that would be useful. Also, can you please explain the pad=1024:576 part?
    – Oliver
    Dec 14, 2019 at 10:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.