Рубрики
Без рубрики

Как транскрибировать речевые записи в текст с помощью Python

Когда у вас есть запись, где говорят один или несколько человек, полезно иметь очень точную … Tagged с Python, транскрипцией.

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

В этом уроке мы будем использовать интерфейс программирования веб-приложений с высокой точностью до текста под названием Assemblyai для извлечения текста из записи MP3 (также поддерживаются многие другие форматы).

Учебные требования

На протяжении всего урока мы собираемся использовать следующие зависимости, которые мы установим через мгновение. Убедитесь, что у вас также есть Python 3, предпочтительно 3.6 или более новые, в вашей среде:

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

Запрос версии 2.24.0 Чтобы сделать HTTP -запросы в Assemblyai API речи к тексту А Ассамблея-аи Учетная запись, которую вы можете зарегистрировать бесплатный ключ доступа API здесь Весь код в этом сообщении в блоге доступен с открытым исходным кодом по лицензии MIT на GitHub в рамках каталога Transcribe-Speech-Text-Script репозитория блога-кода. Используйте исходный код по мере желания своих собственных проектов.

Настройка среды разработки

Измените в каталог, где вы сохраняете виртуальные среды Python. Я держу свою в подкаталоге с именем Ванвов в домашнем каталоге моего пользователя. Создайте новый VirtualEnv для этого проекта, используя следующую команду.

python3 -m venv ~/venvs/pytranscribe

Активируйте VirtualEnv с помощью скрипта Activate Shell:

Источник ~/venvs/pytranscribe/bin/activate

После выполнения вышеупомянутой команды командная строка изменится так, чтобы имя VirtualENV было приготовлено к исходному формату командной строки, поэтому, если ваша подсказка просто $, теперь она будет выглядеть следующим образом:

(pytranscribe) $ Помните, что вы должны активировать свой VirtualENV в каждом новом окне терминала, где вы хотите использовать зависимости в VirtualENV.

Теперь мы можем установить пакет запросов в активированный, но в остальном пустой VirtualEnv.

PIP установка.24.0

Ищите вывод, аналогичный следующему, чтобы подтвердить, что соответствующие пакеты были правильно установлены из PYPI.

(pytranscribe) $ pip install requests==2.24.0
Collecting requests==2.24.0
  Using cached https://files.pythonhosted.org/packages/45/1e/0c169c6a5381e241ba7404532c16a21d86ab872c9bed8bdcd4c423954103/requests-2.24.0-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests==2.24.0)
  Using cached https://files.pythonhosted.org/packages/5e/c4/6c4fe722df5343c33226f0b4e0bb042e4dc13483228b4718baf286f86d87/certifi-2020.6.20-py2.py3-none-any.whl
Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 (from requests==2.24.0)
  Using cached https://files.pythonhosted.org/packages/9f/f0/a391d1463ebb1b233795cabfc0ef38d3db4442339de68f847026199e69d7/urllib3-1.25.10-py2.py3-none-any.whl
Collecting chardet<4,>=3.0.2 (from requests==2.24.0)
  Using cached https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl
Collecting idna<3,>=2.5 (from requests==2.24.0)
  Using cached https://files.pythonhosted.org/packages/a2/38/928ddce2273eaa564f6f50de919327bf3a00f091b5baba8dfa9460f3a8a8/idna-2.10-py2.py3-none-any.whl
Installing collected packages: certifi, urllib3, chardet, idna, requests
Successfully installed certifi-2020.6.20 chardet-3.0.4 idna-2.10 requests-2.24.0 urllib3-1.25.10

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

Загрузка, инициирование и транскрибирование звука

У нас есть все, что нам нужно, чтобы начать создавать наше приложение, которое будет транскрибировать аудио в текст. Мы собираемся создать это приложение в трех файлах:

upload_audio_file.py : Загружает ваш аудиофайл в безопасное место в сервисе Assemblyai, чтобы его можно было получить для обработки. Если ваш аудиофайл уже доступен с публичным URL, вам не нужно делать этот шаг, вы можете просто следить за этим QuickStart initiate_transcription.py : сообщает API, какие файлы транскрибируются и начинают немедленно get_transcription.py : печатает состояние транскрипции, если она все еще обрабатывает, или отображает результаты транскрипции, когда процесс завершен Создайте новый каталог с именем Pytranscribe для хранения этих файлов во время их записи. Затем переодеться в новый каталог проектов.

Mkdir pytranscribe CD Pytranscribe

Нам также необходимо экспортировать наш ключ API AssblyAI в качестве переменной среды. Подпишитесь на учетную запись AssemblyAI и войдите в панель панели AssemblyAI, затем скопируйте «ваш токен API»

Экспорт-Апи-Кей-Хер

Обратите внимание, что вы должны использовать команду Export в каждом окне командной строки, которое вы хотите, чтобы этот ключ был доступен. Сценарии, которые мы пишем, не смогут получить доступ к API, если у вас нет токена, экспортируемого как AssemblyAI_KEY в среде, в которой вы используете сценарий.

Теперь, когда у нас создан наш каталог проекта и набор клавиш API в качестве переменной среды, давайте перейдем к написанию кода для первого файла, который будет загружать аудиофайлы в службу Assemblyai.

Загрузка аудиофайла для транскрипции

Создайте новый файл с именем upload_audio_file.py и поместите в него следующий код:

import argparse
import os
import requests


API_URL = "https://api.assemblyai.com/v2/"


def upload_file_to_api(filename):
    """Checks for a valid file and then uploads it to AssemblyAI
    so it can be saved to a secure URL that only that service can access.
    When the upload is complete we can then initiate the transcription
    API call.
    Returns the API JSON if successful, or None if file does not exist.
    """
    if not os.path.exists(filename):
        return None

    def read_file(filename, chunk_size=5242880):
        with open(filename, 'rb') as _file:
            while True:
                data = _file.read(chunk_size)
                if not data:
                    break
                yield data

    headers = {"authorization": os.getenv("ASSEMBLYAI_KEY")}
    response = requests.post("".join([API_URL, "upload"]), headers=headers,
                             data=read_file(filename))
    return response.json()

Приведенный выше код импортирует пакеты Argparse, OS и запросов, чтобы мы могли использовать их в этом сценарии. API_URL – это постоянная, которая имеет базовый URL -адрес службы AssemblyAI. Мы определяем функцию upload_file_to_api с одним аргументом, именем файла, которая должна быть строкой с абсолютным путем к файлу и его имени файла.

В рамках функции мы проверяем, что файл существует, затем используем кодирование передачи запроса для потоковой передачи больших файлов в API AssemblyAI.

Функция getEnv модуля ОС считывает API, который был установлен в командной строке, используя команду Export с Getenv. Убедитесь, что вы используете эту команду экспорта в терминале, где вы запускаете этот сценарий, иначе это значение assblyai_key будет пустым. В случае сомнений, используйте Echo $ Assembly_AI, чтобы увидеть, соответствует ли значение вашим ключам API.

Чтобы использовать функцию opload_file_to_api, добавьте следующие строки кода в файл upload_audio_file.py, чтобы мы могли правильно выполнить этот код в виде скрипта, вызванного командой Python:

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("filename")
    args = parser.parse_args()
    upload_filename = args.filename
    response_json = upload_file_to_api(upload_filename)
    if not response_json:
        print("file does not exist")
    else:
        print("File uploaded to URL: {}".format(response_json['upload_url']))

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

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

Выполните заполненный скрипт upload_audio_file.py, запустив его в командной строке с командой Python. Замените full_path_to_file на абсолютный путь к файлу, который вы хотите загрузить, например, как/сец/matt/devel/audio.mp3.

python upload_audio_file.py full_path_to_file

Предполагая, что файл найден в указанном вами месте, когда сценарий заканчивает загрузку файла, он будет распечатать сообщение, подобное этому с уникальным URL:

Файл загружен в URL: https://cdn.assemblyai.com/upload/463ce27f-0922-4ea9-9ce4-3353d84b5638 Этот URL не является общедоступным, он может использоваться только Сервисом AssemblyAI, поэтому никто другой не сможет получить доступ к вашему файлу и его содержимому, за исключением вас и их API транскрипции.

Часть, которая важна, является последним разделом URL, в этом примере она составляет 463CE27F-0922-4EA9-9CE4-3353D84B5638. Сохраните этот уникальный идентификатор, потому что нам нужно передать его в следующий сценарий, который инициирует службу транскрипции.

Инициировать транскрипцию

Далее мы напишем немного кода, чтобы начать транскрипцию. Создайте новый файл с именем initiate_transcription.py. Добавьте следующий код в новый файл.

import argparse
import os
import requests


API_URL = "https://api.assemblyai.com/v2/"
CDN_URL = "https://cdn.assemblyai.com/"


def initiate_transcription(file_id):
    """Sends a request to the API to transcribe a specific
    file that was previously uploaded to the API. This will
    not immediately return the transcription because it takes
    a moment for the service to analyze and perform the
    transcription, so there is a different function to retrieve
    the results.
    """
    endpoint = "".join([API_URL, "transcript"])
    json = {"audio_url": "".join([CDN_URL, "upload/{}".format(file_id)])}
    headers = {
        "authorization": os.getenv("ASSEMBLYAI_KEY"),
        "content-type": "application/json"
    }
    response = requests.post(endpoint, json=json, headers=headers)
    return response.json()

У нас есть тот же импорт, что и в предыдущем сценарии, и мы добавили новую постоянную, CDN_URL, которая соответствует отдельному URL -адресу, где AssemblyAI хранит загруженные аудиофайлы.

Функция initiate_transcription, по сути, просто устанавливает один HTTP -запрос на API AssemblyAI, чтобы запустить процесс транскрипции на аудиофайле при конкретном URL -адресе. Вот почему передача в File_ID очень важно: завершает URL -адрес аудиофайла, который мы говорим Assemblyai для получения.

Завершите файл, добавив этот код, чтобы его можно было легко вызвать из командной строки с аргументами.

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("file_id")
    args = parser.parse_args()
    file_id = args.file_id
    response_json = initiate_transcription(file_id)
    print(response_json)

Запустите скрипт, запустив команду Python в файле initiate_transcription и передайте уникальный идентификатор файла, который вы сохранили с предыдущего шага.

# the FILE_IDENTIFIER is returned in the previous step and will
# look something like this: 463ce27f-0922-4ea9-9ce4-3353d84b5638
python initiate_transcription.py FILE_IDENTIFIER

API отправит ответ JSON, который этот скрипт печатает в командную строку.

{'audio_end_at': None, 'acoustic_model': 'assemblyai_default', 'text': None, 
 'audio_url': 'https://cdn.assemblyai.com/upload/463ce27f-0922-4ea9-9ce4-3353d84b5638', 
 'speed_boost': False, 'language_model': 'assemblyai_default', 'redact_pii': False, 
 'confidence': None, 'webhook_status_code': None, 
 'id': 'gkuu2krb1-8c7f-4fe3-bb69-6b14a2cac067', 'status': 'queued', 'boost_param': None, 
 'words': None, 'format_text': True, 'webhook_url': None, 'punctuate': True, 
 'utterances': None, 'audio_duration': None, 'auto_highlights': False, 
 'word_boost': [], 'dual_channel': None, 'audio_start_from': None}

Обратите внимание на значение ключа ID в ответе JSON. Это идентификатор транскрипции, который мы должны использовать для получения результата транскрипции. В этом примере это «GKUU2KRB1-8C7F-4FE3-BB69-6B14A2CAC067». Скопируйте идентификатор транскрипции в своем собственном ответе, потому что он нам понадобится, чтобы проверить, когда процесс транскрипции завершился на следующем шаге.

Получение результата транскрипции

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

Сколько времени потребуется, чтобы вернуть результаты, может зависеть от размера файла, поэтому этот следующий скрипт отправит HTTP -запрос в API и сообщает о состоянии транскрипции или распечатайте вывод, если он завершен.

Создайте третий файл Python с именем get_transcription.py и поместите в него следующий код.

import argparse
import os
import requests


API_URL = "https://api.assemblyai.com/v2/"


def get_transcription(transcription_id):
    """Requests the transcription from the API and returns the JSON
    response."""
    endpoint = "".join([API_URL, "transcript/{}".format(transcription_id)])
    headers = {"authorization": os.getenv('ASSEMBLYAI_KEY')}
    response = requests.get(endpoint, headers=headers)
    return response.json()


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("transcription_id")
    args = parser.parse_args()
    transcription_id = args.transcription_id
    response_json = get_transcription(transcription_id)
    if response_json['status'] == "completed":
        for word in response_json['words']:
            print(word['text'], end=" ")
    else:
        print("current status of transcription request: {}".format(
              response_json['status']))

Приведенный выше код имеет тот же импорт, что и другие сценарии. В этой новой функции GET_TRANSCREPT мы просто называем API AssemblyAI с помощью нашего ключа API и идентификатора транскрипции с предыдущего шага (не идентификатор файла). Мы получаем ответ JSON и возвращаем его.

В основной функции мы обрабатываем идентификатор транскрипции, который передается как аргумент командной строки, и передаем его в функцию GET_TRANSCREPT. Если ответ JSON из функции GET_TRANSCREPTION содержит завершенное состояние, мы печатаем результаты транскрипции. В противном случае распечатайте текущее состояние, которое либо в очереди, либо обработка до его завершения.

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

python get_transcription.py transcription_id

Если служба еще не начала работать над стенограммой, то она вернет в очередь так:

Текущее состояние запроса транскрипции: в очереди

Когда служба в настоящее время работает над аудиофайлом, она вернет обработку:

Текущее состояние запроса транскрипции: обработка

Когда процесс будет завершен, наш скрипт вернет текст транскрипции, как вы видите здесь:

An object-relational mapper is a code library that automates the transfer of 
data stored in relational, databases into objects that are more commonly used
in application code or EMS are useful because they provide a high level 

...(output abbreviated)

Вот и все, у нас есть транскрипция!

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

Оригинал: “https://dev.to/saketsarin/how-to-transcribe-speech-recordings-into-text-with-python-137g”