当前位置: 首页 > Web前端 > HTML5

HTML5实时语音通话聊天,MP3压缩传输每秒3KB

时间:2023-04-05 18:30:22 HTML5

自RecorderH5GitHub开源库优化后,支持录音转码成语音小文件实时上传到服务器的操作非常棒好,所以之前不太好支持的H5语音通话已经有了更好的突破空间。因此,花了两个晚上的时间搭建了一个H5语音通话聊天的demo。欢迎在线玩:https://xiangyuecn.github.io/Recorder/1.怎么玩在局域网内准备两台设备(PeerA,PeerB)用最新版本的浏览器打开demo页面(demo是低版本不适配)(也可以在同一个浏览器打开两个tab)查看页面语音通话聊天H5版本,点击PeerA中的NewConnection,手动将PeerA的本地消息复制转发给PeerB,并将其粘贴到远程消息中。然后点击确定连接,手动将PeerB自动生成的本地信息复制传输给PeerA,粘贴到远程信息中,点击确定连接。双方的P2P连接已经建立。实时发送到对方局域网H5版对讲机?2.技术特点(1)数据传输githubdemo考虑减少对服务器的依赖,所以采用WebRTCP2P传输功能,无需任何服务器支持即可实现局域网内的两台设备相互连接,并且连接代码也算简单。有服务器支持,可能会逆天,但是代码会比较复杂。如果是正式使用的话,可能不会考虑使用WebRTC,用WebSocket通过服务器转发可能是最好的选择。WebRTC局域网P2P连接要点(实际代码其实差不多,只是更兼容):/******PeerA(本机)******/varpeerA=newRTCPeerConnection(null,null)//打开session等待远程连接.onicecandidate监听获取所有ICE连接信息候选。如果有多个网卡,就会有多个候选//创建连接通道对象,A通过这个发送数据varpeerAChannel=peerA.createDataChannel("RTCTest");/******PeerB(remote)******/varpeerB=newRTCPeerConnection(null,null)//连接到PeerApeerB.setRemoteDescription(peerAOffer);//开启应答会话,等待PeerA确认连接peerB.createAnswer().then(function(answer){peerB.setLocalDescription(answer);peerBAanswer=answer;});//将PeerA的所有连接点添加到peerB.addIceCandidate(......peerAICEList)varpeerBICEList=[...]//通过peerB.onicecandidate监听获取所有ICE候选连接信息。如果有多个网络适配器,将有多个候选varpeerBChannel=..。//通过peerB.ondatachannel获取连接通道对象,B端通过this发送数据);//将PeerB的所有连接点添加到peerA.addIceCandidate(...peerBICEList)/*peerApeerB分别等待peerA/BChannel.onopen回调完成P2P连接,然后通过监听peerA/BChannel.onmessage获取对方发送的信息,通过peerA/BChannel.send(data)发送数据*/(2)audioAcquisitionandencoding是我的Recorder库里新加的demo,所以audio的采集和编码是现成的。Recorder库具有良好的兼容性和稳定性,因此节省了最大头的工作量。最好使用MP3格式进行编码,因为这种格式优化了实时编码性能,可以边录边转码。在16kbps16khz的情况下,可以达到每秒2kb的文件大小。音质还不错,实时传输3kb/s,15分钟3M流量左右。也可以使用wav格式,但是这种格式编码的数据量太大,16位16khz实时传输数据接近每秒50kb,15分钟需要37M以上的流量。由于其他格式没有针对实时编码进行优化,因此在使用过程中会造成明显的卡顿。不提供降噪和静音检测等高级功能。毕竟是非专业的?要求高一点可以,但不要越界太多。(3)实时音频接收和播放收到一个音频片段后,应该立即播放,但是由于编码和网络传输造成的延迟,之前的片段可能还没有播放(甚至开始),所以缓冲需要处理。由于缓存的存在,需要实时同步处理。如果缓存中积累的音频片段过多,语音播放会非常滞后,需要适当丢弃数据。实际测试发现网络正常,设备性能可靠。基本上没有丢弃的数据。然后就播放了。本来是播完一播就播下一播的。测试发现这是不可靠的。因为一段结束后才播放下一个声音,所以这个过程会中断很长时间,很明显中间有一个短暂的停顿。因此,需要在一段播放完之前为下一段的播放做准备,提前开始播放,消除中间的停顿。我写了两种播放方式:双Audio旋转播放的实时解码和播放。一开始觉得一个Audio的停顿太明显,所以用两个Audio旋转来抹去中间的停顿,但是发现不同格式的Audio播放差别很大,wav播放很流畅,但是播放mp3还是有停顿(后来使用解码发现获取到的PCM时长变长了,导致事件触发错误,为什么变长了?奇怪)。因此,我写了一个解码器,稍后播放。这次终于可以连续播放mp3了。wav格式和dualAudio的播放差别不大。DualAudio技术也被用于实时解码。其实就是用两个BufferSources做类似的旋转操作,抹去两个clip之间的停顿。但最终播放效果还是不够好,音质变差了一点,噪音也多了一点。如果有现成的播放代码可以使用就好了。3.应用场景数据传输改成WebSocket,还是可以仿微信语音通话H5版(受Recorder浏览器支持限制)局域网H5版对讲机(前端玩具)...我没有'别想了。