webRTC学习三(代码分析)
来源:互联网 发布:自建服务器绑定域名 编辑:程序博客网 时间:2024/05/29 17:26
https://github.com/pchab/AndroidRTC
AndroidRTC是ProjectRTC的android客户端,下载后直接AndroidStudio打开。AndroidRTC中包含两个moudle,app是主界面,webrtc-client是工具类moudle 。
本文为自己学习过程中查询的资料和代码的分析,纯属个人观点,有不对之处还望提出,多多交流和提高,谢谢。
Web API——第三方开发人员用来开发基于Web的应用,如视频聊天。
WebRTC Native C++ API——浏览器厂商用于实现Web API的函数集。
Session Management——抽象session层,支持调用构建和管理层,由应用开发者来决定如何实现协议。
VoiceEngine——音频媒体链的框架,从声卡到网络。
iSAC——一种用于VoIP和流音频的宽带和超宽带音频编解码器,iSAC采用16 kHz或32 kHz的采样频率和12—52 kbps的可变比特率。
iLBC——用于VoIP和流音频的窄带语音编解码器,使用8 kHZ的采样频率,20毫秒帧比特率为15.2 kbps,30毫米帧的比特率为13.33 kbps,标准由 IETF RFC 3951和3952定义。
NetEQ for Voice——动态抖动缓存和错误隐藏算法,用于缓解网络抖动和丢包引起的负面影响。在保持高音频质量的同时尽可能降低延迟。
VideoEngine——视频媒体链的框架,从相机像头到网络,从网络到屏幕。
VP8——来自于WebM项目的视频编解码器,非常适合RTC,因为它是为低延迟而设计开发的。
Image enhancements——消除通过摄像头获取的图片的视频噪声等。
PeerConnection位于WebRTC Native C++ API的最上层,它的代码实现来源于libjingle(一款p2p开发工具包),目前被应用于WebRTC中。
- 可以看得出来PeerConnectionFactory的重要性,` Factory是工厂,工厂可以生产很多很多的PeerConnection
- 摄像头、麦克风这些设备只能是进程独占方式的,所有只有一个,然后多个PeerConnection共享使用LocalMediaStream
下面是爱立信公司的openWebRTCDemo
最开始以为OpenWebrtc是对Webrtc的修改版本,但是实际上不是这样。
Openwebrtc是爱立信实验室开发的,Ericsson和Google都是webrtc标准的主要制定者,两家公司分别实现了一套webrtc ,即Ericsson Openwebrtc和我们熟知的Google Webrtc。两者更是一种竞争关系。
Google Webrtc基于GIPS,而Ericsson Openwebrtc基于GStreamer。
WebRTC Android端的大体实现过程如下:(在不考虑播放本地视频的情况下)
- 连接服务器,并通过服务器打通两个客户端的网络通道。
- 从摄像头和麦克风获取媒体流 。
- 将本地媒体流通过网络通道传送给对方的客户端 。
- 渲染播放接收到的媒体流 。
关键技术
核心类PeerConnectionFactory
首先需要初始化PeerConnectionFactory,这是WebRTC的核心工具类,初始化方法如下:
- 1
- 2
- 3
- 4
- 5
- 6
然后就可以获得对象:PeerConnectionFactory factory= new PeerConnectionFactory();
获取媒体流
第一步:获取视频源videoSource
- 1
- 2
- 3
其中videoConstraints是对视频流的一些限制,按如下方法创建。
- 1
- 2
- 3
- 4
- 5
第二步:获取音频源audioSource
音频源的获取简单许多:
- 1
第三步:获得封装VideoTrack/AudioTrack
VideoTrack/AudioTrack 是 VideoSource/AudioSource 的封装,方便他们的播放和传输:
- 1
- 2
第四步:获取媒体流localMS
其实 VideoTrack/AudioTrack 已经可以播放了,不过我们先不考虑本地播放。那么如果要把他们发送到对方客户端,我们需要把他们添加到媒体流中:
- 1
- 2
- 3
然后,如果有建立好的连接通道,我们就可以把 localMS 发送出去了。
建立连接通道
WebRTC是基于P2P的,但是在连接通道建立好之前,我们仍然需要服务器帮助传递信令,而且需要服务器帮助进行网络穿透。大体需要如下几个步骤。
第一步:创建PeerConnection的对象。
- 1
- 2
- 3
- 4
iceServers 我们下面再说。
pcConstraints是媒体限制,可以添加如下约束:
- 1
- 2
- 3
监听器建议同时实现SdpObserver、PeerConnection.Observer两个接口。
第二步:信令交换
建立连接通道时我们需要在WebRTC两个客户端之间进行一些信令交换,我们以A作为发起端,B作为响应端(A call B,假设服务器和A、B已经连接好,并且只提供转发功能,PeerConnection对象为pc ):
- A向B发出一个“init”请求(我觉得这步没有也行)。
- B收到后“init”请求后,调用
pc.createOffer()
方法创建一个包含SDP描述符(包含媒体信息,如分辨率、编解码能力等)的offer信令。 - offer信令创建成功后会调用SdpObserver监听中的
onCreateSuccess()
响应函数,在这里B会通过pc.setLocalDescription
将offer信令(SDP描述符)赋给自己的PC对象,同时将offer信令发送给A 。 - A收到B的offer信令后,利用
pc.setRemoteDescription()
方法将B的SDP描述赋给A的PC对象。 - A在
onCreateSuccess()
监听响应函数中调用pc.setLocalDescription
将answer信令(SDP描述符)赋给自己的PC对象,同时将answer信令发送给B 。 - B收到A的answer信令后,利用
pc.setRemoteDescription()
方法将A的SDP描述赋给B的PC对象。
这样,A、B之间就完成里了信令交换。
第三步:通过ICE框架穿透NAT/防火墙
如果在局域网内,信令交换后就已经可以传递媒体流了,但如果双方不在同一个局域网,就需要进行NAT/防火墙穿透(我是在局域网下测试的,没有穿透,但还是把这方面内容介绍下)。
WebRTC使用ICE框架来保证穿透。ICE全名叫交互式连接建立(Interactive Connectivity Establishment),一种综合性的NAT/FW穿越技术,它是一种框架,可以整合各种NAT/FW穿越技术如STUN、TURN(Traversal Using Relay NAT 中继NAT实现的穿透)。ICE会先使用STUN,尝试建立一个基于UDP的连接,如果失败了,就会去TCP(先尝试HTTP,然后尝试HTTPS),如果依旧失败ICE就会使用一个中继的TURN服务器。使用STUN服务器穿透的结构如下:
我们可以使用Google的stun服务器:stun:stun.l.google.com:19302(Google嘛,翻墙你懂得,当然如果有精力可以自己搭建一个stun服务器),那么我们怎么把这个地址告诉WebRTC呢,还记得之前的iceServers吗,就是在创建PeerConnection对象的时候需要的参数,iceServers里面存放的就是进行穿透地址变换的服务器地址,添加方法如下(保险起见可以多添加几个服务器地址,如果有的话):
- 1
然后这个stun服务器地址也需要通过信令交换,同样以A、B客户端为例过程如下:
- A、B分别创建PC实例pc(配置了穿透服务器地址) 。
- 当网络候选可用时,PeerConnection.Observer监听会调用
onIceCandidate()
响应函数并提供IceCandidate(里面包含穿透所需的信息)的对象。在这里,我们可以让A、B将IceCandidate对象的内容发送给对方。 - A、B收到对方发来的candidate信令后,利用
pc.addIceCandidate()
方法将穿透信息赋给各自的PeerConnection对象。
至此,连接通道完全打通,然后我们只需要将之前获取的媒体流localMS赋给pc即可:
- 1
在连接通道正常的情况下,对方的PeerConnection.Observer监听就会调用onAddStream()
响应函数并提供接收到的媒体流。
- webRTC学习三(代码分析)
- WebRTC代码走读(三):音频接收流程
- WebRTC代码走读(十):rtp_rtcp模块分析
- WebRTC代码走读(十一):video_coding模块分析
- WebRTC源码分析三:视频处理流程
- WebRTC源码分析三:视频处理流程
- WebRTC源码分析三:视频处理流程
- WebRTC源码分析三:视频处理流程
- WebRTC源码分析三:视频处理流程
- WebRTC源码分析三:视频处理流程
- WebRtc/Speex AEC matlab代码分析
- WebRTC学习之三:录音和播放
- lvm代码分析(三)
- IpMsg代码分析(三)
- WebRTC-Android 源码导读(三):视频硬编码实现分析
- Webrtc delay-base-bwe代码分析(6): 整体分析
- Webrtc AGC 算法原理介绍(三)
- WebRTC之本地视频采集(三)
- 论大数据应用环境体验
- HihoCoder #1513 : 小Hi的烦恼
- 真正的inotify+rsync实时双向同步
- js获取input = radio 单选框选择中的值
- 2017.8.17
- webRTC学习三(代码分析)
- Java多线程(一)之volatile深入分析
- 求字符串的重复子字符串的最小周期
- while(cin >>)的输入停止与错误问题
- VUE计算属性
- 生产者/消费者模型
- 基础数论算法(⑩) Catalan数与Stirling数
- flink增量读文本数据
- Java字符串的内存分配