Pull to refresh

Распознаем голосовые сообщения Telegram без СМС и пересылок ботам

Reading time7 min
Views10K

Как всем известно, люди делятся на две категории:

  1. Те, кто любит отправлять голосовые сообщения

  2. Те, кто кто надеются, что для первых приготовлен отдельный котел, градусов так на 200. Можно сделать похолоднее, вот инструкция:

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

Мое отношение к голосовым сообщениям

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

Какие есть варианты для решения проблемы

Теперь, когда мы точно убедились, что вам именно сюда, рассмотрим уже, наконец, варианты:

  • Встроенное в телеграмм распознавание текста после покупки Premium. Ну это слишком просто) К тому же это надо покупа-а-а-ать. А мы не такие!

  • Распознавание текста путем пересылки ботам. Еще одно неплохое решение, благо ботов сейчас много и платных и бесплатных. Но есть и минусы:

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

    • Если это не твой собственный бот, то пересылать третьим лицам личные сообщения - такое себе.

  • Отказ слушать голосовые. Тут есть разные способы, кто купил себе премиум - может просто заблокировать прием голосовых, кто не купил тоже пытается изгаляться как может:

    • кто-то в ответ на голосовое отправляет сообщение типа: "голосовые сообщения отключены" или "не доставлено: пользователь запретил голосовые сообщения" и т.д. и иногда собеседник на той стороне даже верит... и начинает слать свои голосовые в WhatsApp.

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

    Некоторые из вариантов предназначены для того, чтобы поиздеваться над человеком на той стороне, некоторые более сдержанны, но в любом случае они нам не подходят для решения нашей проблемы. Потому, что решить проблему перевалив её на другого - это не решение проблемы, а ее перекладывание. Если человек отправляет голосовые сообщения, значит ему так, действительно, удобнее, и заставив его набирать все это текстом, мы делаем удобнее себе за счет причинения неудобства ему. Но мы не идем этим путем. Мы хотим, чтобы тот, кто хочет диктовать, мог диктовать, а мы, если хотим читать, могли читать.

Переходим от слов к делу

Итак в чем заключается моя идея? Мы не можем написать простого бота потому, что столкнемся с необходимостью пересылки сообщений, как у всех остальных подобных ботов. А мы не хотим ничего никуда пересылать, мы хотим, чтобы все само. Но мы можем написать свою программу, которая будет крутиться на каком-нибудь нашем сервере (у нас всех же есть свой сервер, правда?) через Telegram ApiId и ApiHash иметь доступ к нашему аккаунту, как дополнительный клиент, она будет получать все сообщения и писать нам расшифровку прямо в чате! Правда писать она будет он нашего же имени, телеграм не даст нам написать в чат от имени собеседника. Поэтому, возможно, собеседник будет слегка удивлен, когда мы тут же ответим на его голосовое, текстом его же голосового. Но мы пожалеем его психику и припишем, что это бот распознал.

Для начала нам нужно получить ключи разработчика телеграм, это легко: https://core.telegram.org/api/obtaining_api_id

Затем можно приступить к написанию клиента, я это делал на C# и древнем .Net Core 3.1, и использовал библиотеку WTelegramClient

Дальше надо подумать, как распознавать текст, да еще и на русском, да еще и в оффлайне. Вначале я подумал про распознавание текста через какую-нибудь утилиту командной строки, поэтому спросил у ЧатаГПТ:

List me all software for Windows that can convert audio speech to text using command line in offline mode supporting Russian language

И он выдал мне прекрасные вещи:

1. IBM Watson Speech to Text: IBM offers a powerful speech recognition service that supports multiple languages, including Russian. While it's primarily a cloud-based service, IBM provides an option to deploy on-premises for offline use to meet various requirements like data privacy or low latency. You would have to check the current availability and features for command line usage in offline mode.

2. CMU Sphinx (PocketSphinx): Sphinx is an open-source speech recognition system developed at Carnegie Mellon University. PocketSphinx is especially designed for mobile and other resource-limited devices. While it primarily supports English out of the box, there are Russian language models available that you might be able to integrate. You can interact with PocketSphinx via command line.

3. Mozilla DeepSpeech: DeepSpeech is an open-source speech-to-text engine based on deep learning that can be used offline. You can build or download pre-trained models for various languages, and there are community-contributed models for different languages, including Russian. DeepSpeech provides a command-line interface to perform speech-to-text using these models.

4. Kaldi: Kaldi is an open-source toolkit for speech recognition for researchers. The toolkit is more complex than others listed here but offers state-of-the-art speech recognition features. There are Kaldi models for Russian language available in the community that you can leverage. Kaldi does support command-line operations, although setting everything up might require a deep dive into the documentation.

5. Vosk-API: Vosk is an open-source speech recognition toolkit available for multiple programming languages. It supports several languages, including Russian, and can run on different platforms like Windows, Linux, macOS, and even on mobile devices. It has a command-line interface, and since it's open-source, you can use it offline.

Я все тщательно изучил, проанализировал и принял самое оптимальное и взвешенное решение ткнуть случайно пальцем в один из них и это был Vosk-API. У этого проекта есть плюсы и минусы, давайте с хорошего, у них есть библиотека сразу под c# (nuget) поэтому не нужно ничего делать через командную строку или отдельный веб-сервер. А вот минусы кому-то могут показаться критичными: в библиотеку под c# они не завезли пока пунктуацию и все что распознается, распознается сплошным потоком слов, без точек и запятых. На питоне у них это вроде даже работает, но не для шарпа, но позже обещают завезти. Меня пока устраивает и так, поэтому я решил пойти этим путем. Впрочем, в конце будет бонус, где и эта проблема будет решена.

Итак, идем к ним за моделями:
https://alphacephei.com/vosk/models
Из русских есть большая и маленькая модель. Большая загружается программой довольно долго (2-5мин), но распознает текст лучше. Но для большой модели вам потребуется немножко памяти:

Да, больше 5 гигов, это не проблема для современного домашнего компьютера, но если у вас арендован дешевый 2х гиговый VDS в датацентре, то тут ой. Придется использовать маленькую модель. Она тоже распознаёт. Распознаёт же, да? да??

На самом деле все нормально, распознаёт, да, чуть хуже)
На самом деле все нормально, распознаёт, да, чуть хуже)

Проверяем распознавание

Пишем код

Написали: https://github.com/CodeName33/TGAudioToText

Теперь о том, что же было написано. Программа постоянно запущена и получает все сообщения которые идут к нам или от нас. Если она видит голосовое, она его распознает и пишет ниже распознанный текст, как сообщение. В настройках у неё можно включать и выключать следующее:

  • InPersonal - распознавать голосовые сообщения приходящие лично от контакта

  • OutPersonal - распознавать голосовые сообщения исходящие от вас лично контакту

  • OutGroup - распознавать голосовые сообщения исходящие от вас в групповой чат

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

Как это выглядит:

Сначала Бот пишет сообщение, что распознает текст
Сначала Бот пишет сообщение, что распознает текст
А когда распознает, редактирует это сообщение, вставляя туда распознанный текст
А когда распознает, редактирует это сообщение, вставляя туда распознанный текст

Как это все запустить

Итак, если вы решили, что вам это тоже надо, то тогда:

  1. Программу берем здесь: https://github.com/CodeName33/TGAudioToText

    • Если вы мне ну очень сильно доверяете, то можно брать сразу релизы бинарников

    • В противном случае берем исходники и начинаем их читать. Убеждаемся, что программа ничего никому не сливает. Дальше убеждаемся, что программа точно ничего никому не сливает. Дальше убеждаемся, что программа, вот прямо совсем никогда ничего никому не сливает. И вот тогда компилируем исходники с помощью DotNet под нужную архитектуру и переходим к пункту 2.

  2. Понадобится также FFMPEG, чтобы перекодировать звук в WAV 16000kHz. Для линукса это что-то типа:

sudo apt-get install ffmpeg

Но если ваш линукс не такой, то сделайте это как-то по другому. Под Windows можно пойти сюда: https://ffmpeg.org/download.html#build-windows, скачать бинарники и положить их в папку с программой (чтобы ffmpeg.exe был в одной папке с TGAudioToText.exe)

  1. Теперь качаем модель отсюда https://alphacephei.com/vosk/models и распаковываем в папку с программой

  2. Запускаем TGAudioToText и он создаст полупустой конфиг рядом с собой (TGAudioToText.cfg)

  3. В конфиге заполняем поля:

    ModelName - название папки модели

    TelegramPhone - Ваш номер телефона (+79xxxxxxxxx)

    TelegramApiId TelegramApiHash - Telegram ApiId и ApiHash (как получить тут: https://core.telegram.org/api/obtaining_api_id)

  4. Дальше снова запускаем программу, и в первый раз она спросит код, который придет вам в телеграмм. После его введения спрашивать больше не будет. Дальше по документам должно настать "все работает". Надеюсь по факту будет также.

Бонус. Пунктуация

Все-таки проект не будет закончен, если распознавание будет идти сплошным потоком текста, это все хоть и читаемо, но не совсем. Поэтому стал искать как это сделать, ну на питоне, так на питоне, что делать. Не люблю я его, но тут и не про любовь. Стал я ковырять модель пунктуации от VOSK, но что-то не удалось её завести,то одна ошибка выскакивала то другая. Я игрался с версиями питона и библиотек, но проиграл. Плюнул и решил воспользоваться другой моделью: https://huggingface.co/kontur-ai/sbert_punc_case_ru

Итак, сделал версию 1.1, где в конфиг добавились 2 параметра:

  • PunctuationEnabled - ставим True, если пунктуация нужна.

  • PunctuationServer - адрес Веб-сервера пунктуации (по умолчанию http://127.0.0.1:8018/)

Настройка:

  1. Потребуется установить Python и Git (Для Linux обязательн нужны модули VENV и PIP)

  2. В папке с программой есть папка "punctuation" в ней запустить "punctuation-server-setup" (.cmd для Windows, .sh для Linux). Возможно все будет хорошо)

  1. Прописываем в настройку в TGAudioToText.cfg:

    PunctuationEnabled = True

  2. В папке с программой есть папка "punctuation" в ней запустить "punctuation-server" (.cmd для Windows, .sh для Linux). Запустится сервер пунктуации, его надо будет всегда запускать в паре с программой при старте ситсемы.

  3. Запускаем программу TGAudioToText и она будет обращаться на сервер пунктуации за добавлением точек и запятых.

Выглядит теперь это так
Выглядит теперь это так

Ну вот и все, надеюсь было интересно.

Tags:
Hubs:
+36
Comments30

Articles