Skip to main content

website 自動語音辨識技術

ASR (Automatic Speech Recognition)

getUserMedia

navigator.mediaDevices.getUserMedia() 是一個 Web API,屬於瀏覽器中的 MediaDevices API,主要用途是存取使用者的攝影機、麥克風或其他媒體輸入裝置

基本語法

navigator.mediaDevices
.getUserMedia(constraints)
.then((stream) => {
// 成功取得媒體串流
})
.catch((error) => {
// 取得失敗的處理
});

回傳值

  • Promise
  • 成功時回傳 MediaStream 物件,可以用來當作 <video><audio>、WebRTC 之類 API 的來源。
navigator.mediaDevices
.getUserMedia({ video: true, audio: true })
.then((stream) => {
const video = document.querySelector("video");
video.srcObject = stream;
})
.catch((err) => {
console.error("取得媒體失敗:", err);
});

MediaRecorder

The MediaRecorder interface of the MediaStream Recording API provides functionality to easily record media. It is created using the MediaRecorder() constructor.

MediaRecorder.isTypeSupported("audio/mp3"); // return boolean 判斷是否可以 record 音檔類型

參考 MDN

new 出一個可以 recorder 的實體

mediaRecorder = new MediaRecorder(stream, {
mimeType: "audio/webm",
});

監聽在 data 生成的時候

let audioChunks = [];
mediaRecorder.addEventListener("dataavailable", (event) => {
console.log(event);
audioChunks.push(event.data);
console.log(audioChunks);
});

在停下 record 的時候,把 Blob 的檔案產生 url 讓畫面可以 play

mediaRecorder.addEventListener("stop", () => {
const audioBlob = new Blob(audioChunks, { type: mimeType });
const audioUrl = URL.createObjectURL(audioBlob);
audioPlayback.src = audioUrl;
audioPlayback.style.display = "block";
});

MP3

Website 沒有辦法直接可以用 lamejs 轉為 mp3

mediaRecorder.onstop = async () => {
const audioBlob = new Blob(audioChunks, { type: "audio/webm" });
console.log("轉換前檔案類型:", audioBlob.type);
console.log("轉換前檔案大小:", audioBlob.size, "bytes");

const arrayBuffer = await audioBlob.arrayBuffer();
const audioContext = new AudioContext();
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);

// 使用 lamejs 轉換為 MP3
const mp3encoder = new lamejs.Mp3Encoder(1, audioBuffer.sampleRate, 128);
const samples = audioBuffer.getChannelData(0);
const sampleBlockSize = 1152;
const mp3Data = [];

for (let i = 0; i < samples.length; i += sampleBlockSize) {
const sampleChunk = samples.slice(i, i + sampleBlockSize);
const mp3buf = mp3encoder.encodeBuffer(sampleChunk);
if (mp3buf.length > 0) {
mp3Data.push(mp3buf);
}
}

const end = mp3encoder.flush();
if (end.length > 0) {
mp3Data.push(end);
}

const mp3Blob = new Blob(mp3Data, { type: "audio/mp3" });
console.log("轉換後檔案類型:", mp3Blob.type);
console.log("轉換後檔案大小:", mp3Blob.size, "bytes");

const mp3Url = URL.createObjectURL(mp3Blob);

// 顯示音訊播放器
const audio = document.createElement("audio");
audio.controls = true;
audio.src = mp3Url;
audioContainer.innerHTML = "";
audioContainer.appendChild(audio);

// 提供下載連結
const downloadLink = document.createElement("a");
downloadLink.href = mp3Url;
downloadLink.download = "recording.mp3";
downloadLink.textContent = "下載 MP3";
audioContainer.appendChild(downloadLink);
};