I have a list of mp4 and an aac audio file. I have a concat.txt file with all the mp4s that need to be concatenated. I need to concat all the mp4s and merge the aac on top.
As said in the title, the mp4s individually may or may not have an audio track, and I can not check the mp4s with no audio, add a dummy sound track as it will be an automated process with thousands of commands executed daily.
The sound of the mp4, if present, must be preserved and merged with the aac
Here is a working command for the case where at least the first of my mp4s has an audiotrack:
ffmpeg -f concat -safe 0 -i concat.txt -i audio.aac -c:v copy -filter_complex "[0:a][1:a] amix=inputs=2:duration=shortest [audio_out]" -map 0:v -map "[audio_out]" -y result.mp4
However that breaks if my mp4s dont have audio
Stream specifier ':a' in filtergraph description [0:a][1:a] amix=inputs=2:duration=shortest [audio_out] matches no streams.
I've been reading about anullsrc, and would like to take [0:a] if it exists, or a generated empty audio channel, and merge it with my aac, but I'm not getting there.
Any help would be appreciated
Thanks
bash script
#!/bin/bash
#LST=($(ls -1tr *.mp4))
LST=("input 1.mp4" "only_video.mp4" "1280x720x30_2.mp4")
#LST=("1280x720x30_1.mp4" "only_video.mp4" "1280x720x30_2.mp4")
f="${LST[0]}"
IFS=, read VID WID HEI SAR FMT FPS TBN <<< $(ffprobe -v 0 -select_streams v:0 -show_entries stream=codec_name,width,height,sample_aspect_ratio,r_frame_rate,time_base,pix_fmt -of csv=p=0 "$f")
echo $VID $WID $HEI $SAR $FMT $FPS $TBN
if [ "$SAR" = "N/A" ]; then SAR=1; fi
#FPS=30
TBN=${TBN#*/}
echo $VID $WID $HEI $SAR $FMT $FPS $TBN
IFS=, read AUD SRA CHL <<< $(ffprobe -v 0 -select_streams a:0 -show_entries stream=codec_name,channel_layout,sample_rate -of csv=p=0 "$f")
echo $AUD $SRA $CHL
TXT=list.txt
mkdir out
o="out/${f%.*}.mkv"
ffmpeg -i "$f" -c copy "$o" -y -hide_banner
echo "file '$o'" > $TXT
for (( i=1; i<${#LST[@]}; i++ )); do
f="${LST[$i]}"
o="out/${f%.*}.mkv"
AU2=$(ffprobe -v 0 -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if [ "$AU2" = "" ]; then
echo --- create empty audio
ffmpeg -i "$f" -f lavfi -i anullsrc -c:v copy -c:a $AUD -q:a 5 -shortest "$o" -y -hide_banner
else
if [ "$AU2" = "$AUD" ]; then
echo --- copy audio
ffmpeg -i "$f" -c copy "$o" -y -hide_banner
else
echo --- encode audio
ffmpeg -i "$f" -c:v copy -c:a $AUD -q:a 5 -shortest "$o" -y -hide_banner
fi
fi
echo "file '$o'" >> $TXT
done
cat "$TXT"
ffmpeg -f concat -safe 0 -i "$TXT" -i "input 3.mp3" -filter_complex "
[0:a][1:a] amix=inputs=2:duration=shortest
" -c:v copy -c:a aac out/output.mp4 -y -hide_banner
mpv out/output.mp4
it was simplified and edited part of script