Когда у вас есть запись, на которой говорят один или несколько человек, это полезно чтобы иметь высокоточный и автоматизированный способ извлечения произнесенных слов в текст. Получив текст, вы можете использовать его для дальнейшего анализа или как функция доступности.
В этом руководстве мы будем использовать веб-приложение для преобразования речи в текст с высокой точностью. интерфейс программирования под названием AssemblyAI для извлекать текст из записи MP3 (также поддерживаются многие другие форматы).
С помощью кода из этого руководства вы сможете получить аудиофайл что содержит речь например, этот пример, который я записал и выведите очень точную транскрипцию текста, например:
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 abstraction upon a relational database that allows developers to write Python code instead of sequel to create read update and delete, data and schemas in their database. Developers can use the programming language. They are comfortable with to work with a database instead of writing SQL... (the text goes on from here but I abbreviated it at this point)
Требования к руководству
В этом руководстве мы будем использовать следующие зависимости: который мы установим буквально через мгновение. Убедитесь, что у вас также установлен Python 3, желательно установить 3.6 или новее , в вашей среде:
Мы будем использовать следующие зависимости, чтобы завершить это руководство:
- запросы
- версии 2.24.0 для выполнения HTTP-запросов к
- преобразование речи в текст AssemblyAI
- API
- Учетная запись AssemblyAI ,
- который вы можете подписаться на
- бесплатный ключ доступа к API здесь
Весь код в этом сообщении в блоге доступен с открытым исходным кодом по лицензии MIT. на GitHub в разделе каталог transcribe-speech-text-script репозитория blog-code-examples . Используйте исходный код по своему усмотрению для своих собственных проектов.
Настройка среды разработки
Перейдите в каталог, в котором вы храните свой Python виртуальные среды. Я храню свой в подкаталоге с именем venvs
в доме моего пользователя каталог. Создайте новый virtualenv для этого проекта, используя следующие команда.
python3 -m venv ~/venvs/pytranscribe
Активируйте virtualenv с помощью сценария оболочки activate
:
source ~/venvs/pytranscribe/bin/activate
После выполнения указанной выше команды в командной строке появится измените так, чтобы имя virtualenv добавлялось к исходный формат командной строки, поэтому, если ваша подсказка просто $
, теперь он будет выглядеть следующим образом:
(pytranscribe) $
Помните, что вы должны активировать виртуальный сервер в каждом новом терминале. окно, в котором вы хотите использовать зависимости в файле virtualenv.
Теперь мы можем установить пакет requests
в активированный но в остальном пустой virtualenv.
pip install requests==2.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
У нас установлены все необходимые зависимости, поэтому мы можем начать кодирование приложения.
Загрузка, инициализация и расшифровка аудио
У нас есть все необходимое для создания нашего приложения, которое преобразует аудио в текст. Мы собираемся построить это приложение в трех файлах:
Создайте новый каталог с именем pytranscribe
для хранения этих файлов как мы их пишем. Затем перейдите в новый каталог проекта.
mkdir pytranscibe cd pytranscribe
Нам также необходимо экспортировать наш ключ API AssemblyAI в качестве переменной среды. Зарегистрируйте учетную запись AssemblyAI и войдите в панель управления AssemblyAI , затем скопируйте «Ваш токен API», как показано на этом снимке экрана:
export ASSEMBLYAI_KEY=your-api-key-here
Обратите внимание, что вы должны использовать команду 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
и requests
. так что мы можем использовать их в этом скрипте. API_URL
– это постоянная с базовым URL-адресом службы AssemblyAI. Мы определяем upload_file_to_api
функция с одним аргументом, filename
это должна быть строка с абсолютным путем к файлу и его имя файла.
Внутри функции мы проверяем, существует ли файл, затем используем Request фрагментированное кодирование передачи для потоковой передачи больших файлов в AssemblyAI API.
Функция getenv
модуля os
считывает API, установленный на в командной строке с помощью команды export
с getenv
. Убедись что вы используете эту команду export
в терминале, где вы находитесь запускаем этот скрипт, иначе значение ASSEMBLYAI_KEY
будет пустой. В случае сомнений используйте echo $ ASSEMBLY_AI
, чтобы проверить, соответствует вашему ключу API.
Чтобы использовать функцию upload_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']))
Приведенный выше код создает объект ArgumentParser
, который позволяет приложение для получения единственного аргумента из командной строки чтобы указать файл, к которому мы хотим получить доступ, прочитать и загрузить в AssmeblyAI сервис.
Если файл не существует, сценарий выведет сообщение, которое файл не может быть найден. На счастливом пути, где мы находим правильный файл по этому пути, затем файл загружается с использованием код в функции upload_file_to_api
.
Выполните завершенный скрипт upload_audio_file.py
, запустив его на в командной строке с помощью команды python
. Заменить FULL_PATH_TO_FILE
с абсолютным путем к файлу, который вы хотите загрузить, например /Users/matt/devel/audio.mp3
.
python upload_audio_file.py FULL_PATH_TO_FILE
Предполагая, что файл найден в указанном вами месте, когда скрипт завершит загрузку файла, он распечатает сообщение, подобное этому с уникальным URL:
File uploaded to 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-запрос к AssemblyAI API для запуска транскрипции обработать аудиофайл по указанному 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_transcription
, мы просто вызываем AssemblyAI API с нашим ключом API и идентификатором транскрипции из предыдущего шаг (не идентификатор файла). Мы получаем ответ JSON и верни это.
В основной функции мы обрабатываем идентификатор транскрипции, который передается как аргумент командной строки и передается в get_transcription
функция. Если ответ JSON от Функция get_transcription
содержит статус completed
, тогда мы распечатать результаты транскрипции. В противном случае распечатайте текущий статус: либо в очереди
, либо обработка
перед он завершен
.
Вызов скрипта с помощью командной строки и идентификатора транскрипции из предыдущего раздела:
python get_transcription.py TRANSCRIPTION_ID
Если сервис еще не начал работать над расшифровкой стенограммы, то он вернет в очереди
следующим образом:
current status of transcription request: queued
Когда сервис в настоящее время работает с аудиофайлом, он вернуть processing
:
current status of transcription request: processing
Когда процесс будет завершен, наш скрипт вернет текст транскрипция, как вы видите здесь:
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)
Вот и все, у нас есть транскрипция!
Вам может быть интересно, что делать, если точность не там, где вам нужно это должно быть для вашей ситуации. Вот где повышение точности ключевых слов или фраз и выбор модели, которая лучше соответствует вашим данным войдите. Вы можете использовать любой из этих двух методов, чтобы повысить точность ваших записей до приемлемого для вашей ситуации уровня.
Что дальше?
Мы только что закончили писать сценарии, которые вызывают API AssemblyAI для транскрибировать записи с речью в текстовый вывод.
Затем взгляните на более сложную документацию, которая идет помимо основ в этом руководстве:
- Поддерживаемые форматы файлов
- Транскрибирование двухканальных / стереозаписей
- Получение ярлыков спикеров (диаризация спикеров)
Вопросов? Сообщите мне через тикет о проблеме на репозиторий Full Stack Python , в Твиттере @fullstackpython или @mattmakai . Что-то не так с этим сообщением? Вилка источник этой страницы на GitHub и отправьте запрос на перенос.