Is it possible to conditionally enable or disable filters/streams with user input?

Solution 1:

On initial testing I thought this would be pretty complicated, but it turned out to be simpler than expected - it can be dealt with entirely in Bash, by wrapping each stream that references the conditional stream in a variable.

The real trouble - as pigeonburger guessed - is in taking care of all the references to the stream, especially the final one that outputs the video: this stream's variable needs to have its content set conditionally, and in my case also involved using a "dummy" filter like setsar=1 to avoid an empty stream error.

After that, the hardest part is making sure all the stream labels match in both conditions - if not, they'll need to be conditionally renamed just like with the final stream.

The below example asks the user whether they want to apply a watermark to the video: if anything other than N or n is entered, it applies the watermark by setting the necessary streams and then running the FFmpeg command with them.

read -p "Add watermark to video? [Y/n] " -n1 -r
if [[ $REPLY =~ ^[Nn]$ ]]; then
unset wmstream1
unset wmstream2
wmstream3="[tmp2]setsar=1[outv];"
else
wmstream1="[2:v]lut=a=val*0.7,fade=in:st=5:d=2:alpha=1,fade=out:st=$length1:d=2:alpha=1[v2];"
wmstream2="[v2][tmp2]scale2ref=w=oh*mdar:h=ih*0.1[wm_scaled][video];"
wmstream3="[video][wm_scaled]overlay=W-w-50:50:format=auto:shortest=1[outv];"
fi
ffmpeg -y   -i "$1" -i "outro.mp4" -loop 1 -i "../Watermark/watermark3.png" \
-t 20 \
-movflags +faststart \
-preset ultrafast \
-filter_complex \
"color=black:16x16:d=$total[base]; \
[0:v]scale=-2:'max(1080,ih)',setpts=PTS-STARTPTS[v0]; \
[1:v]fade=in:st=0:d=$fadeduration:alpha=1,setpts=PTS-STARTPTS+(($fadetime)/TB)[v1]; \
$wmstream1 \
[base][v0]scale2ref[base][v0]; \
[base][v0]overlay[tmp]; \
[tmp][v1]overlay,setsar=1[tmp2]; \
$wmstream2 \
$wmstream3 \
[0:a][1:a]acrossfade=d=$fadeduration[outa]" \
-map "[outv]" -map "[outa]" -c:v libx264 -c:a libopus -crf 17 "$output"

Although it's probably far from being as robust or succinct as a better Bash programmer than me can make it, it's definitely more succinct and more maintainable than the alternative of messing with two separate commands.