【笔记】从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

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