Простой подход к видео, в котором нет звука, заключается в добавлении звука (нулевой источник звука):
ffmpeg -f lavfi \
-i anullsrc=channel_layout=stereo:sample_rate=44100 \
-i "videoWithoutAudio.mp4" \
-shortest -c:v copy -c:a aac "videoWithAudio.mp4"
Если вы хотите go, далее мой сценарий оболочки, который
- объединяет несколько видеофайлов
- различного размера, формата изображения и формата, а
- добавляет тихое аудио к видео без звука
Установить целевой размер
targetWidth=1920
targetHeight=1080
создать масштабное выражение, которое масштабируется при необходимости в зависимости от источника
slhck придумали это удивительное масштабное выражение для ffmpeg. Независимо от того, какой у вас размер или соотношение сторон, это выражение масштабируется и подставляется по мере необходимости.
smartScale="scale=iw*min($targetWidth/iw\,$targetHeight/ih):ih*min($targetWidth/iw\,$targetHeight/ih), pad=$targetWidth:$targetHeight:($targetWidth-iw*min($targetWidth/iw\,$targetHeight/ih))/2:($targetHeight-ih*min($targetWidth/iw\,$targetHeight/ih))/2:color=black, setdar=ratio=16/9, setfield=tff"
Создайте счетчик и установите переменные
c=0
ffmpegInput=""
filter_complex_params_1=""
filter_complex_params_2=""
Go для каждого видео и выполните 2 действия:
Обнаружение отсутствия звука
строка аргументов ffmpeg вместе
Вы можете поставить свой файлы в папку, добавьте номера перед их именем файла, чтобы определить порядок объединения. Не используйте пробелы в именах файлов!"01_SummerVacation_2020.mkv
"
for i in *
do
# Use file command to recognize the type of data contained in a file
bashFileCommand=$(file "$i")
# parts of the file command output for many files that are not a video
regexPattern="image|Image|IMAGE|bitmap|text|Text|TEXT|ocument|DOCUMENT|Microsoft|rchive|empty|directory"
# detect if file is a video or not
# if the file contains no string of the above regexPattern it is likely a video
if [[ ! $bashFileCommand =~ $regexPattern ]]; then
# Concatenation works only if all videos contain audio
# detect videos without audio using ffprobe
# store command arguments for ffprobe query in array: codec_type for audio
command_audioCodec_type=(ffprobe -v quiet -select_streams a:0 -show_entries stream=codec_type -of default=nw=1:nk=1 "$i")
# execute command in array and store result variables
result_audioCodec_type=$("${command_audioCodec_type[@]}" | tail -1)
if [[ ! $result_audioCodec_type =~ "audio" ]]; then
# Add dummy audio to video
# Since we cannot overwrite the source file we have to create a temporary file
# ffmpeg chooses the right format according to the extension. Therefore we add "tmp" in front of the filename. Otherwise we would mess up the extension.
ffmpeg -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -i "$i" \
-shortest -c:v copy -c:a aac "tmp_${i}"
# remove original
rm "${i}"
# renaming new file to appear as the original
mv "tmp_${i}" "${i}"
fi
# iterate over all videos (e.g. 3) and add the parameters to the previous parameters:
# Scale videos to set size
# 1st iteration: [0:v]${smartScale}[scaled_v0];
# 2nd iteration: [0:v]${smartScale}[scaled_v0];[1:v]${smartScale}[scaled_v1];
# 3rd iteration: [0:v]${smartScale}[scaled_v0];[1:v]${smartScale}[scaled_v1];[3:v]${smartScale}[scaled_v2];
filter_complex_params_1="$filter_complex_params_1[${c}:v]${smartScale}[scaled_v${c}]; "
# Scale videos to set size
# 1st iteration: [scaled_v0][0:a]
# 2nd iteration: [scaled_v0][0:a][scaled_v1][1:a]
# 3rd iteration: [scaled_v0][0:a][scaled_v1][1:a][scaled_v2][2:a]
filter_complex_params_2="$filter_complex_params_2[scaled_v${c}][${c}:a]"
# Add inputs
# 1st iteration: -i video1.mp4
# 2nd iteration: -i video1.mp4 -i video2.mp4
# 3rd iteration: -i video1.mp4 -i video2.mp4 -i video3.mp4
ffmpegInput="$ffmpegInput -i ${i}"
# increment counter for filter
c=$((c+1))
fi
done
создайте фильтр concat
# 3rd (last) iteration: concat=n=3:v=1:a=1[v][a]
filter_complex_params_3="concat=n=${c}:v=1:a=1[v][a]"
Объедините все переменные в последняя команда ffmpeg
# concatenate videos
ffmpeg ${ffmpegInput} -filter_complex "${filter_complex_params_1}${filter_complex_params_2}${filter_complex_params_3}" -map "[v]" -map "[a]" -c:v libx264 -crf 23 -c:a aac concatenated.mkv