去年有个做知识付费的朋友想开直播,电脑是五年前的老笔记本,装OBS打开就风扇狂转,画面卡得像PPT。问我能不能不装任何软件,纯靠浏览器就能推流开播。我说可以,但方案不止一种,选错了延迟能差出几十倍。
网页直播这件事,技术栈其实很成熟了,但网上教程要么是2018年的Nginx-RTMP老方案(延迟15秒起步),要么上来就是SRS+WebRTC但关键配置一笔带过。这一篇把三套方案放一起讲清楚:轻量方案怎么跑通、进阶方案怎么做到毫秒级延迟、云端方案怎么省成本。
三套方案一句话定位
| 1 | Nginx-RTMP方案:最老牌,教程最多,延迟10-20秒,适合没人看延迟的场景(录播回放、监控画面)。 |
| 2 | SRS+WebRTC方案:延迟400-800毫秒,互动直播首选,配置稍复杂但一次性搞定。 |
| 3 | 云服务托管方案:腾讯云/阿里云直播CDN,零运维,按流量付费,起步快但量大了不便宜。 |
一、Nginx-RTMP方案:半小时跑通,但延迟是硬伤
Nginx加RTMP模块是十年前就有的方案,优势就一个字:稳。全球不知道多少直播平台第一版都是这么搭的。如果你只是想验证"能不能播",或者做一个延迟要求不高的内部培训直播,这套完全够用。
Windows上不需要编译源码,有现成的nginx-rtmp-win打包版,下载解压后改一个配置文件就能跑。核心配置大概长这样:
rtmp {server {listen 1935;application live {live on;# 开启HLS,用于浏览器播放hls on;hls_path html/hls;hls_fragment 3s;}}}配置完启动Nginx,OBS里设置推流地址为 rtmp://你的IP:1935/live/,流名称随便填,点开始推流就通了。
观众端怎么播?RTMP协议浏览器原生不支持,需要转一道。用hls.js播放HLS流最简单,网页上嵌一段:
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script><video id="player" controls></video><script>if (Hls.isSupported()) {var video = document.getElementById('player');var hls = new Hls();hls.loadSource('http://你的IP:8080/hls/流名称.m3u8');hls.attachMedia(video);}</script>但问题来了:HLS切片默认3秒一片,加上缓冲,延迟稳定在10到20秒。弹幕互动就别想了,观众打完字主播可能已经说了三句话了。这也是为什么后来出现了HTTP-FLV和WebRTC两套低延迟方案。

Nginx-RTMP的坑
RTMP走TCP,网络稍微抖一下就会丢帧重传,延迟越堆越高。如果观众超过50人,服务器带宽会直接打满——因为每个人都是直接连你的源站拉流,没有CDN分发。
二、SRS+WebRTC方案:400毫秒延迟,这才是互动直播该有的样子
SRS全称Simple Realtime Server,国内开发者做的开源流媒体服务器,Github上两万多star。它把RTMP推流、WebRTC播放、HLS录制、HTTP-FLV分发全打包在了一起,一个进程搞定所有协议转换。
最舒服的部署方式是Docker,一行命令拉起来:
# 拉取SRS镜像并启动(注意替换服务器IP)docker run -d --name srs \-p 1935:1935 -p 1985:1985 -p 8080:8080 \-p 8000:8000/udp \-e CANDIDATE="你的服务器公网IP" \registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5这个CANDIDATE环境变量是WebRTC能跑通的关键,不设或者设错的话,信令通了但媒体流永远传不过来。如果你用云服务器,填公网IP就行;如果是家里电脑有公网IP,填动态域名也可以。
启动后浏览器访问 http://你的IP:8080/,SRS自带一个Web管理页面,里面就有WebRTC推流播放的demo页面。OBS还是用RTMP推流地址 rtmp://你的IP:1935/live/,观众端访问 webrtc://你的IP:1985/live/流名称,延迟从RTMP的10秒直接降到400-800毫秒。
如果连OBS都不想装,SRS 5.0开始支持WHIP协议,浏览器可以直接推流。在网页里调用navigator.mediaDevices获取摄像头和麦克风,通过WHIP协议把流推给SRS,纯浏览器完成推流+播放的闭环。这对做教学直播、在线面试、远程协助这类场景特别实用——用户不需要安装任何东西。
SRS方案适用场景
互动直播、在线教育、游戏直播、视频会议——任何需要低延迟、有弹幕互动的场景。延迟400毫秒意味着观众发弹幕,你几乎同时看到。
SRS方案的硬门槛
需要一台有公网IP的服务器,Docker环境,以及开放1935/8000/8080等端口。如果用的是NAT网络(比如公司内网),WebRTC需要额外配置TURN服务器做NAT穿透。
三、SRS的WebRTC播放器:网页端怎么写
SRS的WebRTC播放不需要第三方库,原生WebRTC API就能搞定。核心代码不到30行:
const pc = new RTCPeerConnection();const streamUrl = 'webrtc://你的IP:1985/live/livestream';// 接收远端视频流pc.ontrack = (event) => {document.getElementById('player').srcObject = event.streams[0];};// 创建SDP offerconst offer = await pc.createOffer();await pc.setLocalDescription(offer);// 向SRS发送offer,获取answerconst res = await fetch('http://你的IP:1985/rtc/v1/play/', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({api: 'http://你的IP:1985/rtc/v1/play/',streamurl: streamUrl,sdp: btoa(JSON.stringify(pc.localDescription))})});const data = await res.json();await pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(data.sdp))));如果觉得手写WebRTC代码麻烦,可以用SRS官方提供的srs-player.js,封装好了推流和播放逻辑。或者直接用video.js搭配WebRTC插件,界面更美观,自带播放控制条。
四、三种播放协议的延迟和兼容性,选错了白折腾
很多人在这一步绕弯——花了两天搭好服务器,结果网页上播不出来,以为是配置问题,其实只是播放协议选错了。
| 协议 | 延迟 | 浏览器支持 | 播放器 | 适用场景 |
|---|---|---|---|---|
| HLS | 10-30秒 | 全部浏览器、移动端原生支持 | hls.js / video.js | 录播回放、大型直播(配合CDN) |
| HTTP-FLV | 2-5秒 | PC端Chrome/Edge(需flv.js),移动端不支持 | flv.js | PC端中等延迟直播 |
| WebRTC | 400-800毫秒 | Chrome/Firefox/Edge/Safari全支持 | 原生API / srs-player.js | 互动直播、连麦、视频会议 |
一个实用的策略是多协议同时输出:SRS配置里同时开启HLS和WebRTC,PC端观众走WebRTC享受低延迟,手机端观众走HLS保证兼容性。观众不用关心协议,前端判断一下浏览器能力自动切换就行。
移动端H5播放的坑
flv.js在移动端基本不能用(iOS Safari不支持MSE的flv格式),所以如果你的观众主要在手机上看,要么走HLS,要么走WebRTC,别在HTTP-FLV上花时间。另外iOS Safari的WebRTC需要HTTPS,记得给域名配SSL证书。
五、带宽和成本算清楚再动手,不然后面续费想哭
直播最烧钱的不是服务器本身,是带宽。很多人买了个2核4G的云服务器觉得够用了,结果直播一开,观众超过20个人就开始卡,以为是配置不够又升级到4核8G,发现还是卡——问题根本不在CPU,在带宽。
一个简单的计算公式:总带宽 = 视频码率 × 并发观众数 × 1.5(冗余系数)。假设你推流码率是2Mbps(720P画质),有50个人同时观看,你需要 2 × 50 × 1.5 = 150Mbps的上行带宽。而大多数云服务器默认只给1-5Mbps。
10人在线(720P)
30Mbps
约300元/月带宽费

50人在线(720P)
150Mbps
约1500元/月带宽费
100人在线(720P)
300Mbps
源站扛不住,必须上CDN
超过50个观众,自建源站直接分发就不现实了。这时候有两个选择:
方案A:自建源站 + CDN分发。源站只负责接收推流和转封装,观众的拉流请求全部走CDN边缘节点。CDN按流量计费,国内大概0.2-0.3元/GB。一个观众看一小时720P直播大概消耗1GB流量,100个观众看两小时就是200GB,CDN费用约50块钱。这个成本结构比升级服务器带宽划算太多了。
方案B:直接用云厂商的直播服务。腾讯云、阿里云都有直播产品,推流地址和播放域名配好就能用,背后自动走CDN分发。按流量计费,和自建CDN价格差不多,但省了运维——不用管服务器重启、证书续期、端口被扫这些事。
| 对比维度 | 纯自建(SRS) | 自建源站+CDN | 云直播服务 |
|---|---|---|---|
| 延迟 | 400-800ms | HLS: 10-30s / FLV: 2-5s | 2-5s(标准)/ 400ms(低延迟) |
| 运维成本 | 高(自己管服务器) | 中(管源站+配CDN) | 低(配域名就行) |
| 小规模费用(<50人) | 服务器200元/月+带宽 | 源站100元+CDN按量 | 按流量,起步0成本 |
| 大规模费用(>500人) | 带宽费用失控 | CDN费用为主,可控 | CDN费用为主,可控 |
| 自由度 | 最高 | 高 | 受限于平台功能 |
六、网页直播间怎么做才不像山寨网站
流媒体搭好了,前端页面如果只是一个裸的video标签加黑底,观众打开三秒就想关。一个像样的网页直播间至少要有这几样东西:
· 播放器皮肤:用video.js或者plyr,自带播放/暂停、音量、全屏、进度条,不用自己画UI。
· 弹幕系统:WebSocket连接,观众发弹幕→服务器广播→前端飘屏。轻量场景用Socket.IO就能搞定,几千人并发换用Go写的WebSocket服务。
· 在线人数:WebSocket连接计数,前端实时刷新数字。注意别用短轮询,一秒一次HTTP请求几百个观众服务器直接崩。
· 自适应码率:SRS可以输出多个码率的HLS流,观众端根据网速自动切清晰度,网络差也不卡死。
如果你是用UC建站系统搭的站点,做直播页面有个天然优势:HTML直出、不依赖前端框架的客户端渲染。直播页面本质上就是一个静态HTML加JS播放器,百度蜘蛛爬得到完整的页面结构,不会因为JS渲染不完整导致收录失败。加上独立IP和独立域名部署,直播间的SEO权重不会和其他站点混在一起。
七、NAT网络和HTTPS,两个最容易卡住的地方
第一个卡点:服务器没有公网IP。公司内网、家用宽带(没申请公网IP)、校园网,这些NAT网络下WebRTC的P2P直连大概率失败。这时候需要在SRS配置里指定TURN服务器做中继转发。推荐用coturn搭一个TURN服务,或者直接用腾讯云、Twilio的托管TURN,按流量计费不贵。
第二个卡点:HTTPS和WebRTC的关系。浏览器安全策略要求,在HTTPS页面里调用getUserMedia(获取摄像头麦克风)必须是localhost或者HTTPS。如果你的网页是HTTP的,Chrome会直接拒绝——连弹窗都不会有,控制台里一行红字。解决方案就一个:给域名配SSL证书,免费的Let's Encrypt足够用。
端口别忘了开
云服务器安全组和系统防火墙都要放行:1935(TCP)、1985(TCP)、8080(TCP)、8000(UDP)。很多人只改安全组忘了iptables/firewalld,排查半天发现是系统防火墙没关。
Docker的网络模式
SRS用Docker部署时,UDP 8000端口映射必须加/udp后缀,少写这个WebRTC的媒体流永远传不进来。另外host网络模式比bridge模式更适合WebRTC,少了NAT转换这一步。
说到底,网页直播的技术选型没有标准答案,全看你的场景在哪个象限。延迟要求不高、观众少——Nginx-RTMP够用,零学习成本。要互动、要连麦——上SRS+WebRTC,400毫秒延迟和10秒是完全两种体验。观众数量不确定、不想运维——云直播服务虽然单价比自建高,但省下的时间是实打实的。
有个容易被忽略的细节:不管你选哪套方案,先把HTTPS和域名搞定再开始搭服务器。很多人在IP地址上把整套流程跑通了,换成域名配HTTPS的时候发现WebRTC连不上、HLS跨域报错,又得回头排查。顺序反了多花半天时间。
用UC建站系统做直播站的话,独立IP部署和HTTPS证书都是标配,域名解析配好了直接就能进入推流配置环节,不用在基础环境上耗时间。多站看板还能统一监控每个直播间的在线人数和带宽消耗,比一个服务器一个服务器登上去看省事得多。
