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
}
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);
}
);
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);
}
);
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 occured: " + err);
}
);
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.