const getPcmBuffer = (bytes, simpleBits = 16)=> { // pcm buffer 數據 let offset = 0 const dataLength = bytes.length * (simpleBits / 8) const buffer = new ArrayBuffer(dataLength) const data = new DataView(buffer) for (let i = 0; i < bytes.length; i += 1, offset += 2) { const s = Math.max(-1, Math.min(1, bytes[i])) // 16位直接乘就行了 data.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true) } // return [data] return new Blob([data]) } const context = new AudioContext({ sampleRate: 8000, sampleBits: 16 }) navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia if (navigator.getUserMedia) { navigator.getUserMedia( // constraints { audio: { channelCount: 1, }, }, // successCallback (mediaStream) => { const sourceNode = context.createMediaStreamSource(mediaStream) const scriptNode = context.createScriptProcessor(512, 1, 1) sourceNode.connect(scriptNode) scriptNode.connect(context.destination) // 監聽錄音的過程 scriptNode.onaudioprocess = (event) => { if (ws.readyState === 1) { // websocket 推送數據 ws.send(getPcmBuffer(event.inputBuffer.getChannelData(0))) } } }, // errorCallback (err) => { console.log(`The following error occured: ${err}`) }, ) }