0

在这个问题上碰壁:使用大多数相同的功能来进行 AWS Transcribe 流式传输。我已经包括了我认为可能导致问题的相关部分。

首先,我能够解组消息并且它看起来正确(标题都在那里并格式化) - 这让我相信我正确地创建了数据结构。这让我觉得我一定是对有效载荷进行了编码或编码不当。

与某些 aws 转录文档资源不同的注意事项。在 websocket 文档中,它显示了三个标头(八位字节流),但我将其删除以更符合 github 上的静态转录 websocket 示例(请参阅 getAudioEventMessage)。我尝试使用/不使用此标头格式化消息。

以下是我认为的相关代码部分。如果有人希望我扩展,我会附加额外的代码。

首先,我使用音频上下文拉入流,数据正在填充并且看起来正确。

const handleSuccess = function (stream) {
        const context = new AudioContext();
        const source = context.createMediaStreamSource(stream);
        const processor = context.createScriptProcessor(1024, 1, 1);
        source.connect(processor);
        processor.connect(context.destination);

        processor.onaudioprocess = function (e) {
            if (isRecording) {
                ProcessStream(e.inputBuffer);
            }
        }; 
};

在我的视图上点击记录按钮后,会触发一个事件,该事件会为我的 websocket 获取正确签名/格式化的 url,这运行良好,并且连接无缝发生。套接字被打开,并在处理音频数据时将其发送到下面的 ProcessStream。socket.send(message) 返回无法解码音频数据的响应。我经历过一些错误,例如无效的 Web 套接字框架等等。我的问题可能在于我如何处理audioChunk。

function ProcessStream(audioChunk) {
    var eventStreamMarshaller = new EventStreamMarshaller();
    var inputSampleRate = audioChunk.sampleRate;
    var transcribeSampleRate = 16000;
    var raw = audioChunk.getChannelData(0);
    if (raw == null) return; 
    var downsampledBuffer = downsampleBuffer(raw, inputSampleRate, transcribeSampleRate);
    var pcmEncodedBuffer = pcmEncode(downsampledBuffer); 
    var audioEventMessage = getAudioEventMessage(pcmEncodedBuffer);
    var message = eventStreamMarshaller.marshall(audioEventMessage);
   // console.log(eventStreamMarshaller.unmarshall(message));
    socket.send(message); 
}

这会在编组之前将音频事件消息格式化为 AWS Transcribe EventStream 规范。

function getAudioEventMessage(buffer) {
    return {
        headers: {
            ':event-type': {
                type: 'string',
                value: 'AudioEvent',
            },
            ':message-type': {
                type: 'string',
                value: 'event',
            },
        },
        body: buffer
    };
}

我现在没有使用 NodeJS,我不完全理解的一件事是在格式化事件消息之前完成的 Buffer.From(pcmEncodedBuffer) 调用。我已经尝试过 base64 编码并将其包装在 arrayBuffer 中,以及 nodejs 文档中对 Buffer.From(ArrayBuffer) 的描述中的其他一些内容。

错误:无法解码您提供的音频流。(错误的请求异常)。

附加功能:

function downsampleBuffer(buffer, inputSampleRate = 44100, outputSampleRate = 16000) {

    if (outputSampleRate === inputSampleRate) {
        return buffer;
    }

    var sampleRateRatio = inputSampleRate / outputSampleRate;
    var newLength = Math.round(buffer.length / sampleRateRatio);
    var result = new Float32Array(newLength);
    var offsetResult = 0;
    var offsetBuffer = 0;

    while (offsetResult < result.length) {

        var nextOffsetBuffer = Math.round((offsetResult + 1) * sampleRateRatio);

        var accum = 0,
            count = 0;

        for (var i = offsetBuffer; i < nextOffsetBuffer && i < buffer.length; i++) {
            accum += buffer[i];
            count++;
        }
        result[offsetResult] = accum / count;
        offsetResult++;
        offsetBuffer = nextOffsetBuffer;
    }
    return result;
}
function pcmEncode(input) {
    var offset = 0;
    var buffer = new ArrayBuffer(input.length * 2);
    var view = new DataView(buffer);
    for (var i = 0; i < input.length; i++, offset += 2) {
        var s = Math.max(-1, Math.min(1, input[i]));
        view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
    }
    return buffer;
}
4

0 回答 0