Время прочтения: 3 мин.

FFmpeg — набор свободных библиотек с открытым исходным кодом. Позволяет записывать, конвертировать и передавать цифровые аудио- и видеозаписи в различных форматах.

Зачем мне еще одна библиотека, если в Python и родных модулей достаточно?

FFmpeg позволяет делать с аудио ВСЁ. Например, во время реализации AI-проекта по распознаванию аудио, возникла необходимость предобработки. Основные frameworks по распознаванию речи deepspeach2, pocketsphinx работают только с аудио формата .wav 16kHz mono. Руководствуясь ранее изложенным принципом, мы не изобретаем велосипед, а используем готовый метод вызова из Python библиотеки FFmpeg.

Как это работает? Для запуска FFmpeg повторим способ, описанный нами в статье «Вызов скриптов и  библиотек на других языках», используя модуль subprocess и модуль os.

import subprocess, os

Запакуем все необходимые методы внутрь класса. Чтобы класс смог опознать ffmpeg* и ffprobe** пропишем пути до исполняемых файлов .exe.

class FFmpeg:
    cmds = '\\ffmpeg\\bin\\ffmpeg.exe' 
    cmds_probe = '\\ffmpeg\\bin\\ffprobe.exe' 

При создании экземпляра класса указывается путь, где лежат аудиофайлы (переменная mypath), и желаемая длительность аудиофайлов после нарезки (переменная cut_duration).

def __init__(self, mypath, cut_duration):
   self.mypath = mypath
   self.cut_duration = cut_duration

Любой аудиофайл можно преобразовать из одного формата в другой, передав команду FFmpeg в командную строку. Например, команда, приведенная ниже преобразует файл input формата mp3 в файл output формата wav 16kHz mono.

   ffmpeg -i input.mp3 -acodec pcm_s16le -ac 1 -ar 16000 output.wav

Обернем это с помощью функции subprocess.Popen (параметр функции file – это имя аудиофайла, который нужно обработать).

def mp3_wav(self, file):
        if file.endswith('mp3'):
            output = file[:-4] + ".wav"
            p = self.Popen(FFmpeg.cmds+" -i "+file+" -acodec pcm_s16le -ac 1 -ar 16000 "+output)
            p.communicate()
            os.remove(file)
            return output
        else:
            return file

А как распознать свойства аудиофайла, например, длительность?

За получение свойств файла отвечает утилита ffprobe, но она выдает сразу все свойства. Чтобы получить именно длительность, через командную строку запускаем следующую команду, и на выходе получаем значение показателя в секундах для аудиофайла с именем input.mp3.

ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp3

Как и ранее обернем эту команду с помощью subprocess.Popen.

def duration(self, file):
   p = self.Popen(FFmpeg.cmds_probe+" -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 " + file)
   output, _ = p.communicate()
   return output.decode('ascii')[:-4]

Аналогично можно обернуть любую команду FFmpeg, а именно, получить класс, который будет использовать любые необходимые команды библиотек FFmpeg для обработки аудио или видео. Похожим способом мы пользовались для реализации AI-проекта по распознаванию аудио, и у нас всё получилось.

* ffmpeg — утилита командной строки для конвертирования видеофайла из одного формата в другой. С её помощью можно также захватывать видео в реальном времени с TV-карты.

** ffprobe — консольная утилита, позволяющая собирать и отображать информацию о медиафайлах (как MediaInfo) и мультимедиа потоках, доступных устройствах, кодеках, форматах, протоколах и др.