時(shí)上傳實(shí)戰(zhàn)指南,錄音未結(jié)束就開(kāi)始發(fā)送數(shù)據(jù))
邊錄邊傳audio-recorder-polyfill timeslice 分片實(shí)時(shí)上傳實(shí)戰(zhàn)指南錄音未結(jié)束就開(kāi)始發(fā)送數(shù)據(jù)【免費(fèi)下載鏈接】audio-recorder-polyfillMediaRecorder polyfill to record audio in Edge and Safari項(xiàng)目地址: https://gitcode.com/gh_mirrors/au/audio-recorder-polyfillaudio-recorder-polyfill是一個(gè) MediaRecorder 音頻錄音 polyfill讓 Edge 和 Safari 也能錄制聲音。它的timeslice參數(shù)能把錄音按固定毫秒切片通過(guò)dataavailable事件實(shí)時(shí)吐出音頻片段——你可以在錄音結(jié)束前就開(kāi)始上傳數(shù)據(jù)這就是邊錄邊傳。本文是一份面向新手的實(shí)戰(zhàn)指南帶你 3 步完成分片實(shí)時(shí)上傳。為什么需要 timeslice 分片上傳傳統(tǒng)做法是錄完整個(gè)文件 → 拿到一個(gè)大 Blob → 一次性上傳。問(wèn)題很明顯? 長(zhǎng)錄音要等錄完才能上傳用戶(hù)干等 整段音頻存在內(nèi)存里長(zhǎng)錄音容易卡頓 網(wǎng)絡(luò)中斷時(shí)整次上傳全部作廢沒(méi)有斷點(diǎn)timeslice的思路是流水線化每 N 毫秒就從錄音器里倒出一段音頻立刻發(fā)往服務(wù)器。錄制、編碼、上傳三件事并行進(jìn)行總耗時(shí)大幅縮短。官方推薦做法直接寫(xiě)在 README.md 里If you need to upload record to the server, we recommend usingtimeslice.timeslice 分片是如何工作的原理并不復(fù)雜核心邏輯在 index.js 的start(timeslice)方法中start()不傳參數(shù) → 錄完為止只在stop()時(shí)一次性派發(fā)dataavailablestart(timeslice)傳毫秒數(shù) → 內(nèi)部用setInterval定時(shí)調(diào)用requestData()每次requestData()通知 Web Worker 編碼器把已緩存的音頻數(shù)據(jù)打包dump編碼后的 Blob 通過(guò)dataavailable事件交給你的回調(diào)對(duì)應(yīng)源碼片段index.js 第 102~106 行附近if (timeslice) { this.slicing setInterval(() { if (this.state recording) this.requestData() }, timeslice) }?? 注意細(xì)節(jié)暫停pause期間不會(huì)分片。setInterval仍在跑但只有state recording才會(huì)真正請(qǐng)求數(shù)據(jù)恢復(fù)錄制后繼續(xù)分片。另外stop()時(shí)會(huì)最后再調(diào)用一次requestData()把剩余的音頻榨干保證收尾片段不丟失隨后自動(dòng)清除定時(shí)器。3 步接入分片實(shí)時(shí)上傳第 1 步請(qǐng)求麥克風(fēng)并創(chuàng)建錄音器navigator.mediaDevices.getUserMedia({ audio: true }).then(stream { recorder new MediaRecorder(stream) })第 2 步監(jiān)聽(tīng)dataavailable收到片段立即上傳// 每隔 1 秒執(zhí)行一次參數(shù)是這一段音頻文件 recorder.addEventListener(dataavailable, e { sendNextPiece(e.data) // 在這里發(fā) fetch / XHR 到服務(wù)器 })第 3 步帶 timeslice 啟動(dòng)錄音// 每秒倒出一份音頻數(shù)據(jù) recorder.start(1000)就這樣錄音剛進(jìn)行 1 秒第一片數(shù)據(jù)已經(jīng)在路上了。項(xiàng)目自帶的在線演示里就有這個(gè)交互參考 test/demo/index.js 中startRecording(parts)分支——點(diǎn)Record by 1 second按鈕即可體驗(yàn)每秒一個(gè)audio/wav片段的分片效果演示頁(yè)面結(jié)構(gòu)見(jiàn) test/demo/index.pug。分片拼接WAV 與 MP3 的差別上傳分片后服務(wù)端需要把它們拼回完整音頻格式選擇很關(guān)鍵編碼器分片行為服務(wù)端拼接方式WAV默認(rèn)每片都是帶頭部的獨(dú)立文件去掉后 N-1 片的 44 字節(jié) WAV 頭依次拼接數(shù)據(jù)MP3mpeg-encoder每片是獨(dú)立 MP3 幀直接按序追加字節(jié)即可WAV 默認(rèn)編碼快、體積大見(jiàn) wave-encoder/index.js想要更好的壓縮率可切換到 MP3 編碼器見(jiàn) mpeg-encoder/index.jsimport mpegEncoder from audio-recorder-polyfill/mpeg-encoder AudioRecorder.encoder mpegEncoder AudioRecorder.prototype.mimeType audio/mpeg這是官方 README.md 中Limitations一節(jié)明確說(shuō)明的行為WAV 的timeslice分片每次都帶文件頭而原生 MediaRecorder 只在第一片帶頭——寫(xiě)服務(wù)端拼接邏輯時(shí)要記住這一點(diǎn)。timeslice 值怎么選4 個(gè)實(shí)用建議1000ms 起步官方示例就用 1 秒單片 WAV 約幾十 KBMP3 更小傳輸壓力輕?追求低延遲可降到 500ms但分片更碎服務(wù)端請(qǐng)求數(shù)翻倍弱網(wǎng)環(huán)境建議配合失敗重試某片上傳失敗時(shí)單獨(dú)重發(fā)該片即可不必整段重來(lái)測(cè)試分片時(shí)序可參考 test/index.test.js 中supports slicing in start method用例start(500)后驗(yàn)證每秒恰好收到 2 片、暫停期間不分片、stop()后再收到最后一片常見(jiàn)問(wèn)題FAQQdataavailable的e.data可以直接預(yù)覽嗎可以。演示代碼用URL.createObjectURL(e.data)把每片轉(zhuǎn)成audio播放見(jiàn) test/demo/index.js 的saveRecord函數(shù)。Q瀏覽器不支持怎么辦先檢查MediaRecorder.notSupported為不支持 Web Audio API 的瀏覽器顯示提示這也是官方 Usage 一節(jié)的第一步。Qpolyfill 體積大嗎很小——gzip 后約 1.1 KB、零依賴(lài)且通過(guò)inline worker把 Web Worker 內(nèi)聯(lián)進(jìn)同一個(gè)文件無(wú)需額外加載 worker 腳本。小結(jié)recorder.start(timeslice)一個(gè)參數(shù)即可把錄完再傳變成邊錄邊傳每片獨(dú)立dataavailable事件天然支持逐片重試、弱網(wǎng)續(xù)傳服務(wù)端拼接前務(wù)必區(qū)分 WAV去頭拼接與 MP3直接追加兩種格式掌握timeslice你的語(yǔ)音聊天、實(shí)時(shí)聽(tīng)寫(xiě)、語(yǔ)音客服類(lèi)產(chǎn)品就能少一個(gè)請(qǐng)等待上傳的轉(zhuǎn)圈圖標(biāo) ?【免費(fèi)下載鏈接】audio-recorder-polyfillMediaRecorder polyfill to record audio in Edge and Safari項(xiàng)目地址: https://gitcode.com/gh_mirrors/au/audio-recorder-polyfill創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考