前置知识
WebRTC前世今生
在线教育、在线会议、在线面试、在线社交、在线医疗、金融证券在线开户、智能家居都已经非常普及了,将常见的线下场景转至线上,而WebRTC就是实现这些场景的主要手段;
WebRTC的使命是使丰富、高质量的RTC应用程序可以为浏览器、移动平台和loT设备开发,并允许所有人通过一组通用的协议进行通信
WebRTC完成音视频通话需要了解四个模块:音视频采集、STUN/TURN服务器、信令服务器和端到端之间的P2P连接
- 常用API
- 获取可用的音视频设备
navigator.mediaDevices.enumerateDevices() //promise
- 音视频的采集
navigator.mediaDevices.getUserMedia() //promise- 在线demo
- 屏幕分享
navigator.mediaDevices.getDisplayMedia() // Promisestream.getVideoTracks()[0].addEventListener('ended', () => {}) //结束共享时触发- 在线demo
- 实现录制和下载
- 主要利用
MediaRecorderAPI,它可以监听到流数据,这样就可以将获取到的数据保存到数组中了,然后回放时设置到另一个Video标签的src属性即可 - 下载也是基于
MediaRecorderAPI录制的数据,转换成Blob后通过a标签触发下载 - 语法:
const mediaRecorder = new MediaRecorder(stream, {mimeType : 'video/webm'})
//录制视频 const recordedBlobs = [] navigator.mediaDevices.getUserMedia({video: true}) .then(function(stream) { const mediaRecorder = new MediaRecorder(stream, {type : 'video/webm'}); //监听录制结束事件 mediaRecorder.onstop = (event) => { console.log('录制结束: ', event); }; // 处理 dataavailable 事件,该事件可用于获取录制的媒体资源 mediaRecorder.ondataavailable = (event) => { console.log('handleDataAvailable', event); if (event.data && event.data.size > 0) { //吧获取的媒体数据放在数组中 //event.data是一个Blob对象,Blob 对象表示一个不可变、原始数据的类文件对象。 recordedBlobs.push(event.data); } }; //开始录制 mediaRecorder.start(); // `mediaRecorder.stop();` 播放录制的视频 })//将获取的recordedBlobs转成Blob类型 const blob = new Blob(recordedBlobs, {type : 'video/webm'}); //获取video元素 const recordedVideo = document.querySelector('video'); //blob 要经过 URL.createObjectURL 的处理,才能被播放。 recordedVideo.src = window.URL.createObjectURL(blob); recordedVideo.play();download.addEventListener('click', () => { const blob = new Blob(recordedBlobs, {type: 'video/webm'}); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.style.display = 'none'; a.download = 'record.webm'; a.click(); }); - 主要利用
- 获取可用的音视频设备
WebRTC解决的问题(主要相对于RTC)
- 互联网网络复杂
- 不同的NAT、防火墙对媒体P2P的建立带来了很大的挑战;而WebRTC为浏览器提供了端到端的直接通信;
- WebRTC技术包含了STUN、TURN、ICE、RTP-over-TCP的关键NAT和防火墙穿透技术,并支持代理
- WebRTC里面有P2P打洞的开源项目libjingle、支持STUN、TURN等协议
- 延时敏感
- 早期的RTC技术中,由于TCP技术的缺陷,只能需要UDP传输,需要开发者解决重传、乱序等问题
- WebRTC提供了NACK、PEC技术,不再需要通过服务器进行路由,减少了延迟和宽带消耗
- 直接通信可以提高数据传输和文件共享的速度
- 流畅性
- 网络中存在不稳定性,例如网络的抖动等问题,此时就需要一套自适应的算法来应对网络拥塞、平滑发送等问题
- WebRTC中提供了TCC+SVC+PACER+JitterBuffer等技术解决这些问题
- 语音清晰
- 由于终端设备和环境的问题,会有噪声、回声等干扰,WebRTC提供了3A算法+NetEQ,让实时环境中的声音处理以及互动体验得到了极大的提升
WebRTC的安全问题
所有WebRTC媒体数据都必须经过加密
WebRTC不是一个插件,也不依赖于任何插件,因此所有应用都可以在浏览器的沙箱中运行,并不用再额外创建新进程,正因为如此,WebRTC有效的阻止了恶意软件进入用户系统
- WebRTC的媒体处理
- 对于WebRTC的媒体处理上,已经使用了DTLS-SRTP技术,使用DTLS类似的SSL证书方式来协商加解密密钥,使用SRTP实现对于媒体(音视频)数据加密和完整性保护,实现媒体传输的安全保护
- 信令协商
- 也需要采取TLS/DTLS进行信令数据传输的保护,当然是取决于各厂商的具体实现方式(如HTTPS、SIPS)
- 针对信令服务器,其信令通信都是对互联网开放的,其受攻击的基本都是DOS/DDOS攻击(如TCP半链接攻击,HTTP Flood攻击),目的就是破坏性的让信令服务器无法提供服务
- 信令协议本身就有挺多的缺陷的,针对单用户的攻击,SIP这种通用的RTC协商信令协议,有很多方法可以使得攻击者将合法用户禁掉
- WebRTC潜在的危险
- 针对信令服务器
- 进行针对用户设备的DOS暴力破解攻击
- 攻击者快速频繁且反复地发送注册请求
- 伪造报文将用户去注册
- 伪造结束报文非法结束用户的通话
- 针对媒体服务器/媒体终端
- 由于媒体地址和媒体端口都是通过SDP协商的,SDP消息如果被恶意篡改,就会导致媒体处理者的媒体报文自我循环,从而造成媒体处理方无法提供服务
- 终端与媒体服务器之间是加密的(如SRTP加密),但在媒体服务器中解密的处理会存在媒体明文暴露点,也就存在了安全风险
- 其他风险
- 交换公钥时存在被黑客截取到的风险
- WebRTC利用DTLS协议就可以有效的解决各端之间交换公钥时被窃取的问题
- 进行DTLS协商,交换公钥证书以及协商密码相关信息,同时通过fingerprint对证书进行验证,确认其没有在传输中被篡改
- 可以通过「指纹」的方式对证书进行加解密操作,实现数据的校验和验证
- 「指纹」是指:用来判断公钥证书在传递过程中有没有被篡改,进行证书完整性判断,通过哈希算法对证书内容进行计算从而获取到指纹
- 在获取到「指纹」后,在发送前需要进行指纹加密,生成数字签名,然后和公钥一起发送给对等端,对等端通过该公钥和对应的哈希算法进行解密,然后再对比从而判断证书是否正确
- WebRTC安全机制
- 但还有一个问题是不能确定对方是不是冒充的
- 解决该问题可以利用STUN协议进行身份认证,从而拦截黑客冒充的身份进行交互窃取信息
- 安全描述的作用
- 进行网络连通性检测时,对用户身份进行验证
- 收发数据时,对用户身份的认证,以免受到对方的攻击
- WebRTC利用DTLS协议就可以有效的解决各端之间交换公钥时被窃取的问题
- 交换公钥时存在被黑客截取到的风险
- 针对信令服务器
- WebRTC使用两种标准的加密协议
- 加密的首选方法是在DTLS(数据报传输层安全性)捂手中使用PFS密码来安全的交换关键数据
- 对于音视频传输,可以使用密钥数据生成AES(高级加密标准)密钥,然后由SRTP(安全实时传输协议)使用AES密钥对媒体进行加密和解密
- 数据报传输层安全性(DTLS)
- 浏览器内置的标准化协议。是基于传输层协议(TLP)的数据流加密
- 由于DTLS使用用户数据协议(UDP),因此保留了传输的语义
- 他是安全套接字层(SSL)的拓展,任何SSL协议均可用于保护WebRTC数据,从而允许端到端加密
- 安全实时传输协议(SRTP)
- 用于媒体流加密
- 是对实时传输协议(RTP)的拓展,该协议没有任何内置的安全性机制
- 为实时传输协议(RTP)提供加密、完整性保证和消息身份验证
- 但是不会对表头进行加密,只会对RTP数据包加密
- 加密的首选方法是在DTLS(数据报传输层安全性)捂手中使用PFS密码来安全的交换关键数据
可以说如果 WebRTC 直接拿过来商用的话,几乎是不太可能的,当下普遍的解决方案是自研,根据自身的业务场景进行二次定制开发,或者更简单一点使用第三方 SDK。Agora WebSDK 是基于 WebRTC 封装的API集合,极致简单,对开发者更加友好,能十行之内完成一个简单的 demo 并上线;
- 媒体协商拓展
- 基本步骤
- 呼叫端 Amy 创建 Offer(createOffer)并将 offer 消息(内容是呼叫端 Amy 的 SDP 信息)通过信令服务器传送给接收端 Bob,同时调用 setLocalDesccription 将含有本地 SDP 信息的 Offer 保存起来
- 接收端 Bob 收到对端的 Offer 信息后调用 setRemoteDesccription 方法将含有对端 SDP 信息的 Offer 保存起来,并创建 Answer(createAnswer)并将 Answer 消息(内容是接收端 Bob 的 SDP 信息)通过信令服务器传送给呼叫端 Amy
-
- 呼叫端 Amy 收到对端的 Answer 信息后调用 setRemoteDesccription 方法将含有对端 SDP 信息的 Answer 保存起来
- 完成P2P通信过程的媒体协商之后,通过信令服务器将各自的网络信息(Candidate)发送给对等端之后就可以打通P2P通信的网络通道,并通过监听onaddstream事件拿到对方的视频流进而完成整个过程的视频通话
- 基本步骤
即时通信(IM)和实时通信(RTC)
简介
即时通信(IM)和实时通信(声网Agora.io)都是一套网络通信系统,其本质都是对信息进行转发,其最大的特点就是对信息传递的时间规定
- 时通信(IM:Instant Messaging):是一个实时通信系统,终端服务,允许两人或多人使用网络实时传输的文字消息、文件、语音与视频交流;
- 本质是客户端与客户端进行消息的实时传递,技术基础就是基于Socket连接的实时数据读写
- 按使用用途分为:企业即时通信和网站即时通信
- 根据装载对象又可以分为手机即时通信和PC即时通信
- 主要的产品:钉钉、微信、QQ等以IM为核心的产品,其他的如在线游戏、社交应用 - 可以说IM系统是任何一个带有社交属性的应用需要具备的基础功能
- 最核心的部分是:消息系统
- 消息系统中最核心的功能是消息的同步、存储和检索
- 消息的同步
- 将消息完整的、快速的从发送方传递到接收方就是消息的同步
- 最重要的衡量标准就是消息传递的实时性、完整性以及可以支撑的消息规模
- 功能上来说:一般至少支持在线和离线推送,高级的IM系统还支持「多端同步」
- 消息的存储
- 即消息的持久化保存
- 传统的消息系统智能支持消息在接收端的本地存储,数据基本不具备可靠性
- 现代消息系统是支持消息的服务端的在线存储,功能上实现的就是「消息漫游」,「消息漫游」的好处就是可以实现账号在任一端登录都可以查看所有的历史消息
- 消息的检索
- 消息一般是文本格式呈现,所以一般是支持检索的功能,不管是传统的本地存储还是现在的在线存储检索
- 现代IM系统中的消息系统架构 - 架构篇
场景与需求点分析
- 即时通信
- 包括常见的文字聊天、语音消息发送、文件传输、音视频播放等
- 主要要求可靠,在意送达率
- 实时通信
- 场景包括语音、视频电话会议、网络电话等
- 主要要求低延时和接通率
相关技术、协议和解决方案
- 即时通信
- XMPP,MQTT
- 实时通信
- WebRTC、Tokbox
- 即时通信
- 消息发送和确认、「消息接入端、服务端消息逻辑处理、服务端消息缓存和存储、转发、服务端用户状态管理、心跳机制、消息发送端」、消息接受和确认
- 为了保证连接的可靠性、最常用的是TCP协议或者类TCP连接协议
- 造成的后果就是为了追求连接的可靠性、而造成延迟的不可控性
- TCP封装了消息的重传机制,在丢包的情况下,延时问题比较严重,甚至在超过30%丢包的情况下延时会达到几十分钟,甚至容易断开连接,而UDP还可以传输数据,TCP就无法进行实时通信了
- 实时通信
- 技术环节:采集、前处理、编码、「服务端接入、转发、服务端接入」解码、播放和渲染
- 声网Agora.io采用UDP作为基础传输协议,在设计低延时的实时通信服务时,UDP表现要比TCP好的多
WebRTC基本概念
- RTP协议
- 实时互动直播系统采用UDP进行传输,但一般在传输数据流的时候,并不直接将音视频数据交给UDP传输,而是先给音视频数据加个RTP头,然后再交给UDP进行传输
- WebRTC原生支持Web浏览器进行实时通信
- 实时通信数据包括语音、音视频、和任意其他类型的数据,无需下载任何插件
- 可以通过WebRTC传输任意数据,这个过程在WebRTC中的数据通道(data channel)中进行,当你需要在浏览器时间传输信息不通过任何服务器时(还是需要一个TURN服务器转发消息)就可以使用数据通道
- 数据通道可以配置成可靠或非可靠、有序或无序传输消息
- 数据通道的使用方法
- WebRTC是使用JavaScript API的媒体引擎
- WebRTC只是一个媒体引擎,其上层是JavaScript API
- WebRTC P2P发送数据原理
- P2P可以实现直接在浏览器之间发送数据
- 需要先通过信令服务器交换彼此的数据,目的是得到对方的网络信息
- 信令服务器用于交换三种类型的信息
- 会话控制消息:初始化/关闭,各种业务逻辑消息以及错误报告
- 网络消息:外部可以识别的IP地址和端口(ICE消息)
- 为了连接媒体通道,实现了ICE(有时需要通过TURN转发消息)
- ICE(Interactive Connectivity Establishment:交互式连接建立),可以整合各种NAT穿越的技术如STUN、TURN(Traversal Using Relay NAT 中继NAT实现的穿透)
- STUN服务器位于公网上,其做的事情就是获取自己的IP、Port和NAT信息,然后通过信令服务器交换这些信息,最后让两个客户端根据自己得到的IP、Port和NAT信息进行对应的穿透
- ICE会先使用STUN(NAT会话穿越应用程序-获取面向公众的IP地址),尝试建立一个基于UDP的连接,如果失败了就会去用TCP,还是失败时就会使用一个中继的TURN(中继穿透NAT)服务器
- ICE会尝试找到最好的路径来让用户端建立连接,或尝试所有可能的选项,然后选取最合适的
- 媒体能力:客户端能控制的编解码器、分辨率、以及想和谁通信(SDP信息)
- 信令一旦发送成功,就可以直接在两个浏览器之间发送消息,Web服务器不会获取到这些信息
- WebRTC需要通过网络进行两种类型的交互
- 信令传输
- 发生在HTTPS连接或者WebSocket上,通过JS代码实现
- 在信令中需要做的就是:用户找到彼此并开启对话
- 目前业界中使用较多的是WebSocket+JSON/SDP的方案,其中WebSocket用来提供信令传输通道,JSON/SDP用来封装信令的具体内容
- WebSocket建立在TCP之上,提供了长连接的能力,解决了HTTP仅支持半双工,header信息冗余等的低效问题
- SDP(Session Description Protocol)是一个会话描述协议,用来封装流媒体能力协商的信令内容,两个WebRTC代理会将建立连接所需的所有状态通过此协议来分享
- 协议是个标准/约定,而协议栈是协议的实现,可以理解为代码,函数库、供上层应用调用
- 传输媒体
- 需要用到媒体渠道(Media channels)、使用SRTP(用于语音和视频)和SCTP(用于数据通道)实现
- SCTP 与 SRTP被用于为多路复用、提供拥塞和流控制,以及部分在UDP之上提供部分可靠的传递和其他附加服务
- DTLS用于保护对端的数据传输
- 与信令不同,媒体选择了一条不同的路线在网络上传输,且表现也不尽相同
- 需要用到媒体渠道(Media channels)、使用SRTP(用于语音和视频)和SCTP(用于数据通道)实现
- 信令传输
- WebRTC处理媒体和视频
- WebRTC使用VoIP技术处理媒体,并将其通过网络发送,这一切都在SRTP(RTP的安全、加密版本)之上进行
- WebRTC的音频和视频使用编解码器中进行工作,编解码器用于压缩和解压缩视频和音频数据的已知算法
- WebRTC工作原理简述
- 可以实时发送音频、视频或者任意的数据
- 需要通过NAT穿越机制使得浏览器之间相互访问
- 有时,P2P必须经过中继服务器(TURN)
- 使用WebRTC需要考虑到信令和媒体,彼此分离
- 当然也可以通过媒体服务器实现P2P的相关功能,而非必须使用P2P
- 媒体服务器:当多人进行音视频通话时,常规的对等P2P通信就显得有点吃力,这时就需要通过媒体服务器来减少客户端需要接收或发送的数量,做中继作用
- WebRTC 媒体管理
相关工作原理
H.265在Web端的硬解支持
在旧版的Web端浏览器是不支持H.265的,但是其需求是一直存在,另一种解决方式是通过软解的方式进行播放,但是软解的方式对性能的损耗是比较严重的,因此一般都不支持H.265格式的编码;
在22年9月,Chrome发布了M106版本,默认开启H.265硬解,使得实时预览支持H.265硬解具备可行性;
但是WebRTC本身支持的视频编码格式仅包括VP8、VP9、H.264、AV1,并不支持H.265,短期内也没有计划去支持H.265,因此需要自研实现WebRTC变相支持H.265编码,具体方式有
- 实现WebRTC对H.265的支持方式
- 通过
DataChannel实现DataChannel是专门用来传输除音视频数据之外的任何数据的通道(当然也是支持音视频数据传输的),本质上就是一条socket通道DataChannel使用的协议是SCTP(stream control transport Protocol)是一种与TCP、UDP同级的传输协议,可以直接在IP协议之上运行;- 在WebRTC中,SCTP通过安全的DTLS隧道进行隧道传输,该隧道本身在UDP之上运行,同时支持流控、拥塞控制、按消息传输、传输模式可配置性等特性,但需要注意的是单次发送消息不能超过maxMessageSize(只读,默认65535字节)
DataChannel可以配置在不同模式下,一种是使用重传机制的可靠传输模式(默认模式),可以确保数据成功传输到对等端;另一种是不可靠的传输模式,该模式下可以通过设置maxRetransmits指定最大重传次数,或通过设置maxPacketLife设置传输间隔时间实现;两种配置是互斥的,不可同时设置,当同时为null时使用可靠传输模式,有一个值不为null时为不可靠传输模式
- 数据通道支持String类型或ArrayBuffer类型,即二进制流或者字符串数据
- 通过
信令服务器工作原理
为了高效的利用CPU,信令服务器采用了事件驱动的工作模式;即当没有网络事件(网络请求)时,空闲出来的CPU可以处理其他任务;当有网络事件时,可以及时响应网络事件
- 事件驱动
- 事件驱动是设计/开发网络服务器最经典、最流行的模型;
- 事件驱动模式可以由不同的API来实现,如select、poll、epoll等,这些API各有各的优势,对于peerconnection_server而言是通过select API实现的
直播协议和视频监控方案
直播难于易
- 直播难:直播运用的技术较多,如视频/音频处理、图形处理、音频/视频压缩、CDN分发、即时通讯等技术,从零实现直播是较难的
- 直播易:站在巨人的肩膀上,使用他们封装的框架进行实现直播搭建
WebRTC(RTP)、FLV(RTMP)和HLS协议 → 不同类型的视频流协议
视频流协议
视频流协议是一组规则,用于管理视频数据如何从一个点传输到另一个点;有助于确保数据完好无损并以正确的顺序到达
- 流式传输协议可以用于通过Internet或本地网络上的设备之间流式传输视频
- 较流行的流媒体协议有
- HTTP实时流式传输(HLS:HTTP Live Streaming)
- 原理就是服务端将整个流切分成一片片小的媒体流片段,客户端通过下载一个包含源数据的extend M3U(m3u8)playlist文件用于寻找可用的媒体流,随后开始下载格式为MPEG-TS的媒体片段
- 其限制的编码格式是H264+AAC编码
- PC端浏览器大多只能解析H264/HEVC播放视频,wasm可以解析H265,因此在进行音视频解析播放时需要考虑降级的方案
- Chrome已经实现对H.265/HEVC的硬件支持,对HEVC硬件支持的代码已经合进了Chromium的仓库,这将意味着只要是使用Chromium内核的浏览器本质上也可以支持H.265/HEVC硬解
- HEVC(High Efficiency Video Coding)高效视频编码,也称H.265和MPEG-H part 2,是视频压缩标准,与AVC比较,HEVC在相同视频质量的前提下提供大约两倍的数据压缩比,或者以相同的比特率显示着提高视频质量,支持高达8192×4320的分辨率,包括8K UHD
- 如:将WebRTC作为直播的首选方案,保证体验的优先;以CDN直播作为降级方案,确保用户能看
- 是由Apple开发的一种协议,它使用分段文件格式通过HTTP传输视频内容
- 例如将固定长度的FLV进行切片转成ts与m3u8,但因为切片时间、网络传输时间、等待固定长度的FLV格式的文件就需要较大的时间
- m3u8是一种基于HLS文件视频的文本格式,主要是存放整个视频的基本信息和分片(Segment)组成
- 一级m3u8文件记录了不同比特率视频流的二级index文件,客户端可以根据自己相关网络设备状况决定播放哪一路视频流,同样的也可以在网络变化时平滑的切换到匹配的视频流
- HLS是把流分成一个个小的基于HTTP的文件来下载,每次只下载一部分
- 例如将固定长度的FLV进行切片转成ts与m3u8,但因为切片时间、网络传输时间、等待固定长度的FLV格式的文件就需要较大的时间
- HLS协议由三部分组成:HTTP(传输协议)、m3u8(索引文件)、TS(音视频媒体信息)
- 每一个.m3u8文件分别对应若干个TS文件,基于HTTP来下载,每次只卸载一小部分;
- .m3u8文件只是存放了一些TS文件的配置信息和相关路径,当视频播放时,.m3u8是动态变化的,在通过解析器(如hls.js)解析这些文件,并找到对应的TS文件来播放,因此一般为了加快速度,.m3u8文件放在Web服务器上,TS文件放在CDN上
- HLS使用的是HTTP的短连接,传输方式上本就不存在优势,对网络要求也较高
- 与其他协议不同点在于:直播客户端获取到的并不是一个完整的数据流,该协议在服务端将直播流数据流式存储为连续的、很短时长的媒体文件(MPEG-TS格式),客户端则不断地下载并播放这些小文件
- 可以理解为HLS是以点播的技术方式来实现直播,数据通过HTTP传输
- 其特点是:基于HTTP短连接,延迟一般在10~15S,可与更广泛的设备兼容、但具有更高的延迟
- 在目前ed视频流媒体中,低延迟HLS流媒体是为数不多的实现低延迟、自适应码率流媒体直播的方式之一
- 优势
- 穿透防火墙:基于HTTP/80传输,有效避免了防火墙拦截
- 高性能:通过HTTP传输,支持网络分发,CDN支持良好,且自带多码率自适应
- 劣势
- 实时性差,延迟高,基本延迟在10s+之上
- 文件碎片:ts切片较小,会导致海量的小文件,需要直播流分片拉取,客户端也需要频繁的进行HTTP请求,对存储和缓存都有一定的挑战
- 通过video标签进行HLS播放,无法很好的在业务层进行定制化操作以及数据监控
- HTML5直接支持(video),适合APP直播,PC端只有Safari、Edge支持
- 由于HLS是由Apple提出的,所以在iOS手机或电脑上,可以直接用Safari浏览器的video标签来播放m3u8格式的视频文件,而其他浏览器则需要借助hls.js来兼容m3u8
var video = document.getElementById("video"); if (Hls.isSupported()) { var hls = new Hls(); hls.loadSource( "https://yunqivedio.alicdn.com/2017yq/v2/0x0/96d79d3f5400514a6883869399708e11/96d79d3f5400514a6883869399708e11.m3u8" ); hls.attachMedia(video); hls.on(Hls.Events.MANIFEST_PARSED, function () { video.play(); }); } else if (video.canPlayType("application/vnd.apple.mpegurl")) { video.src = "https://video-dev.github.io/streams/x36xhzz/x36xhzz.m3u8"; video.addEventListener("loadedmetadata", function () { video.play(); }); }
- 实时消息协议(RTMP: Real Time Messaging Protocol)
- 由Adobe公司开发,底层是基于TCP协议的
- TCP的ACK机制,发送方会等接收方确认才继续发送下一个数据包
- 特点
- TCP长连接,默认端口号是1935,协议中的基本数据单元为消息(message),传输的过程中消息会被拆分为更小的消息块(chunk)单元,最后将分割后的消息块通过TCP协议传输,接收端再反解接收的消息块恢复成流媒体数据
- 延迟在3~5s
- RTMP协议是专门为流媒体开发的协议,对底层的优化比其他协议更加优秀,基本上所有的编码器(摄像头之类)的都支持RTMP输出
- RTMP支持长时间播放,延迟也相对较低,一般在1~3s之间,一般的视频会议、互动式直播完全是够用的
- 兼容性方面必须支持Flash
- 缺点是
- 基于TCP传输,非公共端口,可能会被防火墙阻拦
- RTMP为Adobe私有协议,很多设备无法播放,特别是在iOS端,需要使用第三方解码器才能播放
- 实时流协议(RTSP: Real Time Streaming Protocol)
- 实时流媒体会话协议,是用来控制声音或影视的多媒体串流协议;
- 提供了一个可拓展框架,使得实时数据的受控与点播成为了可能
- 是一种双向的实时数据传输协议,允许客户端向服务器端发送请求,如生成回放、快进、待退等操作
- 内部可基于RTP来传输数据,也可以选择TCP、UDP、组播UDP等通道来发送数据,具有较好的拓展性
- WebRTC
- 是一种开源协议,允许在浏览器之间双向传输音频、视频数据和文本
- 安全可靠传输(SRT)
- HTTP FLV
- 基于HTTP流式IO传输FLV,将流媒体数据封装成FLV格式,然后通过HTTP传输给客户端
- HTTP-FLV依靠MIME(Multipurpose Internet Mail Extensions)的特性,根据协议中的Content-Type来选择对应的程序去处理相应的内容,从而使得流媒体可以通过HTTP传输,例如通过配置MIME类型为
flv-application/octet-stream来达到这个目的,但MIME只是一个描述,并非非得输入上述示例 - MIME类型就是设定某种扩 展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以 及一些媒体文件打开方式
- 是将RTMP封装在HTTP协议之上的用于传输FLV格式的协议,其传输的http_flv是一个文件大小无上限的HTTP流的文件;
- 不需要服务端进行直播流的切片处理,因此具有低延迟的特点,平均延迟只有1~2s
- HTTP FLV还具有一定的避免防火墙干扰(基于HTTP/80传输),兼容302跳转灵活调度/负载均衡,支持HTTPS通道加密等优势
- 局限性:HTTP FLV的支持需要依赖于MSE(Media Source Extensions)API和fetch+stream API,而iOS浏览器不支持MSE API,因此FLV流无法直接在iOS端播放
- 在支持浏览器的协议里,延迟的排序是:RTMP ≈ HTTP-FLV ≈ WebSocket-FLV < HLS
- 在支持浏览器的协议里,性能的排序是:RTMP > HTTP-FLV ≈ WebSocket-FLV > HLS
- HTTP实时流式传输(HLS:HTTP Live Streaming)
- 兼容方案
- PC端
- 优先使用HTTP-FLV,因为它延迟小,性能不差,可以流畅播放1080P
- 尝试使用flv.js进行流媒体播放
- 不支持flv.js就使用Flash播放器播RTMP流,兼容性好但是现在大多都被禁用了
- 使用HLS,但是PC端只有Safari支持HLS
- 移动端
- 优先使用HTTP-FLV,因为它延迟小,性能不差,可以流畅播放1080P
- 尝试使用flv.js进行流媒体播放
- 使用HLS,但是PC端只有Safari支持HLS
- H5端不支持Flash
- 业务流控
- 通过心跳上报,统计不同类型的直播的平台的实时并发流量
- 根据在线并发量,相应新进入房间的学生应该切到哪种直播方式
- 监控日志
- 监控并实时上报各项指标并告警
- PC端
- 拓展
- MSE(Media Source Extension:媒体流拓展)
- 是为了让H5支持流媒体操作(用户层面就是播放)的一个标准
- 原视频文件通过编码来压缩文件大小,再通过封装将压缩视频、音频、字幕组合到一个容器内,可以将
<video>标签看作是拥有解封装、解码功能的浏览器自带的播放器; - 仅依赖
<video>标签是无法识别的TS流文件的,因此就引入了MSE拓展来帮助浏览器识别并处理TS文件,将其变回原来的可识别的媒体容器格式以使得<video>可以正常播放该视频流
- 现阶段支持移动端播放flv格式的js SDK主要有以下几种
- flv.js的工作原理:通过MSE将flv流转码成fmp4给video进行播放,其本质还是依赖于MSE,所以无法支持iOS
- 由于依赖于MSE,所以目前IOS和Android4.4.4(2013年发布4.4系统,现在最新的是6.0)以下的浏览器不支持
- FLV是Adobe公司推出的另一种视频格式,是一种在网络上传输的流媒体数据存储容器格式,其格式相对简单,不需要很大的媒体头部信息
- 编码格式:H264(视频)+AAC/MP3(音频)
- 使用HTTP的流式IO(fetch或stream)或WebSocket协议流式的传输媒体内容
- 延迟大多在2~5s的延迟,首帧比RTMP更快
- 优势:
- 由于浏览器对video标签采用了硬件加速,性能很好,支持高清
- 同时支持直播和录播
- 不用依赖于Flash
- 原理
- 在获取到FLV格式的音视频数据后通过原生的JS去解码转换FLV数据,再通过MSE API喂给原生video标签(原生video标签仅支持mp4/webm格式,不支持FLV)
- FLV容器格式相比于MP4格式更简单,解析起来更方便
- 拓展 → mp4分类
- nMP4:嵌套的Boxes,需要加载整个文件进行播放
- fMP4:是由一系列的片段组成,不需要加载整个文件进行播放
- NodePlayer.js工作原理:通过ASM.js软解码H.264+AAC流,利用WebGL视频渲染,WebAudio音频播放来实现移动端flv直播流的播放;
- WXInlinePlayer与ffmpeg-player工作原理基本类似:
- 数据流获取:从云端的HTTP-FLV流媒体获取直播流数据
- WASM解码层:
- 利用WebWorker开启子线程
- 通过获取视频流的metaData信息后,对视频进行解封装
- 将视频流转换为YUV,音频流格式转换为PCM
- 最后将转换好的数据回调给渲染层
- 渲染层:
- 将获取到的视频数据和音频数据存入渲染缓存池中
- WebGL在Canvas上绘制视频画面
- WebGL渲染器强依赖于手机硬件性能,因此对低端手机会出现降级情况(720分辨率的流降级到540P,或者将FLV降级为HLS)
- Web Audio API播放音频数据
- 解码库依赖方面
- ffmpeg-player是在Web侧复用了FFmpeg中的H.265解码模块实现前端解码,整套解码器在依赖h264、acc、flv的同时还依赖了HEVC,因此ffmpeg-player同时支持了H.264和H.265两种格式的视频流,因此输出的wasm文件体积较大,约1.3M
- WXInlinePlayer提供了三种构建方案,开发者根据需求来选择不同的解码器
- baseline(不使用OpenH264)
- all(在baseline的基础上支持OpenH264)
- h265(基于OpenH265)
- 总体开发思路
- 通过wasm来编解码器从而实现现在前端进行FLV格式的解码,输出YUV视频数据以及PCM音频数据,利用webGL渲染YUV和webAudio API播放PCM音频最终实现FLV播放
- K歌解析FLV的流程图解
- flv.js的工作原理:通过MSE将flv流转码成fmp4给video进行播放,其本质还是依赖于MSE,所以无法支持iOS
- MSE(Media Source Extension:媒体流拓展)
比较WebRTC和HLS协议
- 交付方法比较
- WebRTC视频流采用双向点对点连接进行实时通信
- 可以实现客户端之间的视频流数据直接相互发送 - 几乎无延迟
- WebRTC是基于UDP的
- HLS使用客户端-服务器模型
- 需要使用服务器将视频流发送给客户端 - 产生延迟
- HLS是使用TCP(传输控制协议)
- 总结:WebRTC可以提供更低的延迟
- WebRTC视频流采用双向点对点连接进行实时通信
- 视频质量比较
- WebRTC采用点对点的流式传输,允许客户端之间直接进行通信
- WebRTC可以提供更高的视频流数据
- 可拓展性比较
- WebRTC采用点对点协议,意味着可以拓展到大量用户而不会降低质量
- 拓展性WebRTC较好
- 安全性比较
- WebRTC采用DTLS进行加密
- HLS采用TLS
- 灵活性和兼容性比较
- 兼容性都较好
- 移动端IOS和Android都支持HLS协议,做好视频采集、视频推流服务之后,就可以直接在H5页面通过video标签进行播放直播流
<video<source id="source" src="http://xxxx/video.m3u8" type="application/x-mpegURL" /></video>
监控方案
安防类项目中都需要有视频监控方案的需求,视频监控客户端主要是Native应用的形式,在Web端需要利用NPAPI、ActiveX之类的插件技术实现
B/S架构实时视频监控解决方案
- 音视频编码
- 常见的音频编码算法包括:MP3、Vorbis、AAC
- 常见的视频编码算法包括:H.264、HEVC、VP8、VP9
- 音视频编解码格式
- 视频:AVI、MOV、MPEG/MPG/DAT、Real Media、QuickTime、ASF、H264/X264/AVC、H.263、MPEG-1、MPEG-2、MPEG-4、Sorensen Spark、VC-1、JPEG、RV、DivX、On2 TrueMotion VP6
- 音频:PCM、WAV、OGG、APE、AAC、MP3、Vorbis、Opus...
- video和Audio支持的格式
- video:MP4、webm、ogv
- Audio:MP3、wav、ogg
- 视频的编解码方式取决于Codec(数字信号编解码器,可以对音视频进行压缩CO和解压缩DEC,该技术可以有效减少数字存储占用的空间,在计算机中可以节省CPU的资源,提高系统的运行效率),如MP4根据编解码的不同分为nMP4、fMP4