H5 直播方案指南:从看、播、连麦选型到上线实现

2026/10/22

H5 直播在工程上是三种完全不同的东西。多数方案失败,是因为把"网页看直播"和"网页开直播"当成了一件事。本文结合 ZEGO RTC 的能力,讲清 H5 直播的三种形态(观看、浏览器推流、双向连麦),再按延迟预算选 HLS、HTTP-FLV 或 WebRTC 等协议,附可运行代码与兼容性兜底。

1. 先分清:你要的是"能看"还是"能播"?

形态谁在推流H5 负责什么协议典型场景
纯观看App、OBS、摄像机只拉流播放HLS / HTTP-FLV / WebRTC活动直播、公开课、发布会
浏览器推流主播自己的浏览器采集 + 推流 + 本地预览WebRTC网页开播、远程面试、在线客服
双向连麦主播 + 上麦观众推流 + 同时拉多路流WebRTC + 混流连麦直播、互动课堂

三条边界

  1. 传统 H5 直播页只拉流。 HLS 和 HTTP-FLV 都是单向分发协议,播放器没有上行通道。
  2. 浏览器推流默认 WebRTC 一条路。 不自建 WebRTC,就用封装了 WebRTC 能力的 SDK(比如ZEGO Express Web SDK)。
  3. RTMP 在 H5 里不能直接播。 Flash 已被主流浏览器彻底移除,RTMP 现在的角色是推流和服务端内部传输。

决策顺序

有没有主播端?
├─ 没有 → 纯观看:选 HLS / FLV / RTC 播放
└─ 有 → 主播在哪推流?
    ├─ App / OBS → H5 仍是纯观看
    └─ 浏览器 → WebRTC 推流
        └─ 观众要不要上麦?
            ├─ 不要 → 单路推流 + CDN 分发
            └─ 要 → RTC 房间 + 混流

和 App 直播、小程序直播的对比

维度H5 直播App 直播小程序直播
安装成本无需下载需跳转授权
传播能力最强,链接直达弱中
推流能力WebRTC,受浏览器限制完整可控受平台限制
延迟可控性取决于协议最强中
后台播放基本不可用支持支持
适合场景活动、公开课、轻量带货长期直播业务微信生态内转化

2、协议选型:先定延迟预算,再定协议

选协议前,先问清自己的业务能容忍多少延迟。

五种协议对比

维度HLSLL-HLSHTTP-FLVWebRTCRTMP
典型延迟10s 以上(优化后 5–10s)2–5s1–3s0.2–1s1–3s
首帧较慢中快最快—
iOS 播放原生支持需系统支持无 MSE√×
安卓播放需 hls.js⚠️√ MSE√×
CDN 友好度最高高中低(需 SFU)低
实现成本低中中高中
适合场景大并发观看、回放中低延迟观看低延迟观看连麦、强互动推流入口

延迟为典型区间,实际受切片时长、GOP、播放器缓冲策略和网络状况影响,不同厂商口径存在差异。

延迟预算决策表

业务能容忍的延迟选什么代价
< 1 秒WebRTC兼容性要求高、带宽成本高、需要 SFU 或 RTC 服务
1–3 秒HTTP-FLV(非 iOS)+ HLS 兜底要做双协议,要处理延迟累积
3–10 秒LL-HLS 或优化后的 HLS需要服务端支持低延迟切片
> 10 秒标准 HLS兼容性最好,成本最低

多协议同源输出

成熟的做法不是一个端选一个协议,而是一条源流,多协议输出:

主播推流(RTMP / WebRTC)
        ↓
   流媒体服务器 / RTC 服务
        ↓
┌────────┬─────────┬──────────┐
HLS      HTTP-FLV   WebRTC
(全平台)  (安卓/桌面) (低延迟端)

服务端负责把同一路流转成多种格式,前端根据浏览器能力选择。这样既不用维护多套推流,也不会被单一协议的短板卡死。

3、观看端实现的方案

观看端有三条实现路径。 选一条主路,再准备一条备用路,不要只写一条。

方案延迟兼容性依赖适用
A. video + hls.js高最好hls.js大并发、兼容优先
B. flv.js / mpegts.js中安卓/桌面MSE低延迟观看
C. RTC SDK最低现代浏览器SDK + 服务端强互动、低延迟

以 RTC SDK(以ZEGO Express Web SDK为例):

安装:

npm install zego-express-engine-webrtc

完整拉流链路:

import { ZegoExpressEngine } from 'zego-express-engine-webrtc';

const appID = 123456789;                  // ZEGO 控制台获取
const server = 'YOUR_SERVER_ADDRESS';     // 控制台「项目信息」中的 Server 地址
const roomID = 'live_room_001';
const userID = 'viewer_' + Date.now();
const streamID = 'stream_001';
// Token 必须由业务服务端签发,前端只拿结果
const tokenRes = await fetch(`/api/live/token?roomID=${roomID}&userID=${userID}`);
const { token } = await tokenRes.json();

const zg = new ZegoExpressEngine(appID, server);

// 1. 能力检测:不支持 WebRTC 就不要继续
const support = await zg.checkSystemRequirements();
if (!support.webRTC) {
  // 降级到 HLS
  throw new Error('当前浏览器不支持 WebRTC');
}

// 2. 登录房间
const loginOK = await zg.loginRoom(
  roomID,
  token,
  { userID, userName: userID },
  { userUpdate: true }
);
if (!loginOK) throw new Error('登录房间失败');

// 3. 拉流并渲染
const remoteStream = await zg.startPlayingStream(streamID);
const remoteView = zg.createRemoteStreamView(remoteStream);
remoteView.play('remote-video', { enableAutoplayDialog: true });

// 4. 首帧回调
remoteView.on('canPlayVideo', () => {
  console.log('首帧渲染完成');
});

// 5. 拉流状态
zg.on('playerStateUpdate', (result) => {
  console.log('拉流状态变更', result);
});

4、推流端实现:浏览器开播的边界与代码

浏览器能推流,只在 WebRTC 路线上成立。 而且要同时满足四个条件:HTTPS、用户授权、iOS 14.3 以上、浏览器内核可用。

第一步:采集

let localStream;

try {
  localStream = await navigator.mediaDevices.getUserMedia({
    video: {
      width: { ideal: 1280 },
      height: { ideal: 720 },
      frameRate: { ideal: 30 },
      facingMode: 'user',
    },
    audio: {
      echoCancellation: true,
      noiseSuppression: true,
    },
  });
  document.getElementById('preview').srcObject = localStream;
} catch (err) {
  switch (err.name) {
    case 'NotAllowedError':
      // 用户拒绝授权,或页面不是 HTTPS
      break;
    case 'NotFoundError':
      // 没有摄像头 / 麦克风
      break;
    case 'NotReadableError':
      // 设备被其他程序占用
      break;
    case 'OverconstrainedError':
      // 约束条件当前设备满足不了,降低分辨率重试
      break;
  }
}

第二步:推流(以 ZEGO RTC 为例)

// 创建本地流(节选)
const zegoLocalStream = await zg.createZegoStream();

// 推流
const publishOK = zg.startPublishingStream(streamID, zegoLocalStream);

// 监听推流状态
zg.on('publisherStateUpdate', (result) => {
  if (result.state === 'PUBLISHING') {
    console.log('推流成功');
  }
});

什么时候需放弃 H5 推流

出现下面情况,建议不要在浏览器里硬做:

  • 主播需要稳定的长时间开播(浏览器标签页会被降频、休眠)。
  • 需要屏幕共享且用户在移动端。
  • 用户主要在企业微信里打开。
  • 需要美颜、滤镜、多机位等前处理能力。
  • 推流并发规模大,且对失败率敏感。

这些场景应该改用 App 或 OBS 推流,H5 只承担观看。

5、兼容性:上线前必须验证的 5 个场景

H5 直播的线上事故,八成来自环境,不是代码。 上线前可过一遍:

场景 1:微信内置浏览器

微信的 WebView 内核和系统浏览器不是同一个。iOS 走 WKWebView,安卓走 X5 / XWeb。

  • 拉流、推流都支持,屏幕共享不支持。
  • 首次安装或清理数据后,内核可能还没下载完,此时采集会失败。等 Wi-Fi 下自动下载完成再试。
  • 微信内无法通过配置放开自动播放限制,必须做用户手势兜底。

场景 2:企业微信内置浏览器

和微信不同:企业微信可以拉流,但不能推流,也不能屏幕共享。

如果产品同时投放微信和企业微信,要按 UA 分别判断,不能只判断是不是微信。

场景 3:iOS Safari

  • video 默认会全屏接管,必须加 playsinline 和 webkit-playsinline。
  • 低电量模式下,连静音自动播放都可能被禁止。
  • iPhone 不支持 MSE,FLV 方案直接不可用。

场景 4:安卓 X5 内核接管视频

部分安卓浏览器(尤其 X5 内核)会用自己的播放器接管 video 标签,导致自定义控件、弹幕层、封面全部失效。

处理方式:

  • 给 video 加 webkit-playsinline、x5-playsinline、x5-video-player-type="h5"。
  • 仍被接管时,联系内核方为域名开白名单,或引导用户跳转系统浏览器。

上线前的检测代码

ZEGO Web SDK 提供了统一的能力检测,一次拿到所有关键项:

const result = await zg.checkSystemRequirements();
console.log(result);
// {
//   webRTC: true,
//   customCapture: true,
//   camera: true,
//   microphone: true,
//   videoCodec: { H264: true, H265: false, VP8: true, VP9: true },
//   screenSharing: true,
//   errInfo: {}
// }

用法: 页面初始化时先跑一次,把结果存进全局状态,后续所有功能入口按它来显隐——不支持推流就不显示「开播」按钮,不支持屏幕共享就不显示「共享屏幕」。

六、自建还是买:三条路线的成本结构

决定成本的不是自建还是买,是并发数 × 码率 × 时长。 先算带宽,再谈路线。

先算带宽

所需出口带宽(Mbps) ≈ 并发观看数 × 单路平均码率(Mbps) × 冗余系数

冗余系数一般取 1.2–1.5,用于覆盖峰值波动和协议开销。

举例:1000 人同时看 720p、平均码率 2 Mbps 的流,理论出口带宽约 2000 Mbps,加 1.3 的冗余系数就是 2.6 Gbps。这个量级已经不可能靠单台服务器扛,必须上 CDN。

三条路线

维度自建(SRS / ZLMediaKit)云直播 CDNRTC 厂商
前期投入高(服务器、带宽、部署)低低
运维负担高,需要专人低低
延迟能力可做到 FLV 级,WebRTC 需自己搭中最低
弹性扩容差,要提前采购好好
适合规模稳定大流量、有强合规要求大多数业务强互动业务
主要风险带宽成本和故障自担厂商绑定厂商绑定、单价较高

判断线

  • 日活较低、没有专职音视频运维:可直接用云服务,自建的人力成本远高于节省的流量费。
  • 流量稳定且规模大、有合规或私有化要求:自建源站 + 外采 CDN,把可控性和弹性分开。
  • 延迟要求低于 1 秒:不要在自建上纠结,直接选 RTC 厂商。

常见问题

H5 可以推流吗?

可以,但只能走 WebRTC。浏览器用 getUserMedia 采集后推流,要求 HTTPS、用户授权、iOS 14.3 以上,企业微信内置浏览器不支持推流。

H5 直播延迟一般是多少?

取决于协议。HLS 通常 10 秒以上,HTTP-FLV 约 1 到 3 秒,WebRTC 可低于 1 秒。要 1 秒内只能选 WebRTC,代价是兼容性和成本。

H5 直播一定要用 HTTPS 吗?

推流必须,纯播放不强制。浏览器只在 HTTPS 等安全上下文开放 getUserMedia,HTTP 页面采不到摄像头。HLS 或 FLV 拉流走 HTTP 也能工作。

H5 直播在 iPhone 上为什么播不了 FLV?

iPhone 的 Safari 不支持 MSE,而 flv.js 依赖 MSE 转封装 FLV。iOS 只能播原生 HLS 的 m3u8,或改用 WebRTC,所以必须做双协议。

H5 直播和 App 直播有什么区别?

H5 免安装、传播快、成本低,但推流和低延迟受浏览器限制。App 能控制采集与缓冲,延迟更可控。延迟高低主要由协议决定,与 H5 或 App 无关。

最新文章
如何评估实时音视频服务商:先问这 7 个问题
2026/11/02
ZEGO 声纹识别能力上线:大幅提升嘈杂环境下 AI 语音互动体验
2026/10/29
ZEGO 实时互动 AI Agent 2.15.0 发布:更自然的对话,更灵活的数字人
2026/10/28
AOMedia:AV2 发布仅四个月即在视频生态中快速普及
2026/10/26
H5 直播方案指南:从看、播、连麦选型到上线实现
2026/10/22
扫一扫,获取更多服务与支持
关注我们
获得更多服务与支持了解价格与优惠 扫码关注我们
关注我们
获得更多服务与支持了解价格与优惠 扫码关注我们