一、移动端适配:WebRTC 在 Android 与 iOS 上的实战
聊到 WebRTC 的移动端适配,我得先跟你交个底——这玩意儿在 PC 上跑得挺欢,一上手机,各种坑就冒出来了。我自己在几个商业项目里踩过不少雷,今天把 Android 和 iOS 的集成要点、性能优化手段,一股脑倒给你。
1.1 Android 平台集成:从零开始
Android 上集成 WebRTC,说白了就是跟 Google 的官方库打交道。我习惯用 Maven 依赖,省心。
核心依赖:
implementation 'org.webrtc:google-webrtc:1.0.32006'
嗯,这里要注意版本号。我遇到过几次因为版本太新,跟底层硬件解码器不兼容的情况。建议你锁定一个稳定版本,别追新。
集成步骤其实就三步:
- 初始化 PeerConnectionFactory——这是 WebRTC 的引擎,所有音视频处理都靠它。
- 创建 PeerConnection——负责点对点连接。
- 绑定本地音视频流——从摄像头、麦克风采集数据。
给你看一段我项目里的初始化代码:
// 初始化 PeerConnectionFactory
PeerConnectionFactory.InitializationOptions initOptions =
PeerConnectionFactory.InitializationOptions.builder(context)
.setFieldTrials("")
.createInitializationOptions();
PeerConnectionFactory.initialize(initOptions);
PeerConnectionFactory factory = PeerConnectionFactory.builder()
.setVideoDecoderFactory(new DefaultVideoDecoderFactory(eglBaseContext))
.setVideoEncoderFactory(new DefaultVideoEncoderFactory(eglBaseContext, true, true))
.createPeerConnectionFactory();
我曾经在初始化时忘了设置 EGL 上下文,结果视频渲染黑屏了整整两天。你想想看,排查这种问题多痛苦。
1.2 iOS 平台集成:Swift 与 ObjC 的混搭
iOS 这边,WebRTC 官方推荐用 CocoaPods 或 Swift Package Manager。我个人更倾向 SPM,因为 Xcode 原生支持,少一层依赖。
SPM 添加方式:
https://github.com/stasel/WebRTC.git, branch: 'latest'
iOS 集成有个大坑——音频会话管理。WebRTC 默认会接管 AVAudioSession,如果你 App 里同时有音乐播放功能,两者会打架。
避坑指南:我曾经在集成 iOS SDK 时,用户一边通话一边听歌,结果声音时断时续。后来发现是 WebRTC 把音频会话设成了 PlayAndRecord 模式,跟音乐播放冲突。解决方案是在通话开始前保存当前音频会话配置,通话结束后恢复。
iOS 端的视频渲染,建议用 RTCMTLVideoView,它基于 Metal,性能比 OpenGL 好不少。我测试过,在 iPhone X 上帧率能稳定在 30fps。
1.3 移动端性能优化:别让手机发烫
移动端最头疼的问题是什么?发热、掉帧、耗电快。这三个问题往往是一起出现的。我总结了几条实战经验:
| 优化项 | 具体做法 | 效果 |
|---|---|---|
| 分辨率控制 | 根据网络带宽动态调整,不要硬上 1080p | 降低编码压力,减少发热 |
| 帧率限制 | 非必要场景锁 15fps,通话场景 24fps 足够 | CPU 占用下降 30% |
| 硬件编码器优先 | Android 用 MediaCodec,iOS 用 VideoToolbox | 比软编码省电 50% 以上 |
| 屏幕关闭时暂停视频 | 监听应用生命周期,切后台时停止视频采集 | 显著降低功耗 |
嗯,这里要特别提一下分辨率控制。我见过不少团队直接写死 720p,结果在低端机上卡成幻灯片。正确的做法是用 WebRTC 的 VideoSource.adaptOutputFormat 方法,根据带宽估算器动态调整。
// 动态调整分辨率示例
videoSource.adaptOutputFormat(
new VideoSource.AspectRatio(16, 9),
320, // 目标宽度
240, // 目标高度
15, // 目标帧率
3 // 降级优先级
);
另外,内存泄漏是移动端 WebRTC 的隐形杀手。PeerConnection、MediaStream 这些对象,用完后必须显式释放。我曾在 Android 上因为忘记调用 peerConnection.dispose(),导致 OOM 崩溃。
我的习惯:每次创建 PeerConnection 时,用 try-finally 块包裹,确保 dispose 一定会执行。iOS 上则用 deinit 方法做清理。
1.4 知识体系总览
下面这张图,是我梳理的移动端 WebRTC 适配核心逻辑。你看一眼,心里就有谱了。
你看,整个适配工作其实就围绕这三个模块展开。Android 和 iOS 各有各的脾气,但性能优化的思路是相通的——说白了就是跟硬件、网络、电量做博弈。
最后说一句,移动端 WebRTC 调试起来比 PC 麻烦得多。我建议你准备一台 root 过的 Android 机,配合 Stetho 抓日志;iOS 则用 Xcode 的 Instruments 看 CPU 和内存。工具趁手,问题解决得快。