Статья Telegram бот для конвертации голосовых сообщений в текст

INPC

Grey Team
21.08.2019
70
141
Приветствую!

В этой статье я расскажу о том, как не будучи кодером, писал себе бота для телеграмма. Для начала - немного предыстории. Собственно, она довольно короткая.

Моя позиция следующая: В мессенджеры надо писать буковки!

Лично мне очень не нравятся голосовые сообщения и люди, которые их постоянно используют. Для меня - это просто не удобно, не всегда есть наушники, для того чтоб прослушать присланное сообщение (слушать, через динамики, то, что тебе прислали в личку - вообще не приемлемо), не всегда бывает его вообще слышно (например в транспорте, или на улице)... Это долго, в конце-то концов. Гораздо проще и быстрее прочитать присланные буковы, чем слушать все эти *эээээ*, *мммм*, *чмчавк* и шум на фоне.

Каждое присланное мне голосовое сообщение напрягало меня все больше и больше. И вот, наконец, я не выдержал и решил написать себе бота, который будет всю эту неприятность переводить.

В качестве языка программирования был выбран питон, т.к. на нем я хоть что-то могу написать, а в качестве площадки для бота - телеграмм, т.к. api телеграмма для ботов имеет довольно низкий порог вхождения.

Ну что ж, для начала следует определиться с используемыми библиотеками и импортировать их:
Python:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import telebot
import requests
import speech_recognition as sr
import subprocess
import datetime

Со стандартными "os", "requests", "subprocess" и "datetime" все понятно.

telebot - это пакет, который предоставляет чистый интерфейс Python для Telegram Bot API.

Библиотека Speech Recognition — это, инструмент для передачи речевых API от компаний (google, microsoft, и др.), который в отличие от остальных имеет возможность работы офлайн. Именно Speech Recognition и будет использоваться для распознавания речи.

Еще будет использоваться ffmpeg. Как гласит описание с википедии - это набор свободных библиотек с открытым исходным кодом, которые позволяют записывать, конвертировать и передавать цифровые аудио- и видеозаписи в различных форматах. А устанавливается это чудо простым sudo apt-get install ffmpeg

Теперь создадим пару нужных переменных:
Python:
logfile = str(datetime.date.today()) + '.log' # формируем имя лог-файла
token = 'ваш_токен' # Обратите внимание, что хранить токены в коде - не хорошо, здесь эта строка только для примера
bot = telebot.TeleBot(token)

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

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

Python:
@bot.message_handler(content_types=['voice'])
def get_audio_messages(message):
# Основная функция, принимает голосовуху от пользователя
    try:
        print("Started recognition...")
        # Ниже пытаемся вычленить имя файла, да и вообще берем данные с мессаги
        file_info = bot.get_file(message.voice.file_id)
        path = file_info.file_path # Вот тут-то и полный путь до файла (например: voice/file_2.oga)
        fname = os.path.basename(path) # Преобразуем путь в имя файла (например: file_2.oga)
        doc = requests.get('https://api.telegram.org/file/bot{0}/{1}'.format(token, file_info.file_path)) # Получаем и сохраняем присланную голосвуху (Ага, админ может в любой момент отключить удаление айдио файлов и слушать все, что ты там говоришь. А представь, что такую бяку подселят в огромный чат и она будет просто логировать все сообщения [анонимность в телеграмме, ахахаха])
        with open(fname+'.oga', 'wb') as f:
            f.write(doc.content) # вот именно тут и сохраняется сама аудио-мессага
        process = subprocess.run(['ffmpeg', '-i', fname+'.oga', fname+'.wav'])# здесь используется страшное ПО ffmpeg, для конвертации .oga в .vaw
        result = audio_to_text(fname+'.wav') # Вызов функции для перевода аудио в текст
        bot.send_message(message.from_user.id, format(result)) # Отправляем пользователю, приславшему файл, его текст
    except sr.UnknownValueError as e:
        # Ошибка возникает, если сообщение не удалось разобрать. В таком случае отсылается ответ пользователю и заносим запись в лог ошибок
        bot.send_message(message.from_user.id,  "Прошу прощения, но я не разобрал сообщение, или оно поустое...")
        with open(logfile, 'a', encoding='utf-8') as f:
            f.write(str(datetime.datetime.today().strftime("%H:%M:%S")) + ':' + str(message.from_user.id) + ':' + str(message.from_user.first_name) + '_' + str(message.from_user.last_name) + ':' + str(message.from_user.username) +':'+ str(message.from_user.language_code) + ':Message is empty.\n')
    except Exception as e:
        # В случае возникновения любой другой ошибки, отправляется соответствующее сообщение пользователю и заносится запись в лог ошибок
        bot.send_message(message.from_user.id,  "Что-то пошло через жопу, но наши смелые инженеры уже трудятся над решением... \nДа ладно, никто эту ошибку исправлять не будет, она просто потеряется в логах.")
        with open(logfile, 'a', encoding='utf-8') as f:
            f.write(str(datetime.datetime.today().strftime("%H:%M:%S")) + ':' + str(message.from_user.id) + ':' + str(message.from_user.first_name) + '_' + str(message.from_user.last_name) + ':' + str(message.from_user.username) +':'+ str(message.from_user.language_code) +':' + str(e) + '\n')
    finally:
        # В любом случае удаляем временные файлы с аудио сообщением
        os.remove(fname+'.wav')
        os.remove(fname+'.oga')

bot.polling(none_stop=True, interval=0)# Очень не культурно стучимся к телеге и проверяем наличие сообщений

Ну и сама функция конвертации аудио в текст:
Python:
def audio_to_text(dest_name: str):
# Функция для перевода аудио, в формате ".vaw" в текст
    r = sr.Recognizer() # такое вообще надо комментить?
    # тут мы читаем наш .vaw файл
    message = sr.AudioFile(dest_name)
    with message as source:
        audio = r.record(source)
    result = r.recognize_google(audio, language="ru_RU") # используя возможности библиотеки распознаем текст, так же тут можно изменять язык распознавания
    return result

Python:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import telebot
import requests
import speech_recognition as sr
import subprocess
import datetime


logfile = str(datetime.date.today()) + '.log'
token = 'ваш_токен'
bot = telebot.TeleBot(token)

def audio_to_text(dest_name: str):
# Функция для перевода аудио , в формате ".vaw" в текст
    r = sr.Recognizer() # такое вообще надо комментить?
    # тут мы читаем наш .vaw файл
    message = sr.AudioFile(dest_name)
    with message as source:
        audio = r.record(source)
    result = r.recognize_google(audio, language="ru_RU") # здесь можно изменять язык распознавания
    return result


@bot.message_handler(content_types=['voice'])
def get_audio_messages(message):
# Основная функция, принимает голосовуху от пользователя
    try:
        print("Started recognition...")
        # Ниже пытаемся вычленить имя файла, да и вообще берем данные с мессаги
        file_info = bot.get_file(message.voice.file_id)
        path = file_info.file_path # Вот тут-то и полный путь до файла (например: voice/file_2.oga)
        fname = os.path.basename(path) # Преобразуем путь в имя файла (например: file_2.oga)
        doc = requests.get('https://api.telegram.org/file/bot{0}/{1}'.format(token, file_info.file_path))# Получаем и сохраняем присланную голосвуху (Ага, админ может в любой момент отключить удаление айдио файлов и слушать все, что ты там говоришь. А представь, что такую бяку подселят в огромный чат и она будет просто логировать все сообщения [анонимность в телеграмме, ахахаха])
        with open(fname+'.oga', 'wb') as f:
            f.write(doc.content) # вот именно тут и сохраняется сама аудио-мессага
        process = subprocess.run(['ffmpeg', '-i', fname+'.oga', fname+'.wav'])# здесь используется страшное ПО ffmpeg, для конвертации .oga в .vaw
        result = audio_to_text(fname+'.wav') # Вызов функции для перевода аудио в текст, а заодно передаем имена файлов, для их последующего удаления
        bot.send_message(message.from_user.id, format(result))
    except sr.UnknownValueError as e:
        bot.send_message(message.from_user.id,  "Прошу прощения, но я не разобрал сообщение, или оно поустое...")
        with open(logfile, 'a', encoding='utf-8') as f:
            f.write(str(datetime.datetime.today().strftime("%H:%M:%S")) + ':' + str(message.from_user.id) + ':' + str(message.from_user.first_name) + '_' + str(message.from_user.last_name) + ':' + str(message.from_user.username) +':'+ str(message.from_user.language_code) + ':Message is empty.\n')
    except Exception as e:
        bot.send_message(message.from_user.id,  "Что-то пошло через жопу, но наши смелые инженеры уже трудятся над решением... \nДа ладно, никто эту ошибку исправлять не будет, она просто потеряется в логах.")
        with open(logfile, 'a', encoding='utf-8') as f:
            f.write(str(datetime.datetime.today().strftime("%H:%M:%S")) + ':' + str(message.from_user.id) + ':' + str(message.from_user.first_name) + '_' + str(message.from_user.last_name) + ':' + str(message.from_user.username) +':'+ str(message.from_user.language_code) +':' + str(e) + '\n')
    finally:
        os.remove(fname+'.wav')
        os.remove(fname+'.oga')

bot.polling(none_stop=True, interval=0)# Очень не культурно стучимся телеге и проверяем наличие сообщений

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

1639506009709.png


1639506021214.png


1639506201802.png


P.S. Бот работает с довольно высокой точностью, переводя даже длинные сообщения, зацензуривая при этом не приличные слова. Так же бот работает, как на линухе, так и на винде.

Собственно, вот и все... Лично меня результат вполне устраивает. А как вам? Пишите, что можно улучшить, или поменять, с радостью все выслушаю и учту. И еще раз напоминаю, что с питоном я работаю на уровне "набросать говноскрипт, лишь бы работал", так что не кидайте сильно камнями, если что не так)

Ну и разумеется, спасибо, что дочитали эту статью до конца.
 
Последнее редактирование модератором:

tiolpxe

Green Team
04.03.2020
18
12
Ты, возможно, спас миллионы пользователей от страданий. Хорошая работа
 
  • Нравится
Реакции: INPC
02.03.2021
380
250
спасибо за статью хорошее решение.
Теперь в ответ на голосовое можно не отправлять картиночку

ya-konechno-ne-budu_128534441_orig_.jpg
 
  • Нравится
Реакции: migu и INPC

r4z0r5

Green Team
03.04.2018
13
15
Рекомендую Voicy, чтобы не превращаться в велосипедиста.
Хотя я сам попадал в аналогичную ситуацию когда хотел скачать аудиодорожку из видео с YouTube. Пришлось тоже делать бота.
 
  • Нравится
Реакции: Сергей Сталь

white-hat

Member
04.12.2021
5
0
Что-то не получается(( Выдаёт такую ошибку когда пытаюсь запустить скрипт


Код:
Traceback (most recent call last):
  File "/home/kali/Desktop/bot/script.py", line 6, in <module>
    import telebot
ModuleNotFoundError: No module named 'telebot'
 

INPC

Grey Team
21.08.2019
70
141
Что-то не получается(( Выдаёт такую ошибку когда пытаюсь запустить скрипт


Код:
Traceback (most recent call last):
  File "/home/kali/Desktop/bot/script.py", line 6, in <module>
    import telebot
ModuleNotFoundError: No module named 'telebot'

Пишет, что у вас не установлен модуль telebot . Вообще, для начала рекомендую гуглить ошибки, обычно, сразу много вопросов отпадает и понимания больше становится.
Решается вопрос, через
pip install telebot
Или, если python 3:
pip3 install telebot
 
  • Нравится
Реакции: white-hat

white-hat

Member
04.12.2021
5
0
Пишет, что у вас не установлен модуль telebot . Вообще, для начала рекомендую гуглить ошибки, обычно, сразу много вопросов отпадает и понимания больше становится.
Решается вопрос, через
pip install telebot
Или, если python 3:
pip3 install telebot
Cорри, первый раз с этим работаю. Саму ошибку понял но не знал как её исправить. Подскажи а как устанавливается speech_recognition?
через команду выполнить не получилось как это получилось с telebot
Код:
# pip3 install speech_recognition                                  1 ⨯ 4 ⚙
ERROR: Could not find a version that satisfies the requirement speech_recognition                                                                         
ERROR: No matching distribution found for speech_recognition
 

INPC

Grey Team
21.08.2019
70
141
Cорри, первый раз с этим работаю. Саму ошибку понял но не знал как её исправить. Подскажи а как устанавливается speech_recognition?
через команду выполнить не получилось как это получилось с telebot
Код:
# pip3 install speech_recognition                                  1 ⨯ 4 ⚙
ERROR: Could not find a version that satisfies the requirement speech_recognition                                                                         
ERROR: No matching distribution found for speech_recognition

pip install SpeechRecognition
 
  • Нравится
Реакции: white-hat

INPC

Grey Team
21.08.2019
70
141
Почему его нет или мне нужно его изменить?

Код:
Traceback (most recent call last):
  File "/home/kali/Desktop/bot/script.py", line 28, in <module>
    @bot.message_handler(content_types=['voice'])
AttributeError: 'TeleBot' object has no attribute 'message_handler'
'TeleBot' object has no attribute 'message_handler' · Issue #9 · MasterGroosha/telegram-tutorial

Слушай, я не знаю, какой у тебя часовой пояс, но у меня сейчас 5:44 утра. Посмотри ссылку, попробуй так же. Проверь версии. Проверь, все ли, сделано, как в скрипте, проверь, как ты указал токен. И если не поможет - кидай полный код в ЛС, днём посмотрю, что там не так
 
  • Нравится
Реакции: Сергей Сталь

white-hat

Member
04.12.2021
5
0
'TeleBot' object has no attribute 'message_handler' · Issue #9 · MasterGroosha/telegram-tutorial

Слушай, я не знаю, какой у тебя часовой пояс, но у меня сейчас 5:44 утра. Посмотри ссылку, попробуй так же. Проверь версии. Проверь, все ли, сделано, как в скрипте, проверь, как ты указал токен. И если не поможет - кидай полный код в ЛС, днём посмотрю, что там не так
Спасибо. Всё заработало. Осталось теперь понять как сделать скрипт автономным)
 
02.03.2021
380
250
Спасибо. Всё заработало. Осталось теперь понять как сделать скрипт автономным)
попробуй погуглить по словам сделать скрипт автономным или что то подобное, скорее всего можно на какой то хостинг положить и он будет работать
 

ooolledj

One Level
26.03.2021
4
1
Задумка простая и интересная, попробовал у себя, не без допиливания, но заработало, спасибо.

Столкнулся с несколькими проблемами в процессе тестирования:
1. AttributeError: 'TeleBot' object has no attribute 'message_handler'
Решилось установкой другой версии модуля:
Bash:
pip install pytelegrambotapi==3.6.6
2. В логах: No such file or directory: 'file_0.ogawav'
Всё из-за того, что
Python:
path = file_info.file_path
хранил имя файла с расширением (file_0.oga). Решилось с помощью:
Python:
path = os.path.splitext(file_info.file_path)[0]
 
  • Нравится
Реакции: INPC
17.05.2022
2
0
Здравствуйте, INPC, не подскажите, почему Heroku модуль speechrecognition не находит, когда я деплоить пытаюсь (ModulNotFoundError)?
 

Lizami Amino

New member
11.06.2022
1
0
Что делает переменная "process" эта переменная вообще не используется.
 
17.05.2022
2
0
Здравствуйте, INPC, не подскажите, почему Heroku модуль speechrecognition не находит, когда я деплоить пытаюсь (ModulNotFoundError)?
Ответ: там с Гит'ом что-то намудрил. Но потом еще столкнулся с проблемой, что нужно аудиофайлы где-то сохранять на каком-нибудь интернет-сервере.
 

Tex00n

New member
19.06.2022
1
0
Добрый вечер, столкнулся с проблемой, что код не может найти файл, может кто подсказать как её решить?
1655713251087.png

Файл сохраняется как "file_21.oga", а не "file_21.wav"

Python:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import telebot
import requests
import speech_recognition as sr
import subprocess
import datetime


logfile = str(datetime.date.today()) + '.log'
token = '5192684196:AAGBdm3XLrCN8yogiUd7HiBrT4ClK-nCcpY'
bot = telebot.TeleBot(token)

def audio_to_text(dest_name: str):
# Функция для перевода аудио , в формате ".vaw" в текст
    r = sr.Recognizer() # такое вообще надо комментить?
    # тут мы читаем наш .vaw файл
    message = sr.AudioFile(dest_name)
    with message as source:
        audio = r.record(source)
    result = r.recognize_google(audio, language="ru_RU") # здесь можно изменять язык распознавания
    return result


@bot.message_handler(content_types=['voice'])
def get_audio_messages(message):
# Основная функция, принимает голосовуху от пользователя
    try:
        print("Started recognition...")
        # Ниже пытаемся вычленить имя файла, да и вообще берем данные с мессаги
        file_info = bot.get_file(message.voice.file_id)
        path = os.path.splitext(file_info.file_path)[0] # Вот тут-то и полный путь до файла (например: voice/file_2.oga)
        fname = os.path.basename(path) # Преобразуем путь в имя файла (например: file_2.oga)
        doc = requests.get('https://api.telegram.org/file/bot{0}/{1}'.format(token, file_info.file_path))
        with open(fname+'.oga', 'wb') as f:
            f.write(doc.content) # вот именно тут и сохраняется сама аудио-мессага
        
        result = audio_to_text(fname+'.oga') # Вызов функции для перевода аудио в текст, а заодно передаем имена файлов, для их последующего удаления
        bot.send_message(message.from_user.id, format(result))
    except sr.UnknownValueError as e:
        bot.send_message(message.from_user.id,  "Прошу прощения, но я не разобрал сообщение, или оно поустое...")
        with open(logfile, 'a', encoding='utf-8') as f:
            f.write(str(datetime.datetime.today().strftime("%H:%M:%S")) + ':' + str(message.from_user.id) + ':' + str(message.from_user.first_name) + '_' + str(message.from_user.last_name) + ':' + str(message.from_user.username) +':'+ str(message.from_user.language_code) + ':Message is empty.\n')
    except Exception as e:
        bot.send_message(message.from_user.id,  "Что-то пошло через жопу, но наши смелые инженеры уже трудятся над решением... \nДа ладно, никто эту ошибку исправлять не будет, она просто потеряется в логах.")
        with open(logfile, 'a', encoding='utf-8') as f:
            f.write(str(datetime.datetime.today().strftime("%H:%M:%S")) + ':' + str(message.from_user.id) + ':' + str(message.from_user.first_name) + '_' + str(message.from_user.last_name) + ':' + str(message.from_user.username) +':'+ str(message.from_user.language_code) +':' + str(e) + '\n')
    finally:
        os.remove(fname+'.wav')
        os.remove(fname+'.oga')

bot.polling(none_stop=True, interval=0)# Очень не культурно стучимся телеге и проверяем наличие сообщений
 
Мы в соцсетях: