Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Audio and Video not synced after ffmpeg filter_complex select between

I am trying to trim a video shoot on an iPhone.

When I execute:

ffmpeg -i IMG_8555.MOV \
-filter_complex " \
[0:v] select='between(t,448.856,1279.240)', setpts=N/FR/TB; \
[0:a] aselect='between(t,448.856,1279.240)', asetpts=N/SR/TB \ 
" \ 
output.mov

the output audio is out of sync - audio is faster (noticeable towards the end of the output video).

I noticed that the outputs frame rate is 29.97 while the inputs is 29.98.

So I did some experimenting and changed setpts to setpts=N/29.98/TB; but still the video is falling behind. So I changed it even more to setpts=N/30.00/TB; - then it feels almost ok.

I tired adding -vsync 1 - no luck

I tried adding -async 1 - no luck

I tried adding -async 7000 - no luck

edit: If i put setpts=N/29.99/TB then it is ideal.

Any ideas how can I make it always synced (no matter what is the input)?

like image 508
RadekJ Avatar asked Dec 01 '25 13:12

RadekJ


2 Answers

@kesh's method worked for the mentioned problem but it was causing the other overlays (not included in this example) using enable='between(...)' to be off sync, so I couldnt go with that solution.

At the end I managed to still use between and setpts but without using FRAME_RATE constant to calculate new pts values.

Here is an example of my approach, assuming I want to have 3 cuts like that:

[start1, end1]---[start2,end2]---[start3,end3]
ffmpeg -i input.mov \
[0:v] \
select='between(t,start1,end1)+between(t,start2,end2)+between(t,start3,end3)', \
setpts='PTS-STARTPTS-(gt(T,end1)*(start2-end1) + gt(T,end2)*(start3-end2) )/TB'; \
[0:a] \
aselect='between(t,start1,end1)+between(t,start2,end2)+between(t,start3,end3)', \ 
asetpts='PTS-STARTPTS-(gt(T,end1)*(start2-end1) + gt(T,end2)*(start3-end2) )/TB' \
output.mov

Note that gt(t,100) returns 1 if it is greather than 100 and 0 otherwise. I am using it to shift PTS by the gap between previous cuts (start2-end1). If the current T is less than end1 then the value of gt(T,end1) will be 0. So start2-end1 wont be added (as it is multiplied by zero)

like image 90
RadekJ Avatar answered Dec 04 '25 05:12

RadekJ


Try this:

ffmpeg -ss 448.86 -to 1279.240 -i IMG_8555.MOV output.mov

<addendum>

If you have more cuts, then you can try one of the following 2 approaches:

  1. specify them as different inputs then concat
ffmpeg -ss 0 -to 1 -i IMG_8555.MOV \
       -ss 4 to 5 -i IMG_8555.MOV \
       ...
       -ss 448.86 -to 1279.240 -i IMG_8555.MOV \
       -filter_complex [0:v][0:a][1:v][1:a]...[99:v][99:a]concat
       output.mov
  1. (Unverified but likely work) Use concat demuxer. First create a concat file, name it say IMG_8555_trim.ffconcat and save it on the same folder as the video file
ffconcat version 1.0

file IMG_8555.MOV
inpoint 0 
outpoint 1 

file IMG_8555.MOV
inpoint 4
outpoint 5 

...

file IMG_8555.MOV
inpoint 448.86
outpoint 1279.240

then run

ffmpeg -i IMG_8555_trim.ffconcat output.mov
like image 44
kesh Avatar answered Dec 04 '25 07:12

kesh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!