· 5 years ago · Aug 11, 2020, 01:10 PM
1import xml.etree.ElementTree as XmlElementTree
2import httplib2
3import uuid
4from config import ***
5
6***_HOST = '***'
7***_PATH = '/***_xml'
8CHUNK_SIZE = 1024 ** 2
9
10
11# Конвертация аудио в текст через внешний API
12def speech_to_text(filename=None, bytes=None, request_id=uuid.uuid4().hex, topic='notes', lang='ru-RU', key=***_API_KEY):
13
14 # Попытка открытия файла
15 if filename:
16 with open(filename, 'br') as file:
17 bytes = file.read()
18 if not bytes:
19 raise Exception('Neither file name nor bytes provided.')
20
21 # Конвертация аналогового сигнала в цифровой
22 bytes = convert_to_pcm16b16000r(in_bytes=bytes)
23
24 # Генерация URL для отправки запроса к сервису через API
25 url = ***_PATH + '?uuid=%s&key=%s&topic=%s&lang=%s' % (
26 request_id,
27 key,
28 topic,
29 lang
30 )
31
32 chunks = read_chunks(CHUNK_SIZE, bytes)
33
34 connection = httplib2.HTTPConnectionWithTimeout(***_HOST)
35
36 connection.connect()
37 connection.putrequest('POST', url)
38 connection.putheader('Transfer-Encoding', 'chunked')
39 connection.putheader('Content-Type', 'audio/x-pcm;bit=16;rate=16000')
40 connection.endheaders()
41
42 # Отправка аудио по частям
43 for chunk in chunks:
44 connection.send(('%s\r\n' % hex(len(chunk))[2:]).encode())
45 connection.send(chunk)
46 connection.send('\r\n'.encode())
47
48 connection.send('0\r\n\r\n'.encode())
49 response = connection.getresponse()
50
51 # В случайе возврата 200Ok с сервиса
52 if response.code == 200:
53 # Содержимое ответа с сервиса (json)
54 response_text = response.read()
55
56 # json -> xml
57 xml = XmlElementTree.fromstring(response_text)
58
59 # В случае успешной обработки звука
60 if int(xml.attrib['success']) == 1:
61 # Задание нижней границы в качестве датчика
62 max_confidence = - float("inf")
63 text = ''
64
65 # Цикл поиска наиболее достоверного слова
66 # Чей 'confidence' выше
67 for child in xml:
68 if float(child.attrib['confidence']) > max_confidence:
69 text = child.text
70 max_confidence = float(child.attrib['confidence'])
71
72 if max_confidence != - float("inf"):
73 return text
74 else:
75 # Если сервис не обнаружил слова
76 raise SpeechException(
77 'No text found.\n\nResponse:\n%s' % (response_text))
78 else:
79 # Если сервис не смог обработать звук
80 raise SpeechException(
81 'No text found.\n\nResponse:\n%s' % (response_text))
82 else:
83 # Если сервис вернул ошибку
84 raise SpeechException('Unknown error.\nCode: %s\n\n%s' %
85 (response.code, response.read()))
86
87# Создание класса ошибок для использования raise конструкции
88сlass SpeechException(Exception):
89 pass
90