Потоковое аудио в API речи Azure с помощью node.js в браузере - PullRequest
0 голосов
/ 11 января 2019

Я делаю демонстрацию речи к тексту с помощью API речи Azure в браузере от node.js. Согласно документу API здесь он указывает, что ему нужны файлы .wav или .ogg. Но пример внизу делает вызов API через отправку байтовых данных в API.

Итак, я уже получил свои данные с микрофона в виде байтового массива. Это правильный путь, чтобы преобразовать его в байт и отправить его в API? Или мне лучше сохранить его как файл .wav, а затем отправить в API?

Итак, мой код ниже.

Это поток с микрофона.


navigator.mediaDevices.getUserMedia({ audio: true })
    .then(stream => { handlerFunction(stream) })

function handlerFunction(stream) {
    rec = new MediaRecorder(stream);
    rec.ondataavailable = e => {
        audioChunks.push(e.data);
        if (rec.state == "inactive") {
            let blob = new Blob(audioChunks, { type: 'audio/wav; codec=audio/pcm; samplerate=16000' });
            recordedAudio.src = URL.createObjectURL(blob);
            recordedAudio.controls = true;
            recordedAudio.autoplay = true;
            console.log(blob);
            let fileReader = new FileReader();
            var arrayBuffer = new Uint8Array(1024);
            var reader = new FileReader();
            reader.readAsArrayBuffer(blob);
            reader.onloadend = function () {
                var byteArray = new Uint8Array(reader.result);
                console.log("reader result" + reader.result)
                etTimeout(() => getText(byteArray), 1000);
            }
        }
    }
}

Это часть вызова API


function getText(audio, callback) {
    console.log("in function audio " + audio);
    console.log("how many byte?: " + audio.byteLength)
    const sendTime = Date.now();
    fetch('https://westus.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=en-US', {
        method: "POST",
        headers: {
            'Accept': 'application/json',
            'Ocp-Apim-Subscription-Key': YOUR_API_KEY,
            // 'Transfer-Encoding': 'chunked',
            // 'Expect': '100-continue',
            'Content-type': 'audio/wav; codec=audio/pcm; samplerate=16000'
        },
        body: audio
    })
        .then(function (r) {
            return r.json();
        })
        .then(function (response) {
            if (sendTime < time) {
                return
            }
            time = sendTime
            //callback(response)
        }).catch(e => {
            console.log("Error", e)
        })
}

Возвращается с 400 (Bad Request) и говорит:

{Сообщение: «Неподдерживаемый аудиоформат»}

1 Ответ

0 голосов
/ 14 января 2019

Причина:

Обратите внимание, что вы не создаете MediaRecorder с audio/wav mimeType с помощью

new Blob(audioChunks,{type:'audio/wav; codec=audio/pcm; samplerate=16000'})

Это утверждение является только описанием для blob. Я тестирую свой Chrome (v71) с isTypeSupported:

MediaRecorder.isTypeSupported("audio/wav")  // return false
MediaRecorder.isTypeSupported("audio/ogg")  // return false
MediaRecorder.isTypeSupported("audio/webm") // return true

Похоже, что MediaRecorder будет записывать звук только в audio/webm. Кроме того, когда я запускаю следующий код в Chrome, значение по умолчанию rec.mimeType равно audio/webm;codecs=opus

rec = new MediaRecorder(stream);

В соответствии с требованиями к форматам аудио , audio/webm пока не поддерживается.

Подход:

Перед вызовом getText() нам нужно сначала преобразовать webm в wav. Есть довольно много библиотек, которые могут помочь нам сделать это. Я просто копирую Jam3-скрипт перед вашим кодом для преобразования webm в wav:

    // add Jam3's script between Line 2 and Line 94 or import that module as you like

    // create a audioContext that helps us decode the webm audio
    var audioCtx = new (window.AudioContext || window.webkitAudioContext)();

    rec = new MediaRecorder(stream,{
        mimeType : 'audio/webm',
        codecs : "opus",
    });

    // ...

    rec.ondataavailable = e => {
        audioChunks.push(e.data);
        if (rec.state == "inactive") {
            var blob = new Blob(audioChunks, { 'type': 'audio/webm; codecs=opus' });
            var arrayBuffer;
            var fileReader = new FileReader();
            fileReader.onload = function(event) {
                arrayBuffer = event.target.result;
            };
            fileReader.readAsArrayBuffer(blob);
            fileReader.onloadend=function(d){
                audioCtx.decodeAudioData(
                    fileReader.result,
                    function(buffer) {
                        var wav = audioBufferToWav(buffer);
                        setTimeout(() => getText(wav), 1000);
                    },
                    function(e){ console.log( e); }
                );
            };
        }
    }

И у меня это прекрасно работает:

enter image description here


В качестве дополнительного примечания я предлагаю вам использовать свой бэкэнд для вызова служб преобразования речи в текст . Никогда не вызывайте службу Azure stt в браузере . Это потому, что выставление ключа подписки на передний конец действительно опасно. Кто угодно может проверить сеть и украсть ваш ключ .

...