首先我们知道,Rtmp是一种客户端到服务端的技术,Peer to Server。WebRTC是一种客户端到客户端的技术,Peer to Peer。
Rtmp通过一个TCP连接,向服务端发送或接收连接信息,媒体数据。
WebRTC先使用ICE技术连接STUN/TURN,得到自己的连接信息。再绑定音视频设备获取媒体信息,拼装为SDP信令。两个客户端通过任意方式交换信令,建立客户端直接的连接,再使用RTP发送和接收媒体数据。
如果一个服务端实现了WebRTC客户端的能力,那么它也可以被认为是一个Peer,与用户浏览器的WebRTC客户端创建连接,获得客户端推送过来的媒体数据,就完成了Peer to Server的转换。
WebRTC是一个非常非常复杂的协议,如果自己从0开始写起是不现实的。在完成这个工作的时候,我也尝试过其它一些实现,做了一些分析。大体分为如下几种类型。
第一种,将开源项目Chromium内WebRTC的cpp原生实现集成到项目中使用。
比如这个项目:
https://github.com/node-webrtc/node-webrtc
经过分析,pion/webrtc 是目前看起来最适合用在NMSv3中的项目。原因如下:
1. 原生WebRTC虽然有最好的功能实现,但复杂的编译环境,源码整合,API封装,工作量非常繁重,放弃。
2.GStreamer在Linux下有非常普遍的使用率,但它严重依赖大量第三方项目,比如glib,libice等,都存在跨平台编译问题,也存在API使用繁琐的问题。
3.gortc与pion相比,完成度较低。
pion/webrtc使用原生的Go语言实现,和NMSv3完美整合,API封装程度非常高,使用非常简单。当然相比原生实现,有一些bug,好在改起来也不难,提交过pr,不一定合并,以我的版本为准。
然后我们需要定义信令交换的方式,web编程当然最简单的就是WebSocket了,我定义了一个URL格式
wss://serverip:port/live/stream.rtc
这种格式和RTMP,HTTP-FLV等相互通用。必须是wss,因为现在的浏览器对webrtc访问摄像头,除了localhost外,必须是https连接,https页面也只能使用wss连接。
信令交换后,客户端创建了和服务端的udp连接,并源源不断的发送H.264+Opus的rtp包。目前客户端能使用的视频编码是vp8,vp9,h264,音频有PCMA,Opus,不会有AAC,因此我们还需要定义flv封装Opus。Opus和AAC类似,我们定义id为13。这样实现rtmp播放客户端的时候,加入opus解码能力和flv负载opus的能力,就可以播放啦。
当然,我们还需要继续工作,在服务端将Opus直接转码为AAC,NMSv3前期已经实现了Speex、Nellymoser等实时转码AAC的能力,现在加入Opus的能力,完成。
至此,我们完成了浏览器无插件推流,后续我考虑下是否有需要实现webrtc播流。Flash将在2020年12月停止支持,我们已经可以正式的向它告别。