Android 怎么做直播推流:从原理、协议选型到代码实现

想在 Android 上做直播推流,多数人第一反应是”找 SDK 或源码”。但动手前可以思考几个问题:推给谁?延迟要多低?用自研还是商业方案?推到第三方平台如抖音和推到自建服务器不是一回事。

本文先给三条直接可用的结论,再讲清楚背后的取舍,最后以 ZEGO Express SDK 为例,给出从集成到上架的一条完整可跑路线:

  1. 直播推流 = 采集 → 编码 → 上行传输 → 服务器/云接收 → 分发 → 播放。一般您的工作重点在前三段,后三段由服务器(或云厂商)解决。
  2. 技术路线取决于延迟要求:互动场景(连麦、PK、教学问答)选 WebRTC/RTC 方案(<500ms);传统直播(秀场、电商,1–5s 可接受)选 RTMP 方案;RTMP 依然是手机推流的事实标准,但不是唯一答案。
  3. 实现方式按成本排序:商业 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)<500msWebRTC / 私有 UDP 优化协议同协议或旁路 CDN连麦 PK、在线教育提问、带货互动、游戏开黑
传统直播(CDN)1–5sRTMP(或 SRT)HLS / HTTP-FLV秀场、演唱会、赛事、监控观看
平台直播秒级 ~ 平台决定平台推流码(RTMP)平台 App 播放推到抖音、B站、快手做内容分发

形态决定了协议,协议决定了后面所有的代码和服务器选型。交互需求是延迟的根源:只要观众需要”说话给主播听”,就走互动直播;否则传统 CDN 更便宜、并发更大。

二、选型:看路线对比

动手前先回答:

  1. 推给谁:只有自己 App 的观众?还是抖音/B站/快手的用户?
  2. 延迟要求:能不能容忍 1–5 秒?观众要不要连麦互动?
  3. 团队与预算:有没有专职音视频工程师?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/UDPH.264/H.265/AV1 + AAC/G711/Opus活跃,GitHub ~2.8k star上手首选;摄像头/屏幕/文件多源
StreamPack(Kotlin)RTMP/SRTH.265/H.264/VP9/AV1 + AAC/Opus活跃新、模块化
anyRTC-RTMP-OpenSourceWebRTC 系,多协议软编为主约 2023-12 后停更(~4.9k star)参考价值高,接新版 Android 需自适配
librestreamingRTMPMediaCodec2020-08 停更,止于 Android 7.0 时代经典教学源码,别直接用于新项目

判断开源库能不能用的第一标准不是 star 数,是最近一次提交时间和 Issues 处理速度。音视频库跟系统版本深度耦合,两年不更新的库在新机型上就是炸弹。

2.3 协议选型对照表

协议典型延迟传输层强项注意
RTMP1–3s(实测波动可达 5s)TCP生态最成熟,推流到 CDN/平台的绝对主流浏览器端已随 Flash 退出,只做推流/服务端中转
RTMP over QUIC优于 RTMP,弱网更稳QUIC(UDP)上行弱网时保画质多为云厂商增值能力,需开通
SRT~1s 量级UDP弱网/跨国专线可靠传输服务器端支持面窄于 RTMP
WebRTC<500msUDP互动直播唯一现实选择需要 SFU/实时云,不能直接推给普通 CDN
LL-HLS2–5sHTTP播放端兼容性最好只是”低延迟的 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" />

运行时再动态申请 CAMERARECORD_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(做容灾或多平台分发);停止转推用 removePublishCdnUrlstopPublishingStream 不会自动移除转推地址;转推状态变化走 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

(0)

相关推荐