TransWikia.com

ffmpeg - add multiple videos in panes, give offset start times how?

Super User Asked by Betty Crokker on January 21, 2021

In these days of COVID, our choir director is recording a video which is the accompaniment, and then each choir member (at home) is listening to the accompaniment in headphones, singing along, and recording their voice and lovely face as a video. I now want to take all these disparate videos and combine them into one video with all the members in small panes, Brady Bunch style. And of course, each choir member has different hardware so the audio levels are all different and need to be normalized. And of course, one person took the video sideways (portrait instead of landscape) so their video has to be cropped before adding it in.

I’ve got it mostly working, my command line looks like this (simplified):

ffmpeg -y -i "Director.MOV"
   -i "Member1.MOV"
   -i "Member2.mp4"
   -filter_complex "
      nullsrc=size=1920x1080 [base];
      [0:v] scale=960x540 [clip0];
      [0:a]volume=1[aud0];
      [1:v] crop=1080:1000:0:920,scale=583x540 [clip1];
      [1:a]volume=2[aud1];
      [2:v] scale=960x540 [clip2];
      [2:a]volume=1.1[aud2];
      [base][clip0] overlay=shortest=1:x=0:y=0 [tmp0];
      [tmp0][clip1] overlay=shortest=1:x=1148:y=0 [tmp1];
      [tmp1][clip2] overlay=shortest=1:x=0:y=540 [tmp2];
      [aud0][aud1][aud2]amix=inputs=3[a]
   " -map "[tmp2]" -map "[a]" -c:v libx264 output.mkv"

That’s working beautifully.

Now for the (hopefully final) issue. Everybody hit the "record" button at different times, so the videos have to be time-shifted before being combined.

I tried adding -itsoffet as mentioned here, but of course that offsets the video and not the audio. I tried adding the offset after the STARTPTS as mentioned here, and again that offsets only the video. I tried offsetting the audio using the asetpts method as mentioned here but that didn’t seem to do anything.

EDIT

[0:v] setpts=PTS-STARTPTS-0.2/TB,scale=960x540 [clip0];
[0:a]volume=1.7066118239302597,asetpts=PTS-STARTPTS-0.2/TB[aud0];
[1:v] setpts=PTS-STARTPTS-3.2/TB,crop=1080:1000:0:920,scale=583x540 [clip1];
[1:a]volume=2.384951956074125,asetpts=PTS-STARTPTS-3.2/TB[aud1];
[2:v] setpts=PTS-STARTPTS,scale=960x540 [clip2];
[2:a]volume=1.1[aud2];

How do I shift videos forward or backward in time, while keeping their audio in sync?

I tried going the other direction (adding a positive offset to the videos that started later, instead of a negative offset to the videos that started sooner), just to see what would happen (see if PTS-STARTPTS doesn’t like negative numbers), and it was no better –

[0:v] setpts=PTS-STARTPTS+3/TB,scale=960x540 [clip0];
[0:a]volume=1.7066118239302597,asetpts=PTS-STARTPTS+3/TB[aud0];
[1:v] setpts=PTS-STARTPTS,crop=1080:1000:0:920,scale=583x540 [clip1];
[1:a]volume=2.384951956074125[aud1];
[2:v] setpts=PTS-STARTPTS+3.2/TB,scale=960x540 [clip2];
[2:a]volume=1.1,asetpts=PTS-STARTPTS+3.2/TB[aud2];
[base][clip0] overlay=shortest=1:x=0:y=0 [tmp0];
[tmp0][clip1] overlay=shortest=1:x=1148:y=0 [tmp1];
[tmp1][clip2] overlay=shortest=1:x=0:y=540 [tmp2];
[aud0][aud1][aud2]amix=inputs=3[a]

EDIT: ffmpeg -version reports

ffmpeg version git-2020-08-07-fab00b0 Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 10.2.1 (GCC) 20200805

which seems reasonably up-to-date.

One Answer

itsoffset works on audio as well; it's just that amix doesn't respect absolute timestamps. Use aresample to pad the start with silence.

I'd also suggest you alter offsets with respect to the earliest starting video, so all offsets are positive. overlay has to be altered to avoid showing a frozen first frame till playback starts, for delayed streams.

ffmpeg -y -i "Director.MOV"
   -itsoffset 5 -i "Member1.MOV"
   -itsoffset 10 -i "Member2.mp4"
   -filter_complex "
      nullsrc=size=1920x1080 [base];
      [0:v] scale=960x540 [clip0];
      [0:a]volume=1[aud0];
      [1:v] crop=1080:1000:0:920,scale=583x540 [clip1];
      [1:a]volume=2,aresample=async=1:first_pts=0[aud1];
      [2:v] scale=960x540 [clip2];
      [2:a]volume=1.1,aresample=async=1:first_pts=0[aud2];
      [base][clip0] overlay=shortest=1:x=0:y=0 [tmp0];
      [tmp0][clip1] overlay=shortest=1:x=1148:y=0:enable='gt(t,5)' [tmp1];
      [tmp1][clip2] overlay=shortest=1:x=0:y=540:enable='gt(t,10) [tmp2];
      [aud0][aud1][aud2]amix=inputs=3[a]
   " -map "[tmp2]" -map "[a]" -c:v libx264 output.mkv"

Use ffmpeg 4.1 or later.

Correct answer by Gyan on January 21, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP