Удалить аудио из видео файла с помощью FFmpeg

Как удалить звуковую дорожку из видеофайла с помощью FFmpeg?

6 ответов

Решение

Вы удаляете аудио с помощью -an флаг.

ffmpeg -i example.mkv -c copy -an example-nosound.mkv

Полная документация по ffmpeg здесь.

Вы, вероятно, не хотите перекодировать видео (медленный процесс с потерями), поэтому попробуйте:

ffmpeg -i [input_file] -vcodec copy -an [output_file]

(nb некоторые дистрибутивы Linux теперь поставляются с веткой avconv ffmpeg)

avconv -i [input_file] -vcodec copy -an [output_file]

Если вы не можете установить ffmpeg из-за существования avconv Попробуй это.

Я собрал короткий фрагмент кода, который автоматизирует процесс удаления звука из видеофайлов для всего каталога, содержащего видеофайлы:

FILES=/{videos_dir}/*
output_dir=/{no_audio_dir}
for input_file in $FILES
do
  file_name=$(basename $input_file)
  output_file="$output_dir/$file_name"
  ffmpeg -i $input_file -c copy -an $output_file
done

Надеюсь, это поможет!

Вы также можете использовать-mapвариантffmpegчтобы лучше контролировать, что именно будет помещено в конечный видеоконтейнер.

Допустим, например, что ваш видеофайлmy_video.mp4составляется так:

      Input #0
  Stream #0:0 Video: h264
  Stream #0:1 Audio: English
  Stream #0:2 Audio: German
  Stream #0:3 Audio: Japanese
  Stream #0:4 Audio: Spanish
  Stream #0:5 Audio: Italian

Чтобы удалить все аудиодорожки (например, -anвариант делает):

      ffmpeg -i my_video.mp4 -map 0 -map -0:a -c copy my_video.noaudio.mp4`

-map 0 захватывает весь ввод (видео, аудио, субтитры, метаданные, главы и т. д.).
удаляет все звуковые дорожки из ввода 0 ( обратите внимание на знак).
-c copyкопирует как есть без перекодирования.

Чтобы удалить японский и испанский треки:< /а>

      ffmpeg -i my_video.mp4 -map 0 -map -0:3 -map -0:4 -c copy my_video.nojap.noesp.mp4`

-map -0:3удаляет третий трек со входа 0, который представляет собой японский звук.
-map -0:4удаляет 4-ю дорожку со входа 0, которая представляет собой испанский звук.

Чтобы удалить все звуковые дорожки, кроме итальянского:

      ffmpeg -i my_video.mp4 -map 0 -map -0:a -map 0:5 -c copy my_video.ita.mp4`

-map -0:aудаляет все звуковые дорожки со входа 0.
-map 0:5вставляет 5-ю дорожку со входа 0, которая представляет собой итальянский звук (обратите внимание на НЕТ).-в этом случае подпишитесь).


Это также очень полезно при работе с несколькими файлами.
Например, когда:

  • захват звука из одного файла
  • аудиодорожки из другого
  • субтитры и метаданные из третьего

Я взял ответ @apolak и превратил его в рекурсивный цикл для всех папок под входной папкой. Он сохранит структуру каталога входной папки, и вы можете установить максимальную глубину для его рекурсии. Выходной каталог не должен быть дочерним по отношению к входному каталогу, иначе произойдет ошибка, чтобы остановить случайную бесконечную рекурсию. Также должно быть нормально с пробелами в именах файлов и путях.

ПРИМЕЧАНИЕ. Будут предприняты попытки обработки всех файлов во входном каталоге, поэтому убедитесь, что все они являются видеофайлами.

      #!/bin/bash

process_files() {
    local current_dir="$1"
    local output_dir="$2"
    local max_depth="$3"
    local depth="${4:-0}" # Set default value of 0 if $4 is not set
    if [ "$depth" -gt "$max_depth" ]; then
        return
    fi
    # Check if output directory is a subdirectory of the input directory and error
    # This should stop accidental recursive loops
    if [[ "$output_dir" == "$current_dir"* ]]; then
        echo "Error: Output directory is a subdirectory of the input directory"
        exit 1
    fi
    mkdir -p "$output_dir"
    for input_file in "$current_dir"/*
    do
        if [ -d "$input_file" ]; then
            # If the input file is a directory, recurse into it
            process_files "$input_file" "$output_dir/$(basename "$input_file")" "$max_depth" "$((depth+1))"
        elif [ -f "$input_file" ]; then
            # If the input file is a regular file, process it
            local file_name=$(basename "$input_file")
            local output_file="$output_dir/$file_name"
            ffmpeg -i "$input_file" -c copy -an "$output_file"
        fi
    done
}

# Call function with input and output directories and maximum depth
process_files "/Volumes/Storage/ORIGINAL" "/Volumes/Storage/MUTED" 2 # Set the maximum recursion depth to 2
Другие вопросы по тегам