ffmpeg объединяет два источника с дополнительным аудио - PullRequest
0 голосов
/ 09 февраля 2020

Я хочу объединить два видеофайла вместе с помощью ffmpeg. Я уже нашел эту команду:

ffmpeg -i INPUT1 -i INPUT2 -filter_complex \"[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[v][a]\" -map \"[v]\" -map \"[a]\" OUTPUT

Проблема в том, что INPUT2 не всегда имеет аудио, поэтому ffmpeg генерирует неверный поток ввода. Я очень неопытен с ffmpeg и не разбираюсь в документации. Есть ли возможный способ, который достаточно понятен, возможно, в одной команде?

Подведены итоги: я хочу объединить два видеофайла, включая аудио, но второй файл может иметь или не иметь аудио слой.

Ответы [ 2 ]

0 голосов
/ 02 марта 2020

Должно совпадать с числом и типом потока

Все сегменты, которые должны быть объединены, должны иметь одинаковое количество и тип потоков. Поэтому, если input1.mp4 имеет звук, а input2.mp4 - нет, то вам нужно либо пропустить звук из input1.mp4, либо добавить звук для input2.mp4. Один из способов - добавить тихий звук с фильтром anullsr c, как показано в:

Обнаружение звука

Невозможно автоматически добавить отсутствующий звук, поэтому вы должны проверить входы с помощью ffprobe, чтобы сказать, есть ли на входах звук или нет:

Затем можно использовать приводит к вашему предпочтительному языку сценариев / кодирования для выполнения соответствующей команды.

0 голосов
/ 14 февраля 2020

Простой подход к видео, в котором нет звука, заключается в добавлении звука (нулевой источник звука):

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 действия:

  1. Обнаружение отсутствия звука

    • Определение видео без звука

    • Добавить нулевое аудио к этим видео

  2. строка аргументов ffmpeg вместе

    • Добавить каждое видео как вход ffmpeg

    • Разверните ffmpegs filter_complex для каждого нового входа

Вы можете поставить свой файлы в папку, добавьте номера перед их именем файла, чтобы определить порядок объединения. Не используйте пробелы в именах файлов!"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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...