想在 Android 上做直播推流,多数人第一反应是”找 SDK 或源码”。但动手前可以思考几个问题:推给谁?延迟要多低?用自研还是商业方案?推到第三方平台如抖音和推到自建服务器不是一回事。
本文先给三条直接可用的结论,再讲清楚背后的取舍,最后以 ZEGO Express SDK 为例,给出从集成到上架的一条完整可跑路线:
- 直播推流 = 采集 → 编码 → 上行传输 → 服务器/云接收 → 分发 → 播放。一般您的工作重点在前三段,后三段由服务器(或云厂商)解决。
- 技术路线取决于延迟要求:互动场景(连麦、PK、教学问答)选 WebRTC/RTC 方案(<500ms);传统直播(秀场、电商,1–5s 可接受)选 RTMP 方案;RTMP 依然是手机推流的事实标准,但不是唯一答案。
- 实现方式按成本排序:商业 RTC SDK(最快上线)> 开源推流库(省 license、费工程)> 从零自研。别被”免费”迷惑,自研的隐形成本是服务器、弱网优化和长期维护。
一、一条直播流是怎么走的
把”Android 做直播推流”拆开,本质是把手机上的画面和声音实时、连续地送到远端。完整链路如下:
flowchart LR
A[主播 Android App] -->|采集| B[编码 H.264/H.265/AAC]
B -->|封包| C[推流协议 RTMP/WebRTC/SRT]
C -->|上行| D[流媒体服务器/实时云]
D -->|转码 分发| E[观众端 HLS/HTTP-FLV/低延迟协议]
- 推流端(你做的部分):采集摄像头/屏幕/麦克风 → 编码压缩 → 按协议封包 → 上行推送。
- 服务端(买或搭的部分):接收流、必要时转码、再分发给海量观众。自建(SRS、MediaMTX、Nginx-RTMP)或云厂商 CDN 二选一。
- 拉流端(播放的部分):观众用播放器按地址拉流。
1.1 四个概念
推流(Publishing):推流端把采集编码后的音视频数据上传到服务器的过程。对上行带宽要求高,网络差会直接导致观众端卡顿。
拉流(Playing):观众端主动向服务器请求并接收、解码播放直播流的过程。上行不行不影响观看,下行和服务器分发能力影响。
转推(Relay):服务器或 SDK 把一路流再推给另一个目标(如 RTMP 转推到第三方 CDN、多平台同推),常用于”一路采集、多处分发”。
旁路 CDN(CDN Live):实时音视频场景下,把 RTC 房间内的互动流”旁路”到标准 CDN,让不参与互动的海量观众用 HLS/FLV 观看,互动的少数人走低延迟通道。
一句话区分:推流是上传,拉流是下载(播放),转推是服务器替你再上传一份,旁路是给”看的人多、不需要说话的人”准备的出口。
1.2 三种直播形态,先定形态再选技术
| 形态 | 端到端延迟 | 上行协议 | 观众下行 | 典型场景 |
|---|---|---|---|---|
| 互动直播(RTC) | <500ms | WebRTC / 私有 UDP 优化协议 | 同协议或旁路 CDN | 连麦 PK、在线教育提问、带货互动、游戏开黑 |
| 传统直播(CDN) | 1–5s | RTMP(或 SRT) | HLS / HTTP-FLV | 秀场、演唱会、赛事、监控观看 |
| 平台直播 | 秒级 ~ 平台决定 | 平台推流码(RTMP) | 平台 App 播放 | 推到抖音、B站、快手做内容分发 |
形态决定了协议,协议决定了后面所有的代码和服务器选型。交互需求是延迟的根源:只要观众需要”说话给主播听”,就走互动直播;否则传统 CDN 更便宜、并发更大。
二、选型:看路线对比
动手前先回答:
- 推给谁:只有自己 App 的观众?还是抖音/B站/快手的用户?
- 延迟要求:能不能容忍 1–5 秒?观众要不要连麦互动?
- 团队与预算:有没有专职音视频工程师?license 费和自建服务器的钱谁便宜?
2.1 四条路线横向对比
| 路线 | 上手成本 | 长期维护 | 延迟 | 弱网 | 费用 | 适合 |
|---|---|---|---|---|---|---|
| ① 从零自研(MediaCodec + librtmp) | 极高 | 极高 | 可控 | 自研 | 仅服务器 | 学习原理;无现成方案的特异需求 |
| ② 开源推流库(RootEncoder 等) | 中 | 中高(库停更风险) | RTMP 1–3s 起步 | 弱,需自调 | 免费 + 服务器 | 学习、内部工具、预算敏感 |
| ③ 商业 RTC SDK(ZEGO/Agora/腾讯云等) | 低 | 低 | <200–500ms | 内置(自适应/抗丢包) | 按分钟计费,通常有免费额度 | 产品级直播 App、要连麦要弱网 |
| ④ 用平台现成开播(非开发路线) | — | — | — | — | 平台抽成 | 个人内容分发,不需要自研 App |
结论先行:做产品选 ③,学原理选 ②,练内功看 ① 的源码(但别在生产里手搓)。
2.2 开源推流库横评
如果团队倾向开源,先看这张表:
| 库 | 协议 | 编码 | 维护状态 | 备注 |
|---|---|---|---|---|
| RootEncoder(原 rtmp-rtsp-stream-client-java) | RTMP/RTSP/SRT/UDP | H.264/H.265/AV1 + AAC/G711/Opus | 活跃,GitHub ~2.8k star | 上手首选;摄像头/屏幕/文件多源 |
| StreamPack(Kotlin) | RTMP/SRT | H.265/H.264/VP9/AV1 + AAC/Opus | 活跃 | 新、模块化 |
| anyRTC-RTMP-OpenSource | WebRTC 系,多协议 | 软编为主 | 约 2023-12 后停更(~4.9k star) | 参考价值高,接新版 Android 需自适配 |
| librestreaming | RTMP | MediaCodec | 2020-08 停更,止于 Android 7.0 时代 | 经典教学源码,别直接用于新项目 |
判断开源库能不能用的第一标准不是 star 数,是最近一次提交时间和 Issues 处理速度。音视频库跟系统版本深度耦合,两年不更新的库在新机型上就是炸弹。
2.3 协议选型对照表
| 协议 | 典型延迟 | 传输层 | 强项 | 注意 |
|---|---|---|---|---|
| RTMP | 1–3s(实测波动可达 5s) | TCP | 生态最成熟,推流到 CDN/平台的绝对主流 | 浏览器端已随 Flash 退出,只做推流/服务端中转 |
| RTMP over QUIC | 优于 RTMP,弱网更稳 | QUIC(UDP) | 上行弱网时保画质 | 多为云厂商增值能力,需开通 |
| SRT | ~1s 量级 | UDP | 弱网/跨国专线可靠传输 | 服务器端支持面窄于 RTMP |
| WebRTC | <500ms | UDP | 互动直播唯一现实选择 | 需要 SFU/实时云,不能直接推给普通 CDN |
| LL-HLS | 2–5s | HTTP | 播放端兼容性最好 | 只是”低延迟的 HLS”,不满足互动 |
补充:推流用 RTMP,观看分发用 HLS/HTTP-FLV,由服务器做协议转换。
2.4 很多”直播需求”其实是平台直播
如果目标是把内容推到抖音/B站/快手,且团队没有自研 App 的计划,答案不是写代码,而是获取推流地址/推流码后用 OBS 或推流 App 开播:平台在创建直播场次后给出当场有效的 RTMP 地址与推流码(如 rtmp://domain/AppName/StreamName?鉴权参数)。多平台同推可借助云厂商的”多平台转推”能力。各平台门槛与入口不同,以平台当期规则为准。
只有当你要做”自己的直播 App”,才需要往下读——商业 SDK 的完整落地代码见第四节,决策框架看第二章即可。
三、原理速通:Android 上一条流怎么”跑”起来
虽然落地代码用现成 SDK,但排障时你一定会需要这三块的底层认知,它们决定了你踩坑时能不能自己定位问题。
3.1 采集:摄像头 or 屏幕
- 摄像头:现代 App 用 Camera2 或 CameraX 获取预览帧。注意采集必须与 Activity 生命周期绑定,切后台摄像头会被系统回收。
- 屏幕/录屏:用
MediaProjection + VirtualDisplay。它有两个硬前提:① 必须用户主动授权(系统弹窗);② Android 上屏幕采集依赖前台服务运行,否则系统随时可能掐掉——这条在第五章展开。 - 别在采集层做重处理。美颜、滤镜等图像处理要么走 GPU(OpenGL/Vulkan),要么用 SDK 的自定义前处理通道,把数据导给三方美颜库再送回编码器。
3.2 编码:MediaCodec 与软/硬编取舍
Android 硬件编码统一走 MediaCodec(H.264/HEVC/AV1 视芯片支持而定)。
| 维度 | 硬编(H.264 等) | 软编(x264 等) |
|---|---|---|
| 性能/发热 | 快、省电,主流选择 | 吃 CPU,容易发热降频 |
| 兼容性 | 老机型/部分芯片对 H.265 硬编支持差 | 全平台一致 |
| 画质同码率 | 略低 | 略高(可忽略级别) |
实践建议(2026-09):直播默认 H.264 硬编;追求同画质省码率再上 H.265,但要为不支持硬解的老机型准备降级;AV1 移动端编码暂不具备量产性价比。低端机参考参数:H.264、480p、800kbps、20fps,且系统建议不低于 Android 6.0。
3.3 传输:推流地址是怎么构成的
一个 RTMP 推流地址长这样:
rtmp://推流域名/AppName/StreamName?txSecret=xxx&txTime=yyy
├─ 服务器地址(域名+路径) ├─ 流名称/推流码 ───┴─ 鉴权参数(防盗播,可有可无)
- 自己搭服务器:
rtmp://192.168.1.10:1935/live/stream(IP/域名 + App 名 + 流名)。 - 云厂商 CDN:控制台”地址生成器”生成,带签名防盗链参数。
- 公域平台:创建直播场次后平台下发推流地址+推流码。
推流成败一半看上行带宽:码率设 1500kbps,上行就至少要留 1.5–2Mbps 的稳定余量;用 4G 推流前先做上行测速。观众端卡顿,90% 的根因在推流端上行或服务器,不在观众手机。
四、商业 RTC SDK,五步开播(示例:ZEGO Express SDK)
商业 RTC SDK 的价值不在”少写几行推流”,而在实时云:全球节点、弱网抗丢包、断线重连、连麦与 CDN 旁路一站式解决。示例用 ZEGO 的实时音视频 SDK(ZEGO Express SDK) 推流举例 ,其 Android 文档完整、接口形态典型。
步骤 1:集成 SDK(Maven 自动集成,推荐)
// settings.gradle
dependencyResolutionManagement {
repositories {
maven { url 'https://maven.zego.im' } // ZEGO 私有仓库
google()
mavenCentral()
}
}
// app/build.gradle —— 版本号以官方发布日志为准
implementation 'im.zego:express-video:x.y.z'
<!-- AndroidManifest.xml:网络、摄像头、录音 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
运行时再动态申请 CAMERA、RECORD_AUDIO(Android 6+ 必须)。环境要求:Android 4.4+、支持音视频的真机(模拟器不保证采集正常)、Android Studio 2021.1.1+。
步骤 2:创建引擎(指定直播场景)
// 创建引擎:scenario 告诉 SDK 你的业务场景,它会自动套用合适的音视频初始配置
ZegoEngineProfile profile = new ZegoEngineProfile();
profile.appID = appID; // 控制台申请,long 型
profile.appSign = appSign; // 64 位字符串签名
profile.scenario = ZegoScenario.BROADCAST;// 直播场景(秀场/带货/教育大班课都先选它)
profile.application = getApplication();
ZegoExpressEngine engine = ZegoExpressEngine.createEngine(profile, null);
鉴权说明:2.17.0 及以上,appSign 允许不传,改为在登录房间时通过 ZegoRoomConfig.token 传入服务端生成的 Token(生产环境推荐此方式,权限可控、可过期)。Token 由你的服务端生成,客户端只负责获取与传入,详见使用 Token 鉴权。
步骤 3:登录房间
ZegoUser user = new ZegoUser(userID); // userID 在同 AppID 内全局唯一
ZegoRoomConfig roomConfig = new ZegoRoomConfig();
roomConfig.isUserStatusNotify = true; // 需要监听进出房间回调时开启
engine.loginRoom(roomID, user, roomConfig, (errorCode, extendedData) -> {
if (errorCode == 0) { /* 登录成功,可以推流了 */ }
else { /* 失败,查错误码表 */ }
});
步骤 4:预览并推流
// 先预览,再推流
engine.startPreview(new ZegoCanvas(previewView)); // previewView 为 TextureView 等
engine.startPublishingStream("YOUR_STREAM_ID"); // streamID 在同 AppID 内全局唯一!
到这里,流已经推到 ZEGO 实时云。此时同房间观众用 startPlayingStream(streamID, canvas) 即可低延迟观看(互动直播形态,<400ms 量级)。推流状态通过 onPublisherStateUpdate 回调感知,异常时查错误码表。
步骤 5:推到 CDN ,让”看的人很多但不需要互动”的观众也能看
互动直播只适合有限观众,大并发观众走标准 CDN。两种做法:
做法 A:RTC 房间内推流 + 动态转推 CDN(默认推荐)——推流成功后调用 addPublishCdnUrl,把流转推给任意 RTMP 地址(自家 CDN 或云厂商都行):
// 推流成功后,开始转推到 CDN
String streamID = "YOUR_STREAM_ID";
// 目标 CDN 地址,格式:rtmp://推流域名/接入点/streamID
String url = "rtmp://your-cdn-domain/live/YOUR_STREAM_ID";
engine.addPublishCdnUrl(streamID, url, new IZegoPublisherUpdateCdnUrlCallback() {
@Override
public void onPublisherUpdateCdnUrlResult(int errorCode) {
if (errorCode == 0) { /* 转推成功 */ } else { /* 转推失败 */ }
}
});
要点:可对同一个流多次调用以转推多家 CDN(做容灾或多平台分发);停止转推用 removePublishCdnUrl,stopPublishingStream 不会自动移除转推地址;转推状态变化走 onPublisherRelayCDNStateUpdate 回调;目标地址支持 rtmp/rtmps。完整说明见使用 CDN 直播。
做法 B:直推 CDN(enablePublishDirectToCDN)。流不经实时云中转、直接进 CDN,适合纯单向大并发场景。注意与做法 A 互斥(开启直推后 addPublishCdnUrl 无效),且 CDN 直播能力需在控制台开通后使用。
转推成功后,观众即可用 rtmp://…/…/streamID 或由 CDN 转出的 HLS/FLV 地址在任意播放器观看(VLC、浏览器均支持 FLV/HLS)。验证”推流是否真的成功了”,除了看状态回调,直接用播放器拉这个地址是最快的确认方式(也可通过 URL 拉流的客户端方案)。
进阶:屏幕共享推流(游戏、演示、监控画面)
Android 屏幕采集需要:① 用户授权弹窗;② 前台服务保活。SDK 已封装系统采集,你只需切换采集源:
// 切视频源为屏幕采集(默认是摄像头)
engine.setVideoSource(ZegoVideoSourceType.SCREEN_CAPTURE, ZegoPublishChannel.MAIN);
// 切音频源为屏幕内音频(录屏场景建议同时打开麦克风混音则按需配置)
engine.setAudioSource(ZegoAudioSourceType.SCREEN_CAPTURE, ZegoPublishChannel.MAIN);
清单文件要求(SDK 3.6.0 及以上走 Maven/AAR 集成时可跳过内部 Service 声明,以下为低版本/手动集成所需):
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- targetSdk 34 及以上必须追加 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
详见官方屏幕共享文档。
无服务器快速验证:官方 Web 调试页
接入 RTC 路线最爽的一点:全程不需要自建任何服务器就能联调。ZEGO 提供 Web 端快速开始调试页——填相同 AppID/RoomID、不同 UserID(配控制台”临时 Token”工具生成的 Token),浏览器就能和你的真机进同一个房间互推互拉。
常见问题(FAQ)
Q1:Android 直播推流是什么意思?推流和拉流有什么区别? 推流是主播端把采集编码后的音视频上传到服务器,拉流是观众端从服务器取流播放。推流是”上传”,依赖上行带宽;拉流是”下载”,依赖下行与分发能力。
Q2:Android 直播推流需要服务器吗? 需要接收方。要么自建(SRS、MediaMTX、Nginx-RTMP),要么用云直播/CDN,要么走商业 RTC SDK 的实时云——用 SDK 时服务器由厂商提供,你不需要自己搭。
Q3:Android 推流用 RTMP 还是 WebRTC? 看延迟需求:观众要连麦互动就 WebRTC/RTC(<500ms);传统直播 RTMP(1–5s)即可,且 RTMP 仍是推到 CDN/公域平台的通行协议。低延迟方案见超低延迟直播。
Q4:Android 怎么做直播推流?有哪几种实现方式? 商业 RTC SDK 是产品化的主流选择(最快上线);开源推流库适合学习与原型;从零自研(MediaCodec+librtmp)只建议作为原理练习。选型逻辑见第二章。
Q5:手机直播能推到抖音/B站/快手吗? 能。平台创建直播场次后下发 RTMP 推流地址与推流码,填入 OBS 或支持 RTMP 的推流 App 即可开播;部分平台对第三方推流有粉丝数/认证门槛,以平台当期规则为准。
Q6:RTMP 推流地址和推流码怎么获取? 自建服务器自己定(rtmp://IP:1935/App/流名);云厂商在控制台地址生成器生成;公域平台在开播后台创建场次后下发。推流码等同直播密钥,勿泄露,建议定期轮换。
Q7:直播推流延迟一般多少?怎么降低? RTMP 传统直播 1–5 秒;SRT 约 1 秒;WebRTC/RTC 可到 200–500ms。要低延迟就换协议路线(RTC),同时检查编码缓冲与 CDN 分发链路,别指望在 RTMP+CDN 上抠出毫秒。
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/info/71843.html