背景视频直播现在如此火爆,搭建在线直播间涉及到哪些技术?视频直播由主持人的直播终端和观众的观看终端组成。一个简单的查看器至少应该包括一个播放器和一个聊天室。下面将围绕这两个模块介绍相关技术。视频直播视频直播可分为视频采集、预处理、编码打包、传输、解封装解码、回放。直播端通过硬件设备采集音视频数据,经过预处理、编码、打包后,也传输给收看端。这一步一般由CDN中继完成。推流器将视频流推送到源站,CDN从源站拉流。拉流成功后,会被编码封装成不同的格式,供各个观看端播放。一个简单的示意图如下:接下来说一下观看端的基本要求:稳定的多端观看、无卡顿、低延迟、高并发。浏览器、小程序、PC浏览器、PC客户端。PC浏览器一般支持IE8。而且,由于Chrome浏览器默认屏蔽Flash,所以在PC端浏览器采用的策略是:在兼容H5的浏览器中优先使用H5播放,否则降级使用Flash播放。两者支持的直播播放视频格式的区别如下:Flash支持rtmp或http-flv直播。延迟约3秒。H5支持M3u8直播。延迟约15秒。直播视频卡顿的原因可能有很多,包括直播端、网络、观看端。直播端的主要问题是硬件配置太低、推流参数配置问题、音视频时间戳不同步。可以通过以下措施解决:升级硬件和软件设置,提高兼容性和容错性(这部分是硬件安装,必须有好的设备才能有好的流媒体质量)。使用硬编码方案充分利用GPU加速。降低视频码率,选择流畅、标清或使用动态码率推流。网络的主要问题是网络抖动,流媒体服务器和观看端之间的链路太长,可以通过以下措施解决:选择稳定的运营商网络,合理安排CDN节点。使用足够的网络带宽。观看端在网上看视频的时候,缓存就是在你看视频的时候预先存储一部分视频数据,等数据达到一定量后再播放画面,让播放更流畅。设置太小,在网络不稳定的情况下,将无法流畅连续播放;如果设置太大,会累积延时。所以设置一个适度的缓冲区。//FlashnetStream.bufferTime=1//单位:秒//FLV.jsflvjs.createPlayer({type:'flv',isLive:true,url:'video.flv'},{stashInitialSize:120//默认:384KB})低延迟、高并发我们知道,视频其实是由一帧一帧的图像组成的。RTMP基于TCP不会丢包,所以当网络状况不佳时,服务器会缓存数据包。当网络状况良好时,会一起发送到观看端,导致观看端积累过多的视频帧数据,延迟会随着时间的推移而增加。对于这个问题,除了上面提到的设置合适的缓冲长度外,还可以通过添加追帧和丢帧操作来实现播放追赶。Flash代码://Flash实现追帧:定时器轮询检测到当前buffer长度大于30秒,重新连接,重新拉取直播流netStream.bufferTimeMax=0.1//设置bufferTimeMax主动追帧if(netStream.bufferLength>30){//缓冲区长度大于30,重新连接reconnectStream()}H5代码://H5实现追帧,判断当前缓冲区结束时间与当前时间差超过5秒,然后追帧if(video.buffered.length>0&&video.buffered.end(0)-video.currentTime>5){//如果直播时间接近缓冲时间,则易画面冻结,所以为了安全起见-1secondvideo.currentTime=video.buffered.end(0)-1;}此外,如果你使用FLV.js播放视频,你可以启用它的Worker特性,multi-线程解析以优化延迟,并减少缓冲区。//FLV.jsflvjs.createPlayer({type:'flv',isLive:true,url:'video.flv'},{enableWorker:true,enableStashBuffer:false,stashInitialSize:120//default:384KB})即时聊天室聊天IM服务既要保证实时性和可靠性,又要抗高并发。在实现过程中,我们采用以下方法解决。1、首选WebSocket作为传输方式。如果不支持,它将降级为轮询。constio=require('socket.io')({"transports":['websocket','polling']})2.Node.js服务端由于消息并发度高导致性能低下。通过以下解决方案大大优化了聊天室的稳定性和可靠性。(1)使用命名空间的函数命名空间的作用是将消息的传播限制在一定范围内。对于一些不需要全局接收的消息,增加命名空间可以大大节省资源传输。//创建命名空间constio=require('socket.io')()constadminNamespace=io.of('/admin')adminNamespace.to('level1').emit('anevent',{some:'data'})(2)聊天消息队列当观众进入聊天室时,会广播登录消息。比如房间里同时有2W个人,每个登录的人都会向房间里的所有人广播“我”,相当于发送了2W条消息。如果并发量很大,对服务器性能要求极高。使用聊天队列批量显示消息,可以避免同时处理大量消息,提高处理性能。//消息队列letscoektMsgArr=[{EVENT:'SPEAK',uid:socketId,content:'Thisisthefirstchatmessage'},...]letminCount=0setInterval(()=>{constmaxCount=minCount+100constnewScoektMsgArr=scoektMsgArr.slice(minCount,maxCount)newScoektMsgArr.forEach((item)=>{socket.emit('message',JSON.stringify(item))})},1000)(3)服务器弹性缩放是最后一个大动作。能优化的已经尽量优化了。剩下的就是配置服务器扩(jia)(fu)伸(wu)缩(qi)。3.Dropout重连机制。断开连接会触发disconcent事件,只需监听它并创建套接字连接即可。心跳检测就是定时发送消息保持连接。//保持心跳setInterval(()=>{socket.emit('message',JSON.stringify({EVENT:'HEARTBEAT',uid:socketId}))},30*60*1000)//断开并重新连接socket.on('disconnect',()=>{this.connect()})connect(){socket.on('connect',()=>{//TODO})}POLYVSDK快速搭建在线直播room上面说了,搭建直播间需要考虑的细节很多,包括采集推送、CDN分发、播放体验优化、聊天室性能优化等等,不用着急,你可以快速搭建一个直播间通过调用POLYVSDK。(需要免费注册账号才能使用POLYV视频直播服务)STEP1嵌入播放器:
