user17213: I'm working on a project where I'm using ffmpeg to batch convert some video files, and adding fade in/out effects at the head and tail of each clip.
I've been using this bit of code to add the fade/out effect on clips with known durations:

ffmpeg -i clip.mp4 -filter:v 'fade=in:0:30,fade=out:9650:30' -c:v libx264 -crf 22 -preset veryfast -c:a copy fadeInOut.mp4

My two questions are:

How can I simultaneously fade the audio in/out?
Can ffmpeg automatically figure out the duration of the clip and be told just fade out the last 30 frames?

Thanks!

user10727: The answer to question 2 is a resounding YES! I was looking for the same functionality and I ended up writing a bash script that asks for fade duration in seconds and calculates the initial frame for the fade-out:
#!/bin/bash

f="$*" # all args
p="${f##*/}" # file
fn="${p%.*}" # name only
e="${p##*.}" # extension

echo
echo $f
echo $p
echo $fn
echo $e
echo

read -e -p "Number of seconds of fade-out: " -i 1 sec # prompt for fade duration in seconds

r=$(ffprobe -show_streams "$f" 2> /dev/null | grep r_frame_rate | head -1 | cut -d \= -f 2) # frame rate
let "frames = $r * $sec" # duration of fade as number of frames
echo $r
echo $sec
echo $frames
lf=$(ffprobe -show_streams "$f" 2> /dev/null | grep nb_frames | head -1 | cut -d \= -f 2) # total number of frames
let "lf = $lf - $frames" # initial frame to start fade at

ffmpeg -loglevel quiet -i "$f" -vf fade=out:$lf:$frames -r $r -vcodec libx264 -preset slow -crf 12 -bf 2 -flags +cgop -pix_fmt yuv420p -acodec copy "$fn $sec sec fade-out.$e"
open "$fn $sec sec fade-out.$e"

Fades require re-encoding so using a low crf value for libx264 gives a high quality re-encode. The comments should explain everything else.

user19752: It's a terrible hack, but this might work if all you want to do is audio fade in/out but don't know exactly how long the clip is:
ffmpeg -i input.mp4 -filter_complex "afade=d=0.5, areverse, afade=d=0.5, areverse" output.mp4

[edit 2019-07-24:  Note that this solution is not good for streaming solutions since it requires the full track to be processed before the first byte can be streamed]
another option I is to use acrossfade with a silent track:
ffmpeg -i input.mp4 -filter_complex "aevalsrc=0:d=0.6 [a_silence]; [0:a:0] [a_silence] acrossfade=d=0.6" output.mp4


user1871: #1 To simultaneously fade the audio in/out:
ffmpeg -i clip.mp4 -vf 'fade=in:0:30,fade=out:960:30'
                   -af 'afade=in:st=0:d=1,afade=out:st=32:d=1'
       -c:v libx264 -crf 22 -preset veryfast fadeInOut.mp4

The afade times are in seconds.
#2 Automatically? No. But see workaround below
You can first run ffprobe to get duration.
ffprobe -i clip.mp4 -show_entries stream=codec_type,duration -of compact=p=0:nk=1

You'll get something like this:
video|13.556000
audio|13.816000

You can then use the above to place your fades. These times are in seconds.
Workaround
ffmpeg -i clip.mp4 -sseof -1 -copyts -i clip.mp4 -filter_complex
       "[1]fade=out:0:30[t];[0][t]overlay,fade=in:0:30[v];
        anullsrc,atrim=0:2[at];[0][at]acrossfade=d=1,afade=d=1[a]"
       -map "[v]" -map "[a]" -c:v libx264 -crf 22 -preset veryfast -shortest fadeInOut.mp4

FFmpeg has a sseof option that allows one to seek an input from the end. We can use that to accomplish our goal. So we feed the input twice, with the 2nd time ingesting only the last second. We tell FFmpeg to preserve the timestamps, so that ffmpeg preserves the temporal position of this tail portion. 
We apply a fade out to this tail and then overlay the result onto the full input. Since they are the same media file, the foreground completely covers the background, and since copyts was applied, the overlay happens upon the corresponding identical frame in the background input.
For audio, we create a blank dummy audio of duration 2 seconds, and then apply an audio crossfade from the main audio to this dummy audio. Since the 2nd audio is blank, this is, in effect, a fade-out for the main input. The -shortest is added to leave out portions of the dummy audio after the crossfade has occurred.

17213: <p>I'm working on a project where I'm using ffmpeg to batch convert some video files, and adding fade in/out effects at the head and tail of each clip.</p>

<p>I've been using this bit of code to add the fade/out effect on clips with known durations:</p>

<p><code>
ffmpeg -i clip.mp4 -filter:v 'fade=in:0:30,fade=out:9650:30' -c:v libx264 -crf 22 -preset veryfast -c:a copy fadeInOut.mp4
</code></p>

<p>My two questions are:</p>

<ol>
<li>How can I simultaneously fade the audio in/out?</li>
<li>Can ffmpeg automatically figure out the duration of the clip and be told just fade out the last 30 frames?</li>
</ol>

<p>Thanks!</p>
 10727: <p>The answer to question 2 is a resounding YES! I was looking for the same functionality and I ended up writing a bash script that asks for fade duration in seconds and calculates the initial frame for the fade-out:</p>

<pre><code>#!/bin/bash

f="$*" # all args
p="${f##*/}" # file
fn="${p%.*}" # name only
e="${p##*.}" # extension

echo
echo $f
echo $p
echo $fn
echo $e
echo

read -e -p "Number of seconds of fade-out: " -i 1 sec # prompt for fade duration in seconds

r=$(ffprobe -show_streams "$f" 2&gt; /dev/null | grep r_frame_rate | head -1 | cut -d \= -f 2) # frame rate
let "frames = $r * $sec" # duration of fade as number of frames
echo $r
echo $sec
echo $frames
lf=$(ffprobe -show_streams "$f" 2&gt; /dev/null | grep nb_frames | head -1 | cut -d \= -f 2) # total number of frames
let "lf = $lf - $frames" # initial frame to start fade at

ffmpeg -loglevel quiet -i "$f" -vf fade=out:$lf:$frames -r $r -vcodec libx264 -preset slow -crf 12 -bf 2 -flags +cgop -pix_fmt yuv420p -acodec copy "$fn $sec sec fade-out.$e"
open "$fn $sec sec fade-out.$e"
</code></pre>

<p>Fades require re-encoding so using a low <code>crf</code> value for <code>libx264</code> gives a high quality re-encode. The comments should explain everything else.</p>
 19752: <p>It's a terrible hack, but this might work if all you want to do is audio fade in/out but don't know exactly how long the clip is:</p>

<pre><code>ffmpeg -i input.mp4 -filter_complex "afade=d=0.5, areverse, afade=d=0.5, areverse" output.mp4
</code></pre>

<p>[edit 2019-07-24:  Note that this solution is not good for streaming solutions since it requires the full track to be processed before the first byte can be streamed]</p>

<p>another option I is to use <code>acrossfade</code> with a silent track:</p>

<pre><code>ffmpeg -i input.mp4 -filter_complex "aevalsrc=0:d=0.6 [a_silence]; [0:a:0] [a_silence] acrossfade=d=0.6" output.mp4
</code></pre>
 1871: <p><strong>#1</strong> To simultaneously fade the audio in/out:</p>

<pre><code>ffmpeg -i clip.mp4 -vf 'fade=in:0:30,fade=out:960:30'
                   -af 'afade=in:st=0:d=1,afade=out:st=32:d=1'
       -c:v libx264 -crf 22 -preset veryfast fadeInOut.mp4
</code></pre>

<p>The afade times are in <em>seconds</em>.</p>

<p><strong>#2</strong> Automatically? No. But see workaround below</p>

<p>You can first run ffprobe to get duration.</p>

<pre><code>ffprobe -i clip.mp4 -show_entries stream=codec_type,duration -of compact=p=0:nk=1
</code></pre>

<p>You'll get something like this:</p>

<pre><code>video|13.556000
audio|13.816000
</code></pre>

<p>You can then use the above to place your fades. These times are in seconds.</p>

<p><strong>Workaround</strong></p>

<pre><code>ffmpeg -i clip.mp4 -sseof -1 -copyts -i clip.mp4 -filter_complex
       "[1]fade=out:0:30[t];[0][t]overlay,fade=in:0:30[v];
        anullsrc,atrim=0:2[at];[0][at]acrossfade=d=1,afade=d=1[a]"
       -map "[v]" -map "[a]" -c:v libx264 -crf 22 -preset veryfast -shortest fadeInOut.mp4
</code></pre>

<p>FFmpeg has a <code>sseof</code> option that allows one to seek an input from the end. We can use that to accomplish our goal. So we feed the input twice, with the 2nd time ingesting only the last second. We tell FFmpeg to preserve the timestamps, so that ffmpeg preserves the temporal position of this tail portion. </p>

<p>We apply a fade out to this tail and then overlay the result onto the full input. Since they are the same media file, the foreground completely covers the background, and since <code>copyts</code> was applied, the overlay happens upon the corresponding identical frame in the background input.</p>

<p>For audio, we create a blank dummy audio of duration 2 seconds, and then apply an audio crossfade from the main audio to this dummy audio. Since the 2nd audio is blank, this is, in effect, a fade-out for the main input. The <code>-shortest</code> is added to leave out portions of the dummy audio after the crossfade has occurred.</p>
