【筆記】從0開發瀏覽器上的語音聊天室系統

想着假期越來越久,那麼就開發一個語音聊天系統吧,正好熟悉熟悉modern browser的各種API吧。大家都“呆”在家裏,要不找點娛樂活動,寫點桌遊,既可以跟大家語音,又可以玩起來。今天,我們就來看看瀏覽器如何獲得錄音stream並傳輸數據給加入聊天室的clients吧。

上代碼先:https://github.com/stallpool/boga

先是抄一段人人都能的getUserMedia代碼獲取錄音stream(video爲false關)。之後如何獲取stream的raw data並進行傳輸呢?網上有很多方案,其中鋪天蓋地的都是RTCPeerConnection;看了一下,爲啥非要一個STUN server呢?STUN server的權限控制如何?太煩了,懶人不想管這些,不過你讓我用一個諸如Google host的公共的STUN server我還是不太喜歡,那麼自己解決數據傳輸的問題吧。最直接就是得到raw data,然後websocket傳就可以了。

第一個嘗試的方案當然是直接用現成的MediaRecorder。非常簡單,直接綁定錄音的stream,用dataavailable事件接數據就好了;不過這些數據是encode過的。我們接到這些數據之後當然是想辦法把它轉換成raw string傳到後端廣播。因爲它是chunks,所以傳輸了第一個chunk後第二個chunk當我直接使用audioContext的decodeAudioData的時候會拋出不能識別的錯誤。鬱悶,那還有什麼其他方法可以直接拿到raw data麼?

於是轉去試試polyfill裏的方法:https://github.com/ai/audio-recorder-polyfill 這是作者他自己寫了一個MediaRecorder,用wav編碼;不管什麼編碼,只要能拿到arrayBuffer就可以。它使用了一個方法得到一個可以監聽onaudioprocess事件的對象,好像並沒有什麼效果,而且查了下資料,發現這個東西已經deprecated了…

隨後還是回到MediaRecorder,既然第一個chunk可以被髮送到後端再廣播後仍然可以正確被decode,那麼有辦法了,我錄一段,然後把MediaRecorder幹掉重新new一個出來不就可以了,於是果然成功了…這個方法在desktop端完全沒有問題,到了手機端,firefox下有點卡頓,chrome還是不錯的。速度也還湊合,chrome錄音每秒生成的音頻文件webm大小也就6kb左右。

播放我就隨便寫寫,主要是考慮如果網絡差的話,需要給packet排個序,然後audioContext該播放啥就播放啥。具體recorder和player見 audio.js

先到這吧,本文也會不定期更新。去寫桌遊跟大家一起玩去了…
看來有必要去研究一下DNA程序了,想想如何解析ATGC吧;這次的2019-nCoV和以前的病毒類似的地方,是AT:GC大約爲2:1…
武漢加油!中國加油!

J.Y.Liu
2020.01.30

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章