-1

I have a grouping of files in a videos.txt file:

file 'title.mp4'
file 'welcome.mp4'
file 'introductions_slide.mp4'
file 'introductions.mp4'
file 'presentation_part_1_slide.mp4'
file 'presentation_part_1.mp4'
file 'presentation_part_2_slide.mp4'
file 'presentation_part_2a.mp4'
file 'presentation_part_2b.mp4'
file 'questions_and_answers_slide.mp4'
file 'questions_and_answers.mp4'

Some of these files (title.mp4, introductions_slide.mp4, presentation_part_1_slide.mp4, presentation_part_2_slide.mp4 and questions_and_answers_slide.mp4) are generated from PowerPoint's export to MP4 files and do not contain an audio stream.

I tried to follow this thread to add an audio stream to title.mp4, but when I then run the concat command, it's full of errors in the input stream. The resulting file is a silent one with no audio stream.

I know it's possible to merge a mixed silent-noise audio video files together because I was able ot achieve it in QuickTime. However, I am trying to figure out how to do it using ffmpeg.

Here's my current concat command:

ffmpeg -f concat -i videos.txt -c:v copy -c:a copy output.mp4

How can I run concat so that it will include the audio where audio is present, but maintain silence where it isn't?

Patrick Vellia
  • 399
  • 2
  • 9
  • What if you try to add silence audio like this : `ffmpeg -i input.mp4 -filter_complex "aevalsrc='0|0':d=1.0:c=stereo[silence]" -map [silence] -map v output.mp4` This should add one second of silence so that the concat demuxer works properly (if your video is shorter than one sec, modify d=1.0 to match the desired duration) – Rems Feb 23 '23 at 08:26

1 Answers1

0

script, if videos has same parameters, but not audio:

#!/bin/bash
#LST=($(ls -1tr *.mp4))
LST=("input 1.mp4" "only_video.mp4" "1280x720x30_2.mp4")
f="${LST[0]}"
mkdir out
o="out/${f%.*}.mkv"
CN0=$(ffprobe -v 0 -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
TXT=list.txt
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"
  CN1=$(ffprobe -v 0 -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
  if [ "$CN1" = "" ]; then
    ffmpeg -i "$f" -f lavfi -i anullsrc -c:v copy -c:a $CN0 -q:a 5 -shortest "$o" -y -hide_banner
  else
    if [ "$CN1" = "$CN0" ]; then
      ffmpeg -i "$f" -c copy "$o" -y -hide_banner
    else
      ffmpeg -i "$f" -c:v copy -c:a $CN0 -q:a 5 -shortest "$o" -y -hide_banner
    fi
  fi
  echo "file '$o'" >> $TXT
done

cat "$TXT"
ffmpeg -f concat -safe 0 -i "$TXT" -c copy output.mkv -y -hide_banner
xdg-open output.mkv