Skip to content

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

@Banzaika

Description

@Banzaika

Здравствуйте, я плохо знаком с данным пакетом, поэтому прошу помощи у вас. Мне нужно написать бэкенд приложение на Джанго, который будет использоваться 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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions