在后端使用 Azure Speechsdk.transcription.ConversationTranscriber 处理来自 Web 应用程序的数据时出现问题

问题描述 投票:0回答:1

我正在尝试实现如下流程:

  • JS Web 应用程序使用 WebAudio API 持续捕获音频(getUserMedia,然后处理 MediaRecorder)
  • MediaRecorder 将单通道音频作为二进制流通过 Websockets 连续发送到 python 后端
  • Python websocekt 后端使用 python SDK (speechsdk.transcription.ConversationTranscriber) 将音频发送到 Azure 认知语音服务

即使尝试捕获编解码器(通过指定 MediaRecorder 的 mimeType)和配置 ConversationTranscriber(通过指定pepeatsdk.audio.AudioStreamFormat 实例的wave_stream_format 或compressed_audio_format)的多种组合,我也无法使此配置工作。

我尝试了 OGG/OPUS 编解码器并将其传递到语音 API,但它似乎无法识别(我得到的结果是检测到空文本)。

现在我正在考虑在前端捕获纯 PCM 音频,然后将其即时转码为 ConversationTranscriber 接受的 MP3 的选项。

ConversationTranscriber Python SDK 文档对可以使用的确切格式的描述有限。

我正在寻找前端编解码器、ConversationTranscriber 的 AudioStreamFormat 配置以及可能一些可以使整个设置正常工作的后端音频处理的正确组合的建议。

[编辑]

看起来 Speech API 可以使用的音频格式与 MediaRecorder 生成的格式之间不兼容。

语音 API 可以消化:WAV/PCM、MP3、OGG 容器中的 OPUS、WAV 容器中的 FLAC、ALAW、WAV 容器中的 MULAW、MP4

MediaRecorder 能够生成: WebM 容器中的 OPUS、WebM 容器中的 PMC(使用 RecordRTC 库)

这里的主要问题是如何将 WebM 容器转换为 WAV、OGG、MP4 中的任何一种。 FFmpeg 不是这里的解决方案,因为它太慢并且不支持分块/连续转码。

speech-recognition web-audio-api azure-cognitive-services azure-speech
1个回答
0
投票

我正在寻找前端编解码器、ConversationTranscriber 的 AudioStreamFormat 配置以及可能一些可以使整个设置正常工作的后端音频处理的正确组合的建议。

使用 WebAudio API 捕获 PCM 格式的音频。设置 MediaRecorder 来捕获 PCM 音频流。检查采样率和位深度是否适合语音识别任务(通常为 16 kHz 采样率和 16 位深度)。

前端:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Audio Transcription</title>
</head>
<body>
    <button onclick="startRecording()">Start Recording</button>
    <button onclick="stopRecording()">Stop Recording</button>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/lamejs/1.2.0/lame.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/libopus.js/dist/opus-stream-decoder.min.js"></script>
    <script>
        let mediaRecorder;
        let audioChunks = [];

        async function startRecording() {
            const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
            mediaRecorder = new MediaRecorder(stream);

            mediaRecorder.ondataavailable = event => {
                audioChunks.push(event.data);
            };

            mediaRecorder.onstop = () => {
                const webmBlob = new Blob(audioChunks, { type: 'audio/webm' });
                transcodeToMP3(webmBlob);
            };

            mediaRecorder.start();
        }

        function stopRecording() {
            mediaRecorder.stop();
        }

        function transcodeToMP3(webmBlob) {
            const reader = new FileReader();
            reader.onloadend = function() {
                const opusData = new OggOpusDecoder().decode(new Uint8Array(reader.result));
                const mp3encoder = new lamejs.Mp3Encoder(1, 16000, 128); // Mono, 16 kHz sample rate, 128 kbps
                const mp3Data = mp3encoder.encodeBuffer(opusData);
                sendAudioToBackend(mp3Data);
            };
            reader.readAsArrayBuffer(webmBlob);
        }

        function sendAudioToBackend(mp3Data) {
            const ws = new WebSocket('ws://localhost:8765');
            ws.binaryType = 'arraybuffer';
            ws.onopen = function() {
                ws.send(mp3Data);
            };
        }
    </script>
</body>
</html>
  • 然后使用
    libopus.js
    lamejs
    将收集的音频块(WebM 格式)转码为 MP3。
  • 生成的 MP3 音频数据通过 WebSocket 发送到后端。
  • 您可以使用
    lamejs
    libmp3lame.js
    等 JavaScript 库进行浏览器内 MP3 编码。

后端:

import asyncio
import websockets
from azure.cognitiveservices.speech import SpeechConfig, ConversationTranscriber

async def process_audio(websocket, path):
    async for audio_data in websocket:
        # Configure ConversationTranscriber
        speech_config = SpeechConfig(subscription="your_subscription_key", region="your_region")
        speech_config.speech_recognition_language = "en-US"
        transcriber = ConversationTranscriber(speech_config)

        # Process audio stream
        result = await transcriber.recognize_once_async(audio_data)

        # Handle transcription result
        if result.reason == ResultReason.RecognizedSpeech:
            print("Recognized: {}".format(result.text))
        elif result.reason == ResultReason.NoMatch:
            print("No speech could be recognized")
        elif result.reason == ResultReason.Canceled:
            cancellation_details = result.cancellation_details
            print("Speech Recognition canceled: {}".format(cancellation_details.reason))
            if cancellation_details.reason == CancellationReason.Error:
                print("Error details: {}".format(cancellation_details.error_details))

start_server = websockets.serve(process_audio, "localhost", 8765)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
  • 从前端接收到音频数据后,将使用 Azure 认知语音服务进行处理以进行转录。
  • 转录结果打印到控制台。
© www.soinside.com 2019 - 2024. All rights reserved.