From 3edf2645cdd55eb3b6677e37d182fe4f905c92f7 Mon Sep 17 00:00:00 2001 From: Roman Bazalevskiy Date: Tue, 9 Nov 2021 09:29:34 +0300 Subject: [PATCH] Minor API fixes for OH3 --- voicecontrol | 107 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 64 insertions(+), 43 deletions(-) diff --git a/voicecontrol b/voicecontrol index fafda2c..703e109 100755 --- a/voicecontrol +++ b/voicecontrol @@ -1,9 +1,9 @@ -#!/usr/bin/env python3.8 +#!/usr/bin/env python3 import websockets,asyncio import sys from pyaudio import PyAudio, Stream, paInt16 -from contextlib import asynccontextmanager, contextmanager, AsyncExitStack +from contextlib import asynccontextmanager, contextmanager, AsyncExitStack, ExitStack from typing import AsyncGenerator, Generator from urllib.parse import urlencode, quote @@ -57,6 +57,12 @@ def SkipSource(source,seconds): except: pass +def Silence(speaker, seconds): + buf = bytes(speaker._frames_per_buffer) + bufs = int((seconds)*speaker._rate/speaker._frames_per_buffer) + for i in range(bufs): + speaker.write(buf) + def PlayBack(pyaud, text, mic = None): global config, last_time @@ -78,6 +84,7 @@ def PlayBack(pyaud, text, mic = None): decoder = MP3Decoder(req) speaker = pyaud.open(output=True, format=paInt16, channels=decoder.num_channels, rate=decoder.sample_rate) + Silence(speaker, 0.3) for chunk in decoder: speaker.write(chunk) @@ -148,7 +155,14 @@ def RunCommand(command, pyaud, mic = None): PlayBack(pyaud, res, mic=mic) elif res=="NULL": PlayBack(pyaud, "Сервер не ответил", mic=mic) - http.request('POST',command_url, headers=my_headers, body="") + if command_user: + my_headers = urllib3.util.make_headers(basic_auth=command_user+':'+command_pwd) + else: + my_headers = urllib3.util.make_headers() + my_headers['Content-Type']='text/plain' + my_headers['Accept']='apllication/json' + command="" + http.request('POST',command_url, headers=my_headers, body=command.encode('UTF-8')) except KeyboardInterrupt: raise except: @@ -207,11 +221,10 @@ async def ListenPhrase(mic, server): except websockets.exceptions.ConnectionClosedError: raise except: - raise return '',0 -async def hello(uri): +async def main_loop(uri): global config, last_time @@ -220,49 +233,57 @@ async def hello(uri): rec_attempts = config["rec_attempts"] commands = config["commands"] - async with AsyncExitStack() as stack: - ws = await stack.enter_async_context(websockets.connect(uri)) - print('Type Ctrl-C to exit') - phrases = config["commands"] - phrases.append(config["keyphrase"]) - phrases = json.dumps(phrases, ensure_ascii=False) - await ws.send('{"config" : { "phrase_list" : '+phrases+', "sample_rate" : 16000.0}}') - - ws = await stack.enter_async_context(_polite_websocket(ws)) - p = stack.enter_context(_pyaudio()) - s = stack.enter_context(_pyaudio_open_stream(p, + + with ExitStack() as audio_stack: + p = audio_stack.enter_context(_pyaudio()) + s = audio_stack.enter_context(_pyaudio_open_stream(p, format = paInt16, channels = 1, rate = 16000, input = True, frames_per_buffer = 2000)) - while True: - phrase, confidence = await ListenPhrase(s, ws) - if config["debug"]: - print(phrase,confidence) - if phrase == keyphrase and confidence>=confidence_treshold : - PlayBack(p, "Я жду команду", mic=s) - command = "" - - for i in range(rec_attempts): - phrase, confidence = await ListenPhrase(s, ws) - if config["debug"]: - print(phrase,confidence) - if confidence > confidence_treshold: - if (not commands) or (phrase in commands): - if config["debug"]: - print("Command: ", phrase) - command = phrase - RunCommand(command, p, s) - break - else: - PlayBack(p, "Не знаю такой команды: "+phrase, mic=s) - else: - PlayBack(p, "Не поняла, слишком неразборчиво", mic=s) - - if not command: - PlayBack(p, "Так команду и не поняла...", mic=s) + while True: + try: + async with AsyncExitStack() as web_stack: + ws = await web_stack.enter_async_context(websockets.connect(uri)) + print('Type Ctrl-C to exit') + phrases = [] + config["commands"] + phrases.append(config["keyphrase"]) + phrases = json.dumps(phrases, ensure_ascii=False) + await ws.send('{"config" : { "phrase_list" : '+phrases+', "sample_rate" : 16000.0}}') + + ws = await web_stack.enter_async_context(_polite_websocket(ws)) + while True: + phrase, confidence = await ListenPhrase(s, ws) + if config["debug"]: + print(phrase,confidence) + if phrase == keyphrase and confidence>=confidence_treshold : + PlayBack(p, "Я жду команду", mic=s) + command = "" + + for i in range(rec_attempts): + phrase, confidence = await ListenPhrase(s, ws) + if config["debug"]: + print(phrase,confidence) + if confidence > confidence_treshold: + if (not commands) or (phrase in commands): + if config["debug"]: + print("Command: ", phrase) + command = phrase + RunCommand(command, p, s) + break + else: + PlayBack(p, "Не знаю такой команды: "+phrase, mic=s) + else: + PlayBack(p, "Не поняла, слишком неразборчиво", mic=s) + + if not command: + PlayBack(p, "Так команду и не поняла...", mic=s) + except KeyboardInterrupt: + raise + except: + pass def get_config(path): @@ -379,7 +400,7 @@ while True: loop = asyncio.get_event_loop() loop.run_until_complete( - hello(f'ws://' + server)) + main_loop(f'ws://' + server)) except (Exception, KeyboardInterrupt) as e: loop.run_until_complete( -- 2.34.1