WebRTC是基于点对点视频通话,底层协议栈主要是SRTP、UDP,基于SDP会话协议交互通话前报文(会话描述、ICE报文),通过ICE代理搜集双方的地址信息,大多数情况下音视频数据来源于手机的摄像头和麦克风,本文探讨的是基于源码自定义外部音视频数据。
1、源码下载
要开通VPN,下载基于iOS版本的源码https://webrtc.github.io/webrtc-org/native-code/ios/,需要注意的是如果源码在Linux平台下载,记得拷贝到mac之后要执行gclient sync同步 编译链工具,因为这个编译链工具是基于当前平台的。
2、源码编译
WebRTC 的编译是通过谷歌自己写的编译构建系统(ninja vs make)和构建管理软件 工具(gn),注意不要通过 XCode,否则一堆错误,必须通过源码里面的编译脚本进 行编译(src/tools_webrtc/ios/build_ios_libs),具体的编译说明可以参考文档: https://www.chromium.org/developers/gn-build-configuration。
3、源码分析以及修改
3.1、视频替换
发送端视频流水线建立类图如下:
其中画圈圈就是比较重要的类,如下讲解:
RTCVideoSource:通话视频数据源。
KdCameraVideoCapturer: 实际上的通话数据源,通过实现。
RTCVideoCapturer: 代理 接口,从而实现从外面填充视频数据。
VideoSinkInterface:视频帧的下一站。
VideoStreamBroadcaster: 数据源转发中心,通过注册成为 sink,从而成为视频帧的 下一站。
VideoStreamEncoder: 编码器编码视频帧。
EncoderSink: 编码视频帧的下一站。
ModuleRtpRtcpImpl2: 发送 RTCP 控制包,主要是 sender report。
RTPSenderVideo:把视频数据组装成 rtp 包,然后把数据发送到传输类。
Transport:对接 socket 层的发送,把数据发送到传输层。
3.2、音频替换
发送端音频流水线建立类图如下:
重要的类解析如下:
VoiceProcessingAudioUnit:音频播放和录音模块,封装 iOS 的音频单元模块。
FineAudioBuffer:10ms 音频样本组装类,自定义音频可以直接往此处填充数据。
AudioDeviceBuffer:负责发送音频样本类。
ModuleRtpRtcpImpl2:RTCP 控制包发送,主要的还是 SR 发送。
(RTPSenderAudio:RTP 音频包发送。
3.3、音视频同步
音视频同步涉及的主要类图如下:
同步基本原理:就是相对时间差,即音视频流的 RTP 时间戳和到达时间的差值,通过 这个差值来计算相对延时,这样可以不用考虑双方机器时钟的偏差问题。以下是比较重 要类:
RtpStreamsSynchronizer:音视频同步服务类。
StreamSynchronization:音视频同步控制类。
RtpVideoStreamReceiver2:负责视频同步信息的搜集等。
ChannelReceive:负责音频同步信息的搜集等。
4、期望结果
公司的项目是替换全景相机的全景视频,包括相机上的麦克风录制的音频,整体效果不错。