This repository has been archived by the owner on Feb 3, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 64
/
outsource_audio2text.py
executable file
·139 lines (99 loc) · 5.06 KB
/
outsource_audio2text.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
from handler.base_plugin import CommandPlugin
from utils import traverse
import uuid, defusedxml.ElementTree as ET
import aiohttp
SUPPORTED = {
"ogg": "audio/ogg;codecs=opus",
"spx": "audio/x-speex",
"webm": "audio/webm;codecs=opus",
}
CHUNK_SIZE = 1024 ** 2
class Audio2TextPlugin(CommandPlugin):
__slots__ = ("key", "active", "active_once", "commands_once",
"commands_turn_on", "commands_turn_off", "configurations")
def __init__(self, commands_once=None, commands_turn_on=None,
commands_turn_off=None, key=None, prefixes=None, strict=False):
"""Plugin turning audio messages to text."""
if not key:
raise AttributeError("No api key specified! Get it here: https://tech.yandex.ru/speechkit/cloud/")
if not commands_once:
commands_once = ("что сказал", "что сказал?", "что сказала?", "что сказала",)
if not commands_turn_on:
commands_turn_on = ("в текст", "в текст on",)
if not commands_turn_off:
commands_turn_off = ("не надо в текст", "в текст off", "в текст оф",)
super().__init__(*(commands_once + commands_turn_on + commands_turn_off),
prefixes=prefixes, strict=strict)
self.key = key
self.commands_once = commands_once
self.commands_turn_on = commands_turn_on
self.commands_turn_off = commands_turn_off
self.active = False
self.active_once = False
self.configurations = {} # 0 - off, 1 - on, 2 - once
async def check_message(self, msg):
hm = await super().check_message(msg)
if not hm and self.configurations.get(msg.peer_id, 0) > 0:
msg.meta["__command"] = ""
msg.meta["__arguments"] = ""
msg.meta["__arguments_full"] = ""
return True
return hm
async def process_message(self, msg):
command, text = self.parse_message(msg)
if command in self.commands_turn_on:
if self.configurations.get(msg.peer_id, 0) in (0, 2):
self.configurations[msg.peer_id] = 1
return await msg.answer("Буду всё слушать и записывать :D")
return await msg.answer("Я и так всё слушаю и записываю \_C:_/")
if command in self.commands_turn_off:
self.configurations[msg.peer_id] = 0
return await msg.answer("Как хочешь...")
sound, exten = None, None
async def check(ats):
if not ats:
return None, None
for at in ats:
if at.type == "doc" and at.raw.get("ext") in SUPPORTED:
async with aiohttp.ClientSession() as sess:
async with sess.get(at.url) as resp:
return await resp.read(), at.raw.get("ext")
return None, None
if msg.brief_attaches:
sound, exten = await check(await msg.get_full_attaches())
if self.configurations.get(msg.peer_id, 0) != 1 or command in self.commands_once:
if sound is None and msg.brief_forwarded:
for m in traverse(await msg.get_full_forwarded()):
sound, exten = await check(await m.get_full_attaches())
if sound is not None:
break
if sound is None and command in self.commands_once:
if self.configurations.get(msg.peer_id, 0) != 1:
self.configurations[msg.peer_id] = 2
return await msg.answer("Переведу следующее в текст ;)")
return await msg.answer("Я и так всё перевожу \_C:_/")
if sound is None:
if msg.is_out or self.configurations.get(msg.peer_id, 0) == 1:
return False
return await msg.answer("Мне нечего перевести в текст :(")
@aiohttp.streamer
def sound_sender(writer):
chunki = 0
chunk = sound[chunki * CHUNK_SIZE: (chunki + 1) * CHUNK_SIZE]
while chunk:
yield from writer.write(chunk)
chunki += 1
chunk = sound[chunki * CHUNK_SIZE: (chunki + 1) * CHUNK_SIZE]
url = 'http://asr.yandex.net/asr_xml' + \
'?uuid=%s&key=%s&topic=%s&lang=%s' % (uuid.uuid4().hex, \
self.key, 'notes', 'ru-RU')
async with aiohttp.ClientSession() as sess:
async with sess.post(url, data=sound_sender(),
headers={"Content-Type": SUPPORTED[exten]}) as resp:
response = await resp.text()
if resp.status != 200:
return await msg.answer("Мне не получилось ничего разобрать или я больше не работаю!")
root = ET.fromstring(response)
if root.attrib['success'] not in ("1", 1):
return await msg.answer("Мда. Нет.")
return await msg.answer("\"" + str(root[0].text) + "\"")