Извлекаем аудио дорожку из видео файла в Linux

prolinux

Опубликован:  2024-04-01T11:24:43.693039Z
Отредактирован:  2024-04-01T11:24:43.693039Z
Статус:  публичный
11
0
0

Как извлечь аудио дорожку из видео файла в Linux? Многие пользователи компьютера не раз сталкивались с такой задачей. В этом выпуске блога я расскажу, как это сделать, и покажу пример решения этой задачи на базе компьютера с операционной системой с ядром Linux. Решать эту задачу я буду в Debian, но все показанные здесь действия и команды актуальны для любой операционной системы, любого вендора Linux - Arch, Debian, Fedora, Gentoo, Ubuntu - показанные примеры можно реализовать на любой из перечисленных систем.

Программа для решения задачи

Для работы с аудио и видео данными в операционных системах с ядром Linux есть программа ffmpeg - это очень эффективный и многофункциональный аудио видео фреймворк с интерфейсом командной строки и поддержкой очень широкого спектра аудио и видео форматов. В рамках этой демонстрации я покажу пример кодирования аудио данных с помощью этой великолепной программы на базе операционной системы Debian.

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

Установить программу ffmpeg в Debian подобных операционных системах можно посредством пакетного менеджера apt.

$ sudo apt install ffmpeg

Сразу после выполнения этой команды программа станет доступна для использования всем пользователям системы.

Разбираемся с тонкостями процесса

Приступая к решению задачи стоит ответить себе на следующие, имеющие значение вопросы:

  1. В каком формате исходный видео файл?

  2. Какую именно дорожку необходимо извлечь из исходного видео файла?

  3. Файл какого формат нужно получить на выходе?

От ответа на эти вопросы будут зависеть некоторые мелкие детали реализации задуманного процесса и состав используемой в конкретной команде ключей.

На сегодняшний день известно несколько форматов хранения видео данных. Все мы давно привыкли к таким форматам как AVI, MKV, MP4. Возможности ffmpeg и набор встроенных в него декодеров позволяют работать с любым из этих видео форматов, при этом программе достаточно указать имя исходного файла, его тип программа определит автоматически.

Исходный видео файл

В рамках этой демонстрации я покажу несколько примеров кодирования исходного файла в формате AVI - это достаточно распространённый в глобальной сети видео формат. Как отмечено выше, формат исходного файла может быть любым. В моём распоряжении есть файл с расширением .avi, вот как показывает его программа ls в терминале, внимание на снимок экрана.

CbydEG9CZf.png

Как видно на снимке экрана, в моей текущей директории лежит файл с именем matrix.avi, из этого файла я и буду извлекать одну из нескольких возможных аудио дорожку.

Идентифицируем извлекаемую дорожку в составе видео файла

Перечисленные выше видео форматы являются контейнерами. Файл такого формата может содержать несколько аудио и видео потоков. Соответственно, чтобы что-то из него извлечь, нужно определить, что именно будем извлекать. Список всех имеющихся внутри видео файла потоков я буду определять с помощью этой же программы - ffmpeg. Вот как выглядит команда:

$ ffmpeg -i matrix.avi 2>&1 >/dev/null | grep Stream

В этой команде с помощью ключа -i я указал имя исходного файла - matrix.avi. Для любого другого видео файла команда будет иметь аналогичный состав, но отличаться только именем исходного файла.

В результате выполнения этой команды ffmpeg выдаст в терминал вот такие данные:

  Stream #0:0: Video: mpeg4 (Advanced Simple Profile) (XVID / 0x44495658), yuv420p, 720x400 [SAR 1:1 DAR 9:5], 1826 kb/s, 23.98 fps, 23.98 tbr, 23.98 tbn
  Stream #0:1: Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, stereo, fltp, 224 kb/s
  Stream #0:2: Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, stereo, fltp, 224 kb/s

Простой анализ полученных данных показывает, что в исходном файле имеется один видео поток и два аудио потока. В рамках этой демонстрации я буду извлекать вторую аудио дорожку - она представлена последней строчкой показанного выхлопа. Обращаю внимание, что эта аудио дорожка исходного файла хранится в формате AC3. Программа показала для этой дорожки идентификатор 0:2, этим идентификатором я и буду пользоваться далее, при извлечении аудио данных.

Выбираем формат полученного аудио файла

Извлечь выбранную аудио дорожку можно двумя способами:

  1. Можно скопировать выбранную аудио дорожку с сохранением исходного формата;

  2. Можно извлечь выбранную аудио дорожку и преобразовать её в другой формат.

Сегодня известно достаточно много форматов для хранения аудио данных, можно перечислить некоторые, наиболее популярные из них: WAV, MP3, Vorbis, Opus, FLAC, AAC и так далее. С форматом полученного аудио файла нужно определиться заранее, от этого зависит состав команды ffmpeg для реализации процесса.

Копируем аудио дорожку в исходном формате

Интересующая меня аудио дорожка в исходном файле хранится в формате AC3, ffmpeg позволяет скопировать её один в один, не изменяя формат и параметры. Вот как будет выглядеть команда в этом случае.

$ ffmpeg -i matrix.avi -v quiet -stats -vn -map 0:2 -codec:a copy -map_metadata -1 eng.ac3

Копирование аудио потока осуществляется достаточно быстро, программа покажет прогресс, следует дождаться завершения процесса. В результате выполненной команды в текущей рабочей директории появится новый файл с именем eng.ac3 - это имя я указал в конце команды, это и есть извлечённая аудио дорожка. Вот что показывает мой терминал:

gr6X9L7sN1.png

Преобразование извлекаемой дорожки в формат WAV

WAV - это один из форматов хранения аудио данных. Из файла в формате WAV можно легко и просто получить файл любого другого аудио формата. Поскольку этот формат не предусматривает сжатия, такие файлы занимают достаточно много дискового пространства. С помощью ffmpeg можно получать файлы WAV. Команда извлечения в этом случае будет отличаться от предыдущего примера только ключом -codec:a, и вот как она будет выглядеть для нашего исходного файла:

$ ffmpeg -i matrix.avi -v quiet -stats -vn -map 0:2 -codec:a pcm_s16le -map_metadata -1 eng.wav

В этом случае процесс кодирования займёт немного больше времени, а в текущей рабочей директории после его завершения появится новый файл с именем eng.wav.

rhXaG1FOR8.png

Преобразование извлекаемой дорожки в формат MP3

MP3 - это самый популярный аудио формат, сегодня его поддерживает практически любое устройство, которое воспроизводит музыку и продаётся в магазинах. Программа ffmpeg умеет создавать файлы MP3. Команда извлечения в этом случае будет отличаться от предыдущих примеров ключом -codec:a и содержать дополнительные параметры кодирования, если нужно указать битрейт получаемого файла. Вот как она будет выглядеть для нашего исходного видео:

$ ffmpeg -i matrix.avi -v quiet -stats -vn -map 0:2 -codec:a mp3 -b:a 128k -map_metadata -1 eng.mp3

В данном случае я задал с помощью ключа -b:a битрейт получаемого файла - 128kbps. Если необходимо, можно указать любой другой битрейт из линейки поддерживаемых этим форматом значений: 128, 160, 192, 224, 256, 320. Чем выше битрейт, тем больше размер полученного файла. Процесс кодирования MP3 файла достаточно длительный, нужно запастись терпением и дождаться его завершения. В результате, в текущей рабочей директории появится новый файл с именем eng.mp3.

QRowoTffJ1.png

Кодирование внешним энкодером

Иногда при извлечении аудио дорожки бывает необходимо воспользоваться каким-либо внешним энкодером. Например, для получения формата MP3 можно воспользоваться программой lame, в этом случае можно более подробно описать опции кодирования, включая метаданные полученного файла. На этот случай в ffmpeg предусмотрена возможность отдавать полученный в результате декодирования исходного файла PCM поток по программному каналу любой другой программе, например lame, opusenc, oggenc и так далее. В случае с lame команда будет иметь следующий вид:

$ ffmpeg -i matrix.avi -v quiet -stats -vn -map 0:2 -codec:a pcm_s16le -map_metadata -1 -f wav - | lame --silent -V1 - variant.mp3

Здесь следует обратить внимание на вертикальную черту, которая разделяет две команды (ffmpeg и lame). Она обозначает программный канал. В этом случае программа ffmpeg читает данные из исходного файла, преобразует выбранную с помощью ключа -map аудио дорожку в формат PCM WAV и отдаёт полученные в результате такого кодирования данные по программному каналу программе lame, которая в свою очередь кодирует полученный поток в формат MP3 и создаёт файл с именем variant.mp3. С помощью lame опции кодирования можно задать более гибко, об этом мы поговорим в следующих выпусках этого блога.

В результате выполнения предложенной команды в текущей рабочей директории появится новый файл с именем variant.mp3. От полученного ранее файла eng.mp3 он будет отличаться характером (и величиной) битрейта и, соответственно, конечным размером.

SK9b3Q2ay7.png

Расшифровка некоторых использованных ключей ffmpeg

У каждого использованного в представленных в примерах выше командах ключа ffmpeg своё значение, давайте расшифруем некоторые из них.

  • -i filename - ключ задаёт имя входящего файла, этот файл должен существовать и располагаться в текущем рабочем каталоге;

  • -v quiet - ключ делает программу молчаливой и предотвращает вывод на терминал дополнительной вспомогательной информации;

  • -stats - с этим ключом ffmpeg выводит в терминал строчку, отображающую прогресс текущего процесса и некоторые его параметры;

  • -vn - ключ указывает, что видео поток кодировать не нужно, с ним будет обрабатываться только указанный аудио поток;

  • -map 0:2 - ключ указывает, какой именно поток исходного файла обрабатывать, заданные цифры можно определить из выхлопа первой в этой демонстрации команды ffmpeg;

  • -codec:a mp3 - ключ указывает формат получаемого на выходе файла;

  • -map_metadata -1 - ключ предотвращает запись метаданных исходного файла в полученный файл;

  • -f wav - ключ указывает формат выходного файла, необходим, если выходной поток отдаётся в программный канал, или, если у получаемого файла не указано расширение.

Как видно из продемонстрированных примеров, пользоваться ffmpeg достаточно несложно. Предложенные выше команды являются типовыми, изменяя в них имя исходного файла, идентификатор извлекаемого потока, используемый для кодирования энкодер, его параметры и имя файла назначения, можно извлечь любую аудио дорожку из любого видео файла, ffmpeg поддерживает поистине огромное количество форматов. Как говорят англичане, must have.