0

Hello I want to achieve something like in this pic below using ffmpeg:

enter image description here

Initially I used below command:

ffmpeg -i input1.mp4 -i input2.mp4 -i input3.mp4 -filter_complex 
nullsrc=size=960x304 [base];
[0:v] crop=min(iw\,320):304:(iw-min(iw\,320))/2:0 [v0];
[1:v] crop=min(iw\,320):304:(iw-min(iw\,320))/2:0 [v1];
[2:v] crop=min(iw\,320):304:(iw-min(iw\,320))/2:0 [v2];
[base][v0] overlay=x=0:y=0[tmp0];
[tmp0][v1] overlay=x=320:y=0[tmp1];
[tmp1][v2] overlay=x=640:y=0[tmp2]
 -map [tmp2] -c:v libx264 output.mp4

It was working well but audio was missing in the output so I used below command to mix audios of input videos:

ffmpeg -i input1.mp4 -i input2.mp4 -i input3.mp4 -filter_complex 
nullsrc=size=960x304 [base];
[0:v] crop=min(iw\,320):304:(iw-min(iw\,320))/2:0 [v0];
[1:v] crop=min(iw\,320):304:(iw-min(iw\,320))/2:0 [v1];
[2:v] crop=min(iw\,320):304:(iw-min(iw\,320))/2:0 [v2];
[base][v0] overlay=x=0:y=0[tmp0];
[tmp0][v1] overlay=x=320:y=0[tmp1];
[tmp1][v2] overlay=x=640:y=0[tmp2];
[0:a][1:a][2:a]amix=inputs=3:duration=shortest[audio] 
-map [tmp2] -map [audio] -c:v libx264 output.mp4

I don't know what happened but the execution never stops. It keeps on going. I thought the input audio's sample rate and channel types are mismatched, so I tried below:

ffmpeg -i input1.mp4 -i input2.mp4 -i input3.mp4 -filter_complex 
nullsrc=size=960x304 [base];
[0:v] crop=min(iw\,320):304:(iw-min(iw\,320))/2:0 [v0];
[1:v] crop=min(iw\,320):304:(iw-min(iw\,320))/2:0 [v1];
[2:v] crop=min(iw\,320):304:(iw-min(iw\,320))/2:0 [v2];
[base][v0] overlay=x=0:y=0[tmp0];
[tmp0][v1] overlay=x=320:y=0[tmp1];
[tmp1][v2] overlay=x=640:y=0[tmp2];
[0:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,volume=1[audio0];
[1:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,volume=1[audio1];
[2:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,volume=1[audio2];
[audio0][audio1][audio2]amix=inputs=3:duration=shortest[audio] 
-map [tmp2] -map [audio] -c:v libx264 output.mp4

but same result. The execution never stops. I think there is something with audio handling. Also currently if I remove audio portion and only output video, the output video stops when shortest of the video finishes. I want that the output video should have lenght of the longest video. The short clips should display their last frame until the longest video finishes. Any help regarding this?

PS: Logs from logcat:

ffmpeg version 3.3.4
     Copyright (c) 2000-2017 the FFmpeg developers
      built with gcc 4.9 (GCC) 20140827 (prerelease)

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input1.mp4':
      Metadata:
        major_brand     : 
    isom
        minor_version   : 
    512
        compatible_brands: 
    isomiso2avc1mp41
        title           : 
    1946246598843281
        encoder         : 
    Lavf56.40.101
      Duration: 
    00:00:53.91
    , start: 
    -0.022109
    , bitrate: 
    256 kb/s
        Stream #0:0
    (und)
    : Video: h264 (avc1 / 0x31637661), yuv420p, 400x304, 206 kb/s
    , 
    25 fps, 
    25 tbr, 
    90k tbn, 
    50 tbc
     (default)
        Metadata:
          handler_name    : 
    VideoHandler
        Stream #0:1
    (und)
    : Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 47 kb/s
     (default)
        Metadata:
          handler_name    : 
    SoundHandler
Input #1, mov,mp4,m4a,3gp,3g2,mj2, from 'input2.mp4':
      Metadata:
        major_brand     : 
    isom
        minor_version   : 
    512
        compatible_brands: 
    isomiso2avc1mp41
title           : 
    617689615538740
        encoder         : 
    Lavf56.40.101
      Duration: 
    00:00:15.37
    , start: 
    -0.022109
    , bitrate: 
    392 kb/s
        Stream #1:0
    (und)
    : Video: h264 (avc1 / 0x31637661), yuv420p, 400x400, 349 kb/s
    , 
    30 fps, 
    30 tbr, 
    90k tbn, 
    60 tbc
     (default)
        Metadata:
          handler_name    : 
    VideoHandler
        Stream #1:1
    (und)
    : Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 47 kb/s
     (default)
        Metadata:
          handler_name    : 
    SoundHandler
Input #2, mov,mp4,m4a,3gp,3g2,mj2, from 'input3.mp4':
      Metadata:
        major_brand     : 
    isom
        minor_version   : 
    512
        compatible_brands: 
    isomiso2avc1mp41
        encoder         : 
    Lavf57.25.100
      Duration: 
    00:00:05.97
    , start: 
    0.000000
    , bitrate: 
    770 kb/s
        Stream #2:0
    (und)
    : Audio: aac (mp4a / 0x6134706D), 22050 Hz, stereo, fltp, 128 kb/s
     (default)
        Metadata:
          handler_name    : 
    SoundHandler
        Stream #2:1
    (und)
    : Video: h264 (avc1 / 0x31637661), yuv420p, 368x480, 608 kb/s
    , 
27.29 fps, 
    120 tbr, 
    12k tbn, 
    60 tbc
     (default)
        Metadata:
          handler_name    : 
    VideoHandler
Stream mapping:
      Stream #0:0 (h264) -> crop
      Stream #0:1 (aac) -> aformat
      Stream #1:0 (h264) -> crop
      Stream #1:1 (aac) -> aformat
      Stream #2:0 (aac) -> aformat
      Stream #2:1 (h264) -> crop
      overlay
     -> Stream #0:0 (libx264)
      amix
     -> Stream #0:1 (aac)
    Press [q] to stop, [?] for help

2 Answers 2

1

Upgrade to v 4.3 and limit the duration of the base layer, which is infinite, by default. Audio is fine.

ffmpeg -i input1.mp4 -i input2.mp4 -i input3.mp4 -filter_complex 
nullsrc=size=960x304,trim=0:1 [base];
[0:v] crop=min(iw\,320):304:(iw-min(iw\,320))/2:0 [v0];
[1:v] crop=min(iw\,320):304:(iw-min(iw\,320))/2:0 [v1];
[2:v] crop=min(iw\,320):304:(iw-min(iw\,320))/2:0 [v2];
[base][v0] overlay=x=0:y=0[tmp0];
[tmp0][v1] overlay=x=320:y=0[tmp1];
[tmp1][v2] overlay=x=640:y=0[tmp2];
[0:a][1:a][2:a]amix=inputs=3:duration=longest[audio] 
-map [tmp2] -map [audio] -c:v libx264 output.mp4
2
  • I don't know how to limit the duration of the [base] layer. Though, I added trim=0:1 in base layer as you added but the result is same. Commented Jul 16, 2020 at 15:51
  • 2
    Works here with v4.3
    – Gyan
    Commented Jul 16, 2020 at 16:24
0

Already answered in other page

I just copy paste it

The overlay filter has a shortest option:

If set to 1, force the output to terminate when the shortest input terminates. Default value is 0.

Example:

ffmpeg -i input -filter_complex "color[c];[0:v][c]overlay=shortest=1" output

Usage of shortest is needed because the color duration is indefinite (unless you use the d option).

Your Answer

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

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