本篇文章小编给大家分享一下HTML5实时语音通话聊天MP3压缩传输3KB每秒解析,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。
一、把玩方法
准备局域网内两台设备(Peer A、Peer B)用最新版本浏览器(demo未适配低版本)分别打开demo页面 (也可以是同一浏览器打开两个标签)
勾选页面中的H5版语音通话聊天,在Peer A中点击新建连接
把Peer A的本机信手动复制传输给Peer B,粘贴到远程信息中,并点击确定连接
把Peer B自动生成的本机信息手动复制传输给Peer A,粘贴到远程信息中,并点击确定连接 双方P2P连接已建立,使用页面上方的录音功能,随时开启录音,音频数据会实时发送给对方
局域网H5版对讲机:joy:
二、技术特性
(1)数据传输
github demo中考虑到减少对服务器的依赖,因此采用了WebRTC P2P传输功能,无需任何服务器支持即可实现局域网内的两个设备之间互相连接,连接代码也算简单。有服务器支持可能就要逆天了,不过代码也会更复杂。
如果正式使用,可能不太会考虑使用WebRTC,用WebSocket通过服务器进行转发可能是最佳的选择。
WebRTC局域网P2P连接要点( 实际代码 其实差不多,只不过多做了点兼容):
/******Peer A(本机)******/ var peerA=new RTCPeerConnection(null,null) //开启会话,等待远程连接 peerA.createOffer().then(function(offer){ peerA.setLocalDescription(offer); peerAOffer=offer; }); var peerAICEList=[......] //通过peerA.onicecandidate监听获得所有的ICE连接信息候选项,如果有多个网络适配器,就会有多个候选 //创建连接通道对象,A端通过这个来进行数据发送 var peerAChannel=peerA.createDataChannel("RTC Test"); /******Peer B(远程)******/ var peerB=new RTCPeerConnection(null,null) //连接到Peer A peerB.setRemoteDescription(peerAOffer); //开启应答会话,等待Peer A确认连接 peerB.createAnswer().then(function(answer){ peerB.setLocalDescription(answer); peerBAnswer=answer; }); //把Peer A的连接点都添加进去 peerB.addIceCandidate(......peerAICEList) var peerBICEList=[......] //通过peerB.onicecandidate监听获得所有的ICE连接信息候选项,如果有多个网络适配器,就会有多个候选 var peerBChannel=... //通过peerB.ondatachannel得到连接通道对象,B端通过这个来进行数据发送 /*******最终完成连接********/ //连接到Peer B peerA.setRemoteDescription(peerBAnswer); //把Peer B的连接点都添加进去 peerA.addIceCandidate(......peerBICEList) /* peerA peerB分别等待peerA/BChannel.onopen回调即完成P2P连接 ,然后通过监听peerA/BChannel.onmessage获得对方发送的信息 ,通过peerA/BChannel.send(data) 发送数据。 */
(2)音频采集和编码
由于是在我的 Recorder库 中新加的demo,因此音频采集和编码都是现成的,Recorder库有好的兼容性和稳定性,因此节省了最大头的工作量。
编码最佳使用MP3格式,因为此格式已优化了实时编码性能,可做到边录边转码,16kbps 16khz的情况下可做到2kb每秒的文件大小,音质还可以,实时传输时为3kb每秒,15分钟大概3M的流量。
用wav格式也可以,不过此格式编码出来的数据量太大,16位 16khz接近50kb每秒的实时传输数据,15分钟要37M多流量。其他格式由于暂未对实时编码进行优化,使用中会导致明显卡顿。
降噪、静音检测等高级功能是没有的,毕竟是非专业人员:joy: 要求高点可以,但不要超出范围太多啦。
(3)音频实时接收和播放
接收到一个音频片段后,本应该是立即播放的,但由于编码、网络传输导致的延迟,可能上个片段还未播放完(甚至未开始播放),因此需要缓冲处理。
因为存在缓冲,就需要进行实时同步处理,如果缓冲内积压了过多的音频片段,会导致语音播放滞后太多,因此需要适当进行对数据进行丢弃,实测发现网络正常、设备性能靠谱的情况下基本没有丢弃的数据。
然后就是播放了,本应是播完一个就播下一个,测试发现这是不靠谱的。因为结束一个片段后再开始播放下一个发出声音,这个过程会中断比较长时间,明显感觉得出来中间存在短暂停顿。因此必须在片段未播完时准备好下一个片段的播放,并且提前开始播放,达到抹掉中间的停顿。
我写了两个播放方式:
实时解码播放
双Audio轮换播放
最开始用一个Audio停顿感太明显,因此用两个Audio轮换抹掉中间的停顿,但发现不同格式Auido播放差异巨大,播放wav非常流畅,但播放mp3还是存在停顿(后面用解码的发现是得到的PCM时长变长了,导致事件触发会出现误差,为什么会变长?怪异)。
因此后面写了一个解码然后再播放,mp3这次终于能正常连续播放了,wav格式和双Audio的播放差异不大。实时解码里面也用到了双Audio中的技巧,其实也是用到了两个BufferSource进行类似的轮换操作,以抹掉两个片段间的停顿。
不过最终播放效果还是不够好,音质变差了点,并且多了点噪音。如果有现成的播放代码拿过来用就就好了。
三、应用场景
数据传输改成WebSocket,做个仿微信语音通话H5版还是可以的(受限于Recorder浏览器支持)
局域网H5版对讲机(前端玩具)
......没有想到 完。
太极熊猫2百度版 安卓版v1.7.1
下载黎明觉醒应用宝版 安卓版v1.111.1
下载暗影格斗3国际版 (Shadow Fight 3)最新版v1.40.3
下载王者战魂华为版 安卓版v3.6.1
下载放置魔法学院免广告版 v2.9.5
放置魔法学院内置Mod菜单是游戏的破解版本,在该版本中为玩家
万乘之国qq版本 安卓版v1.0.5
万乘之国qq版本是一款极具魅力的策略游戏,玩家们可以通过不同
动物餐厅国际服无限内购版 v12.9
动物餐厅国际服免广告版是游戏的破解版本,在该版本中为玩家去除
欧洲卡车司机 安卓版v3.2
欧洲卡车司机是款模拟经营游戏,这款游戏的画面还是蛮逼真的,给
疯狂大酒店 (Grand Hotel Mania)最新中文版v4.10.0.20
疯狂大酒店(Grand Hotel Mania)是一款好玩的