1

Here is my current command :

ffmpeg -i [videoFilepath] -i [musicFile] -stream_loop -1 -shortest -filter_complex "[1]volume=0.15:enable=between(t\,4\,10)+between(t\,14\,20)[a1];[0:a][a1]amix=inputs=2" -map 0:v:0 [outputFilepath]

What it does :

  • Takes a video file as an input
  • Takes a music file as an input
  • Loops the music if it is shorter than the video duration
  • If the music is longer, outputs a file the duration of the video
  • Reduce volume by 85% between 4 and 10 seconds as well as between 14 and 20 seconds
  • Mixes the 2 audio streams so we have both the original video audio non-filtered and the music with the volume filter
  • Outputs a video file

I want the volume filter to ease-in and ease-out for a duration of 1 second, instead of abruptly changing. Is this possible ?

1 Answer 1

0

A quick, maybe imperfect solution – use an expression in the volume filter, e.g. for linearly decreasing volume from 1 to 0.15 in the time interval between 4th and 5th second:

volume=1-0.85/(5-4)*(t-4):eval=frame

For time t=4, the volume will evaluate to 1, for t=5 it will be 0.15:

for t=4:    1 - 0.85 / (5-4) * (4-4) = 1 - 0.85 / (10-4) * 0 = 1 - 0 = 1
for t=5:    1 - 0.85 / (5-4) * (5-4) = 1 - 0.85 = 0.15 

enter image description here


You may use (nested) if functions for evaluating the volume value in different time intervals of your audio stream.

For example, to keep the value 1 for the first 4 seconds you may extend the previous formula

              1-0.85/(5-4)*(t-4)

with the help of the lt (less than) function into

if(lt(t\,4),1,1-0.85/(5-4)*(t-4))

enter image description here

and then – for keeping the value 0.15 after 5th second – into

if(lt(t\,4),1,if(lt(t\,5),1-0.85/(5-4)*(t-4),0.15))

enter image description here

And so on, always rewriting the last item with a new if function.

Of course, the resulting expression is not the optimal one, but the procedure is pretty straightforward.

8
  • Hi. Thank you for your answer @MarianD. From your question i came up with this function to decrease the volume : 1 - [ (1 - percentage) / ( stop - start) ] * ( time - start) And this is for the linearly increasing the volume : 1 - [ (1 - percentage) / (stop - start) ] * (stop - time) My question is now : I want the volume to decrease to 15% over 1s then stay at the same level between 2 times and finally increase back up to 100% over 1s. How would i go about doing that ?
    – Nobunaji
    Commented Jun 2, 2023 at 7:37
  • @Nobunaji, I extended my answer to show you how to progressively build the expression for your particular need.
    – MarianD
    Commented Jun 2, 2023 at 22:44
  • finally: ffmpeg -f lavfi -i "aevalsrc=sin(440*2*PI*t)" -af " volume='if(lt(t,4)+between(t,10,14)+gt(t,20),1, if(between(t,4,5),1-0.85*(t-4), if(between(t,9,10),0.15+0.85*(t-9), if(between(t,14,15),1-0.85*(t-14), if(between(t,19,20),0.15+0.85*(t-19), 0.15)))))':eval=frame " -b:a 320k -t 23 -y /tmp/out.mp3 Commented Jun 3, 2023 at 4:17
  • @БаярГончикжапов, nice, you are a smart man – why not to put it as another answer and gain some reputation points?
    – MarianD
    Commented Jun 3, 2023 at 14:34
  • @MarianD Why in your expression you put if(lt(t\,4),1,if(lt(t\,5),1-0.85/(5-4)*(t-4),0.15)) and not if(lt(t, 4), 1), if(lt(t, 5), 1-0.85/(5-4)*(t-4),0.15)) ? This makes more sense to me than to have one if inside of another.
    – Nobunaji
    Commented Jun 5, 2023 at 8:08

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.