安卓上WebRtc

在 Android 上使用 WebRTC,可分为「官方 SDK」和「自己编译源码」两条路线。

多数业务场景直接依赖官方发布的 AAR 即可,下面给出一套从 0 到 1 的落地步骤(基于官方 AAR)。


一、准备工作

  1. Android Studio ≥ 4.0
  2. minSdkVersion ≥ 21(建议 23+)
  3. 真机或模拟器(模拟器需支持 Camera2)

二、在工程里引入 WebRTC

app/build.gradle

java 复制代码
implementation 'org.webrtc:google-webrtc:1.0.32006'   // 官方最新稳定版
implementation 'org.java-websocket:Java-WebSocket:1.5.3' // 仅示例,用 WebSocket 做信令

三、Manifest 权限与特性

xml 复制代码
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

<uses-feature android:name="android.hardware.camera" android:required="true"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>

动态权限申请代码略(可用 EasyPermissions / RxPermission)。


四、初始化 WebRTC(一次性在 Application 或 Activity 中做)

java 复制代码
PeerConnectionFactory.InitializationOptions init =
        PeerConnectionFactory.InitializationOptions.builder(context)
                .setEnableInternalTracer(true)
                .setFieldTrials("WebRTC-H264HighProfile/Enabled/")
                .createInitializationOptions();
PeerConnectionFactory.initialize(init);

五、创建 PeerConnectionFactory

java 复制代码
// EGL 上下文,用于硬件加速编解码 & 渲染
EglBase rootEgl = EglBase.create();

// 视频编解码工厂
VideoEncoderFactory encoderFactory =
        new DefaultVideoEncoderFactory(rootEgl.getEglBaseContext(), true, true);
VideoDecoderFactory decoderFactory =
        new DefaultVideoDecoderFactory(rootEgl.getEglBaseContext());

// 音频模块
AudioDeviceModule adm = JavaAudioDeviceModule.builder(context).createAudioDeviceModule();

PeerConnectionFactory factory = PeerConnectionFactory.builder()
        .setAudioDeviceModule(adm)
        .setVideoEncoderFactory(encoderFactory)
        .setVideoDecoderFactory(decoderFactory)
        .setOptions(new PeerConnectionFactory.Options()) // 可关闭加密/网络监控
        .createPeerConnectionFactory();

六、采集本地音视频

  1. 视频源
java 复制代码
SurfaceTextureHelper surfaceHelper =
        SurfaceTextureHelper.create("CaptureThread", rootEgl.getEglBaseContext());

CameraEnumerator enumerator = new Camera1Enumerator(true);  // Camera2Enumerator 亦可
String camName = enumerator.getDeviceNames()[0];            // 默认后置
VideoCapturer capturer = enumerator.createCapturer(camName, null);

VideoSource videoSource = factory.createVideoSource(capturer.isScreencast());
capturer.initialize(surfaceHelper, context, videoSource.getCapturerObserver());
capturer.startCapture(1280, 720, 30);

VideoTrack localVideoTrack = factory.createVideoTrack("ARDAMSv0", videoSource);
  1. 音频源
java 复制代码
AudioSource audioSource = factory.createAudioSource(new MediaConstraints());
AudioTrack localAudioTrack = factory.createAudioTrack("ARDAMSa0", audioSource);

七、本地渲染(SurfaceViewRenderer)

xml 复制代码
<org.webrtc.SurfaceViewRenderer
    android:id="@+id/localRenderer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
java 复制代码
SurfaceViewRenderer localRenderer = findViewById(R.id.localRenderer);
localRenderer.init(rootEgl.getEglBaseContext(), null);
localVideoTrack.addSink(localRenderer);

八、创建 PeerConnection & 信令交换

  1. 配置 ICE 服务器
java 复制代码
List<PeerConnection.IceServer> iceServers = new ArrayList<>();
iceServers.add(PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer());
// 有 TURN 账号也可加
  1. 创建 PeerConnection
java 复制代码
PeerConnection.RTCConfiguration rtcConfig = new PeerConnection.RTCConfiguration(iceServers);
PeerConnection pc = factory.createPeerConnection(rtcConfig, new PeerConnectionObserver() {
    @Override public void onIceCandidate(IceCandidate iceCandidate) {
        // 通过信令通道发送给对方
        sendIceCandidateToRemote(iceCandidate);
    }
    @Override public void onAddTrack(RtpReceiver rtpReceiver, MediaStream[] mediaStreams) {
        VideoTrack remoteVideoTrack = (VideoTrack) mediaStreams[0].videoTracks.get(0);
        remoteVideoTrack.addSink(remoteRenderer); // 远端渲染
    }
});
// 把本地轨道加入
pc.addTrack(localVideoTrack, Collections.singletonList("ARDAMS"));
pc.addTrack(localAudioTrack, Collections.singletonList("ARDAMS"));
  1. 信令流程(伪代码)
  • 收到 room 中新成员通知 → createOffer → setLocalDescription → 发送 Offer
  • 收到 Answer → setRemoteDescription
  • 收到 ICE candidate → addIceCandidate

信令通道可用 WebSocket、Socket.IO、FCM 任意实现。


九、远端渲染

与本地渲染完全一样,再准备一个 SurfaceViewRenderer 即可。


十、释放资源

java 复制代码
capturer.stopCapture();
capturer.dispose();
pc.close();
factory.dispose();
rootEgl.release();

十一、常见坑排查

现象 可能原因
黑屏 未调用 startCapture/addSink,或 EGL 线程冲突
听不到声音 未动态申请 RECORD_AUDIO,或 AudioTrack 未 addTrack
连不上 防火墙拦截 UDP,需要 TURN
崩溃 so not found 64 位 so 未打入,检查 Gradle abiFilters

十二、进阶方向

  • 多人会议:SFU(Janus/mediasoup)
  • 数据通道:DataChannel 传文件 / 白板
  • 编译源码:定制编解码器、裁剪包大小
  • 性能调优:硬件编解码、带宽估计、抖动缓冲

至此,即可在 Android 上完成一次完整的 WebRTC 点对点通话。

相关推荐
g_i_a_o_giao1 小时前
Android8 binder源码学习分析笔记(一)
android·java·笔记·学习·binder·安卓源码分析
翻滚丷大头鱼1 小时前
android 四大组件—BroadcastReceiver
android
人生游戏牛马NPC1号2 小时前
学习 Android (二十) 学习 OpenCV (五)
android·opencv·学习
2501_916008892 小时前
uni-app iOS 日志与崩溃分析全流程 多工具协作的实战指南
android·ios·小程序·https·uni-app·iphone·webview
文 丰2 小时前
【AndroidStudio】官网下载免安装版,AndroidStudio压缩版的配置和使用
android
WillWolf_Wang2 小时前
Linux 编译 Android 版 QGroundControl 软件并运行到手机上
android·linux·智能手机
fatiaozhang95272 小时前
数码视讯TR100-OTT-G1_国科GK6323_安卓9_广东联通原机修改-TTL烧录包-可救砖
android·xml·电视盒子·刷机固件·机顶盒刷机
撬动未来的支点2 小时前
【Android】内核及子系统
android
2501_915921433 小时前
iOS混淆工具实战 在线教育直播类 App 的课程与互动安全防护
android·安全·ios·小程序·uni-app·iphone·webview
前行的小黑炭5 小时前
Android Flow的其他使用:stateIn和冷流(普通Flow)
android·kotlin