Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Проксирование запросов с Фронтенда в Yandex Speechkit в Django при помощи Websocket #18

Open
Banzaika opened this issue Sep 12, 2023 · 0 comments

Comments

@Banzaika
Copy link

Здравствуйте, я плохо знаком с данным пакетом, поэтому прошу помощи у вас. Мне нужно написать бэкенд приложение на Джанго, который будет использоваться React'ом как прокси запросов к Yandex SpeechKit, используя WebSocket протокол. В документации приведен пример кода, демонстрирующий потоковое распазнование речи с микрофона, но я слишком глуп, чтобы реконструировать его под мой случай. В Read.me указана документация ко всему YandexCloud, но я не нашел там документацию именно к этому репо. Для каждого вебсокет соединения создается объект питон WebsocketConsumer, у него есть методы connect, receive, disconnect. В методе receive принимается порция аудиоданных в виде bytes, конвертируется при помощи Speechkit и возвращается обратно клиенту. Можете ли привести пример кода, который будет конвертировать аудио в текст при помощи cloudapi при проксировании? Пример WebsocketConsumer, который я успел написать(он неправильный):

from channels.generic.websocket import WebsocketConsumer
import grpc
import cloudapi.output.yandex.cloud.ai.stt.v3.stt_pb2 as stt_pb2
import cloudapi.output.yandex.cloud.ai.stt.v3.stt_service_pb2_grpc as stt_service_pb2_grpc

class MyConsumer(WebsocketConsumer):
    secret = 'some-token'
    rate = 8000
    chunk = 4000
    def get_settings_recognition(self):
        '''Генератор возвращяющий настройки распознавания.'''
        # Задать настройки распознавания.
        recognize_options = stt_pb2.StreamingOptions(
          recognition_model=stt_pb2.RecognitionModelOptions(
             audio_format=stt_pb2.AudioFormatOptions(
                raw_audio=stt_pb2.RawAudio(
                   audio_encoding=stt_pb2.RawAudio.LINEAR16_PCM,
                   sample_rate_hertz=8000,
                   audio_channel_count=1
                )
             ),
             text_normalization=stt_pb2.TextNormalizationOptions(
                text_normalization=stt_pb2.TextNormalizationOptions.TEXT_NORMALIZATION_ENABLED,
                profanity_filter=True,
                literature_text=False
             ),
             language_restriction=stt_pb2.LanguageRestrictionOptions(
                restriction_type=stt_pb2.LanguageRestrictionOptions.WHITELIST,
                language_code=['ru-RU']
             ),
             audio_processing_type=stt_pb2.RecognitionModelOptions.REAL_TIME
          )
        )


        yield stt_pb2.StreamingRequest(session_options=recognize_options)

    def connect(self):

        # Установить соединение с сервером.
        cred = grpc.ssl_channel_credentials()
        channel = grpc.secure_channel('stt.api.cloud.yandex.net:443', cred)
        self.stub = stt_service_pb2_grpc.RecognizerStub(channel)

        # Отправить данные для распознавания.
        self.stub.RecognizeStreaming(self.get_settings_recognition(), metadata=(
          ('authorization', f'Api-Key {self.secret}'),
        ))
        self.accept()

    def disconnect(self, close_code):
        pass

    def gen_chunk(self, audio_data: bytes):
        yield stt_pb2.StreamingRequest(chunk=stt_pb2.AudioChunk(data=audio_data))

    def receive(self, bytes_data):
        audio_data = bytes_data
        audio_data = stt_pb2.StreamingRequest(chunk=stt_pb2.AudioChunk(data=audio_data))
        resp = self.stub.RecognizeStreaming(self.gen_chunk(audio_data), metadata=(
            ('authorization', f'Api-Key {self.secret}'),
        ))
        try:
            event_type, alternatives = resp.WhichOneof('Event'), None
            if event_type == 'partial' and len(resp.partial.alternatives) > 0:
                alternatives = [a.text for a in resp.partial.alternatives]
            if event_type == 'final':
                alternatives = [a.text for a in resp.final.alternatives]
            if event_type == 'final_refinement':
                alternatives = [a.text for a in resp.final_refinement.normalized_text.alternative]
        except grpc._channel._Rendezvous as err:
            print(f'Error code {err._state.code}, message: {err._state.details}')
            raise err
        if not alternatives:
            alternatives = ''
        self.send(text_data=alternatives)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant