DEV Community

Juliano Sirtori
Juliano Sirtori

Posted on

Capturar, gravar e enviar um áudio no navegador

Atualmente, estou desenvolvendo uma POC para validar o desenvolvimento de um sistema que consiste em interagir com a inteligência artificial, algo semelhante a este site.

Neste artigo, demonstrarei como implementei a captura do microfone e utilizei a classe MediaRecorder para armazenar o áudio e enviá-lo para uma requisição RESTful na POC que estou desenvolvendo.

Capturando áudio pelo microfone

Primeiro, precisamos verificar se o navegador possui suporte ao microfone. Podemos fazer isso usando a seguinte condição:

if (navigator.mediaDevices.getUserMedia) {
    // possuui acesso
} else {
    // não possuui acesso
}
Enter fullscreen mode Exit fullscreen mode

Em seguida, vamos utilizar o método getUserMedia, passando como parâmetro a solicitação de entrada de áudio. Ao chamar essa função, será solicitada permissão ao navegador para capturar apenas o áudio do computador. Caso o usuário recuse, será lançado um erro. Se for aceito, será enviado um objeto MediaStream. Nosso código ficará desta maneira:

if (!navigator.mediaDevices.getUserMedia) {
    // não possuui acesso
    return;
}

navigator.mediaDevices.getUserMedia({ audio: true }).then(
    (stream) => {
        //Usuário deu permissão
    },
    (err) => {
        //Usuário não deu permissão
        console.error("The following error occured: " + err);
    }
);
Enter fullscreen mode Exit fullscreen mode

Armazenando o áudio no MediaRecorder

Assim que conseguimos permissão para capturar o áudio do navegador e recebermos o MediaStream, vamos utilizar o MediaRecorder para armazenar o nosso stream de dados.

Conforme a documentação do MDN, essa interface nos fornece alguns métodos. Para o nosso exemplo, vamos utilizar apenas 3: start, stop e requestData. Podemos implementar um botão para chamar esses métodos. Para obter mais detalhes sobre o MediaRecorder, você pode consultar diretamente a documentação: MediaStream Recording API. O nosso código vai ficar assim:

if (!navigator.mediaDevices.getUserMedia) {
    // não possuui acesso
    return;
}

navigator.mediaDevices.getUserMedia({ audio: true }).then(
    (stream) => {
        //Usuário deu permissão
        const mediaRecorder = new MediaRecorder(stream);
        mediaRecorder.ondataavailable = async (e) => {
            // aqui será chamado a nossa request
        }

        const micButton = document.querySelector(".mic-button");
        micButton.onclick = async () => {
            const pressed = micButton.getAttribute("aria-pressed") === "true";
            micButton.setAttribute("aria-pressed", !pressed);

            if (!pressed) {
                mediaRecorder.start();
                return;
            }
            mediaRecorder.stop();
        }

    },
    (err) => {
        //Usuário não deu permissão
        console.error("The following error occured: " + err);
    }
);
Enter fullscreen mode Exit fullscreen mode

Enviando áudio para uma API

Agora, falta apenas enviar esse áudio por meio de uma requisição. Para fazer isso, vamos criar um arquivo blob e enviá-lo através de um POST em FormData. Finalizando assim o nosso código:

if (!navigator.mediaDevices.getUserMedia) {
    // não possuui acesso
    return;
}

navigator.mediaDevices.getUserMedia({ audio: true }).then(
    (stream) => {
        //Usuário deu permissão
        const mediaRecorder = new MediaRecorder(stream);
        mediaRecorder.ondataavailable = async (e) => {
            const blob = new Blob([e.data], { type: "audio/mp3" });
            const formData = new FormData();
            formData.append("audio", blob, "recording.mp3");
            const response = await fetch("http://localhost:3001/transcribe", {
                method: "POST",
                body: formData,
            });
            // resto da implementação...
        }

        const micButton = document.querySelector(".mic-button");
        micButton.onclick = async () => {
            const pressed = micButton.getAttribute("aria-pressed") === "true";
            micButton.setAttribute("aria-pressed", !pressed);

            if (!pressed) {
                mediaRecorder.start();
                return;
            }
            mediaRecorder.stop();
        }

    },
    (err) => {
        //Usuário não deu permissão
        console.error("The following error occurred: " + err);
    }
);
Enter fullscreen mode Exit fullscreen mode

Conclusão

Demonstramos acima como capturar, gravar e enviar um áudio. Você pode visualizar o código completo neste link: poc-talk-ai. Em caso de dúvidas ou sugestões, sinta-se à vontade para deixá-las nos comentários abaixo.

Até mais e obrigado pelos peixes.

Top comments (0)