🖥️🔤 Транскрибация видео и создание субтитров с помощью Whisper, FFmpeg и Python

Следуя нашему пошаговому руководству, вы сможете автоматически транскрибировать аудио и добавлять субтитры к своим видео всего за несколько минут.

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

Необходимые инструменты: Python, Whisper, FFmpeg.

Настройка рабочего пространства

Создадим рабочую папку

mkdir open-ai-whisper-ffmpeg

Перейдем в папку проекта и создадим виртуальное окружение:

cd open-ai-whisper-ffmpeg
python3 -m venv .venv
source .venv/bin/activate

Установим необходимые пакеты для OpenAI Whisper:

pip install git+https://github.com/m-bain/whisperx.git
🐍 Библиотека питониста
Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека питониста»
🐍🎓 Библиотека собеса по Python
Подтянуть свои знания по Python вы можете на нашем телеграм-канале «Библиотека собеса по Python»
🐍🧩 Библиотека задач по Python
Интересные задачи по Python для практики можно найти на нашем телеграм-канале «Библиотека задач по Python»

Транскрибация видео

Сначала создадим новый файл Python – main.py.

touch main.py

И добавим в него код:

from datetime import timedelta
import os
import whisperx

def transcribe_video(input_video):
    batch_size = 32 
    compute_type = "float32"  
    device = "cpu"

    model = whisperx.load_model("large-v2", device=device, compute_type=compute_type)

    audio = whisperx.load_audio(input_video)
    result = model.transcribe(audio, batch_size=batch_size, language="en")

    model_a, metadata = whisperx.load_align_model(language_code=result["language"], device=device)
    result = whisperx.align(result["segments"], model_a, metadata, audio, device, return_char_alignments=False)

    segments = result["segments"]


   # if srt file exists, delete it
    if os.path.exists("subtitles.srt"):
        os.remove("subtitles.srt")
    for index, segment in enumerate(segments):
        startTime = str(0)+str(timedelta(seconds=int(segment['start'])))+',000'
        endTime = str(0)+str(timedelta(seconds=int(segment['end'])))+',000'
        text = segment['text']
        print(text)
        segment = f"{index + 1}\n{startTime} --> {endTime}\n{text[1:] if text[0] == ' ' else text}\n\n"

        srtFilename = os.path.join(f"subtitles.srt")
        with open(srtFilename, 'a', encoding='utf-8') as srtFile:
            srtFile.write(segment)

    return srtFilename



def main():
    input_video_path = "input.mp4"
    transcribe_video(input_video_path)

main()

Давайте рассмотрим, что мы делаем в приведенном выше коде. В этих строках мы импортируем необходимые пакеты для работы: whisperx для загрузки модели Whisper, os для получения пути к файлу субтитров и timedelta для форматирования текста временных меток.

from datetime import timedelta
import os
import whisperx

Здесь мы определили функцию, которая принимает входное видео, загружает модель Whisper large-v2, указывает тип вычислений и настраивает модель на использование CPU вместо GPU.

После этого функция загружает аудио в модель, затем транскрибирует и возвращает текст с временными метками.

def transcribe_video(input_video):
    batch_size = 32 
    compute_type = "float32"  
    device = "cpu"

    model = whisperx.load_model("large-v2", device=device, compute_type=compute_type)

    audio = whisperx.load_audio(input_video)
    result = model.transcribe(audio, batch_size=batch_size, language="en")

    model_a, metadata = whisperx.load_align_model(language_code=result["language"], device=device)
    result = whisperx.align(result["segments"], model_a, metadata, audio, device, return_char_alignments=False)

    segments = result["segments"]

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

   # if srt file exists, delete it
    if os.path.exists("subtitles.srt"):
        os.remove("subtitles.srt")
    for index, segment in enumerate(segments):
        startTime = str(0)+str(timedelta(seconds=int(segment['start'])))+',000'
        endTime = str(0)+str(timedelta(seconds=int(segment['end'])))+',000'
        text = segment['text']
        print(text)
        segment = f"{index + 1}\n{startTime} --> {endTime}\n{text[1:] if text[0] == ' ' else text}\n\n"

        srtFilename = os.path.join(f"subtitles.srt")
        with open(srtFilename, 'a', encoding='utf-8') as srtFile:
            srtFile.write(segment)

    return srtFilename

Добавление субтитров к видео

Далее мы загружаем subtitles.srt в видео с помощью FFmpeg. В итоге получаем следующий скрипт:

from datetime import timedelta
import os
import whisperx
import subprocess

def transcribe_video(input_video):
    batch_size = 32 
    compute_type = "float32"  
    device = "cpu"

    model = whisperx.load_model("large-v2", device=device, compute_type=compute_type)

    audio = whisperx.load_audio(input_video)
    result = model.transcribe(audio, batch_size=batch_size, language="en")

    model_a, metadata = whisperx.load_align_model(language_code=result["language"], device=device)
    result = whisperx.align(result["segments"], model_a, metadata, audio, device, return_char_alignments=False)

    segments = result["segments"]


   # if srt file exists, delete it
    if os.path.exists("subtitles.srt"):
        os.remove("subtitles.srt")
    for index, segment in enumerate(segments):
        startTime = str(0)+str(timedelta(seconds=int(segment['start'])))+',000'
        endTime = str(0)+str(timedelta(seconds=int(segment['end'])))+',000'
        text = segment['text']
        print(text)
        segment = f"{index + 1}\n{startTime} --> {endTime}\n{text[1:] if text[0] == ' ' else text}\n\n"

        srtFilename = os.path.join(f"subtitles.srt")
        with open(srtFilename, 'a', encoding='utf-8') as srtFile:
            srtFile.write(segment)

    return srtFilename

def add_srt_to_video(input_video, output_file):

    # FFmpeg command
    subtitles_file = 'subtitles.srt'

    # FFmpeg command
    ffmpeg_command = f"""ffmpeg -i {input_video} -vf "subtitles={subtitles_file}:force_style='FontName=Arial,FontSize=10,PrimaryColour=&HFFFFFF,OutlineColour=&H000000,BorderStyle=3,Outline=1,Shadow=1,Alignment=2,MarginV=10'" -c:a copy {output_file} -y """

    # Run the FFmpeg command
    subprocess.run(ffmpeg_command, shell=True)

<u>def main():</u>
 


    input_video_path = "input.mp4"
    output_file = "output.mp4"
    transcribe_video(input_video_path)
    add_srt_to_video(input_video_path, output_file)


main()

Результат

Транскрибация видео и создание субтитров с помощью Whisper, FFmpeg и Python

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

admin
11 декабря 2018

ООП на Python: концепции, принципы и примеры реализации

Программирование на Python допускает различные методологии, но в его основе...
admin
28 июня 2018

3 самых важных сферы применения Python: возможности языка

Существует множество областей применения Python, но в некоторых он особенно...
admin
13 февраля 2017

Программирование на Python: от новичка до профессионала

Пошаговая инструкция для всех, кто хочет изучить программирование на Python...