From 6ece209f4ccf7e27a4fb4963ca61bd93838c8921 Mon Sep 17 00:00:00 2001 From: Konstantin Krestnikov Date: Wed, 20 Oct 2021 17:35:03 +0300 Subject: [PATCH 1/2] Support auth by secret key and realtime microphone recording --- recognition/v1/python3/README.md | 2 +- recognition/v1/python3/recognize.py | 78 +++++++++++++++++++++++++---- 2 files changed, 70 insertions(+), 10 deletions(-) diff --git a/recognition/v1/python3/README.md b/recognition/v1/python3/README.md index 11fb43a..72b7427 100644 --- a/recognition/v1/python3/README.md +++ b/recognition/v1/python3/README.md @@ -1,6 +1,6 @@ # Installation - $ pip3 install grpcio-tools + $ pip3 install grpcio-tools requests pyaudio $ python3 -m grpc_tools.protoc -I .. -I ../../../task/v1 --python_out=. --grpc_python_out=. ../recognition.proto ../../../task/v1/{storage,task}.proto # Usage diff --git a/recognition/v1/python3/recognize.py b/recognition/v1/python3/recognize.py index 434eab5..ed81d6d 100755 --- a/recognition/v1/python3/recognize.py +++ b/recognition/v1/python3/recognize.py @@ -9,6 +9,11 @@ import recognition_pb2 import recognition_pb2_grpc +import requests +import pyaudio +import wave +import uuid +import base64 CHUNK_SIZE = 2048 SLEEP_TIME = 0.1 @@ -24,6 +29,35 @@ 'mulaw': recognition_pb2.RecognitionOptions.MULAW, } +# CHUNK_SIZE = 1024 +# audio = pyaudio.PyAudio() +# # start Recording +# frames = [] +# stream = audio.open(format=pyaudio.paInt16, channels=1, +# rate=8000, input=True, +# frames_per_buffer=CHUNK_SIZE) +# print("recording...") + +# for i in range(0, 100): +# data = stream.read(CHUNK_SIZE) +# frames.append(data) +# print("finished recording") + + +def auth(client_id, client_secret): + auth_code = base64.b64encode(bytes(f"{client_id}:{client_secret}", "ascii")).decode('ascii') + headers = { + "Content-Type": "application/x-www-form-urlencoded", + "RqUID": str(uuid.uuid4()), + "Authorization": f"Basic {auth_code}" + } + res = requests.post('https://salute.online.sberbank.ru:9443/api/v2/oauth', headers=headers, data="scope=SBER_SPEECH") + if res.ok: + data = res.json() + return res.json().get("access_token", None) + else: + print(f"Error {res.status_code}, {res.text}") + return None def try_printing_request_id(md): for m in md: @@ -31,16 +65,39 @@ def try_printing_request_id(md): print('RequestID:', m.value) -def generate_audio_chunks(path, chunk_size=CHUNK_SIZE, sleep_time=SLEEP_TIME): - with open(path, 'rb') as f: - for data in iter(lambda: f.read(chunk_size), b''): +def generate_audio_chunks(path, mic, recognition_options, chunk_size=CHUNK_SIZE, sleep_time=SLEEP_TIME): + if path: + with open(path, 'rb') as f: + for data in iter(lambda: f.read(chunk_size), b''): + yield recognition_pb2.RecognitionRequest(audio_chunk=data) + time.sleep(sleep_time) + elif mic: + audio = pyaudio.PyAudio() + stream = audio.open(format=pyaudio.paInt16, channels=1, + rate=recognition_options.sample_rate, input=True, + frames_per_buffer=CHUNK_SIZE) + print("Recording...") + while True: + data = stream.read(CHUNK_SIZE) yield recognition_pb2.RecognitionRequest(audio_chunk=data) - time.sleep(sleep_time) + else: + print("User --file or --mic argument") + exit(1) def recognize(args): + token = None + if not hasattr(args, "token"): + if not hasattr(args, "client_id") and not hasattr(args, "client_secret"): + print("Use token or client_id + client_secret arguments.") + exit(1) + else: + token = auth(args.client_id, args.client_secret) + else: + token = args.token + ssl_cred = grpc.ssl_channel_credentials() - token_cred = grpc.access_token_call_credentials(args.token) + token_cred = grpc.access_token_call_credentials(token) channel = grpc.secure_channel( args.host, @@ -51,7 +108,7 @@ def recognize(args): con = stub.Recognize(itertools.chain( (recognition_pb2.RecognitionRequest(options=args.recognition_options),), - generate_audio_chunks(args.file), + generate_audio_chunks(args.file, args.mic, args.recognition_options), )) try: @@ -82,7 +139,7 @@ def recognize(args): class Arguments: - NOT_RECOGNITION_OPTIONS = {'host', 'token', 'file', 'normalized_result', 'emotions_result'} + NOT_RECOGNITION_OPTIONS = {'host', 'token', 'client_id', 'client_secret', 'file', 'mic', 'normalized_result', 'emotions_result'} NOT_RECOGNITION_OPTIONS.update({'ca', 'cert', 'key'}) # diff DURATIONS = {'no_speech_timeout', 'max_speech_timeout', 'eou_timeout'} REPEATED = {'words'} @@ -114,8 +171,11 @@ def create_parser(): parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--host', default='smartspeech.sber.ru', help='host:port of gRPC endpoint') - parser.add_argument('--token', required=True, default=argparse.SUPPRESS, help='access token') - parser.add_argument('--file', required=True, default=argparse.SUPPRESS, help='audio file for recognition') + parser.add_argument('--token', required=False, default=argparse.SUPPRESS, help='access token') + parser.add_argument('--client_id', required=False, default=argparse.SUPPRESS, help='client id (instead of token)') + parser.add_argument('--client_secret', required=False, default=argparse.SUPPRESS, help='client id (instead of token)') + parser.add_argument('--file', required=False, default="", help='audio file for recognition') + parser.add_argument('--mic', action='store_true', help=' ') parser.add_argument('--normalized-result', action='store_true', help='show normalized text') parser.add_argument('--emotions-result', action='store_true', help='show emotions result') From 414ae03959667ca705d54bcbc016b328b70484fb Mon Sep 17 00:00:00 2001 From: Konstantin Krestnikov Date: Wed, 20 Oct 2021 17:40:02 +0300 Subject: [PATCH 2/2] Remove comments --- recognition/v1/python3/recognize.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/recognition/v1/python3/recognize.py b/recognition/v1/python3/recognize.py index ed81d6d..29a77b1 100755 --- a/recognition/v1/python3/recognize.py +++ b/recognition/v1/python3/recognize.py @@ -29,20 +29,6 @@ 'mulaw': recognition_pb2.RecognitionOptions.MULAW, } -# CHUNK_SIZE = 1024 -# audio = pyaudio.PyAudio() -# # start Recording -# frames = [] -# stream = audio.open(format=pyaudio.paInt16, channels=1, -# rate=8000, input=True, -# frames_per_buffer=CHUNK_SIZE) -# print("recording...") - -# for i in range(0, 100): -# data = stream.read(CHUNK_SIZE) -# frames.append(data) -# print("finished recording") - def auth(client_id, client_secret): auth_code = base64.b64encode(bytes(f"{client_id}:{client_secret}", "ascii")).decode('ascii')