我明白为什么B站没法在浏览器开直播了——Windows Chrome推流踩坑全记录

一、信心满满的开局

上一篇文章确定了技术选型:RTMP推流 + SRS转发 + FLV拉流 + WebSocket信令。

但我当时想得有点美:既然SRS 5.0支持WHIP协议,是不是可以写一个简单的网页,让主播打开浏览器就能推流,不用装OBS?

理论上行得通:

  1. getUserMedia 获取摄像头画面,几行代码的事

  2. 创建 RTCPeerConnection,SDP offer发给SRS的WHIP端点

  3. SRS返回answer,连接建立,开始推流

代码很快就写好了,SRS也跑起来了。摄像头画面确实推上去了,SRS后台也能看到流。

然后问题就来了。

二、码率诡异被压:设置4000kbps,实际只有136kbps

我设置的是:

javascript

复制代码
const params = videoSender.getParameters();
params.encodings[0].maxBitrate = 4000000; // 4Mbps
videoSender.setParameters(params);

去SRS后台一看:

text

复制代码
bitrate: 136 kbps

136kbps。一帧1080P的关键帧可能都比这个大。

画面什么样?糊成一团,比马赛克强不了多少。

排查过程

先确认是不是SRS的问题。用OBS推一路RTMP流到同一个SRS实例:

  • OBS NVENC硬编码,码率设置2000kbps

  • SRS后台显示:1950kbps,非常稳定

  • 播放端画面:清晰流畅,1080P 60fps

结论:播放链路没问题,SRS没问题,问题出在浏览器推流这一端。

三、锁定真凶:Windows MediaFoundation H.264硬编码的已知Bug

打开 chrome://webrtc-internals,找到推流的 VideoSendStream,一看:

text

复制代码
codecId: H264 hardware
bitrate: 136kbps

用的是H.264硬件编码,不是软件编码。

顺着这个线索搜了一圈,结果让我哭笑不得------这是一个被多家RTC厂商明确记录的已知Bug:

"在所有使用 AMD 芯片和部分使用 Intel 芯片的 Windows 设备上,Chrome 使用 H.264 编码时,发送码率可能达不到设定值。"------即构科技官方文档

Flashphoner的文档说得更直接:

"在Windows 10/8上Chrome浏览器开启硬件加速时,码率问题可能出现。症状:画面质量低、模糊,chrome://webrtc-internals中显示的码率低于100kbps。"

Stack Overflow上也有开发者遇到了同样的问题。不是SRS的锅,不是WHIP的锅,不是浏览器的锅------是Windows的锅。

为什么会这样?

根本原因在于整条编码链路:

text

复制代码
Chrome WebRTC → Windows MediaFoundation H.264 编码器 → GPU驱动 → 硬件编码单元

Chrome为了降低CPU占用,默认调用Windows的MediaFoundation框架进行H.264硬编码。MediaFoundation再调用GPU(AMD/Intel/NVIDIA)的硬件编码单元。问题就出在GPU驱动层------部分GPU厂商对视频编码的码率做了上限限制,导致无论你设置多大的码率,实际输出都被卡在很低的水平。

四、第一个尝试:强制使用VP8软件编码

既然H.264硬编码有问题,那就绕过它。VP8是Google主推的编码格式,Chrome用的是libvpx软件编码器,完全不经过MediaFoundation。

做法是强制指定VP8为首选编码:

javascript

复制代码
const videoTransceiver = pc.getTransceivers().find(
  t => t.sender.track?.kind === 'video'
);

const caps = RTCRtpSender.getCapabilities('video');
const vp8Codecs = caps.codecs.filter(c => c.mimeType === 'video/VP8');
videoTransceiver.setCodecPreferences(vp8Codecs);

推流,看SRS后台------

码率上去了!2000kbps稳稳的!

还没来得及高兴,问题又来了。

画面开始一顿一顿的,帧率从30fps掉到10-15fps。打开任务管理器一看:

CPU占用:85%+

VP8软件编码正在用CPU死磕视频压缩,把浏览器进程直接拉满了。

五、第二个尝试:关闭浏览器硬件加速

Flashphoner文档里还提了另一个方案:关闭Chrome硬件加速。

原理很简单------强制H.264也走软件编码,绕开GPU驱动的限制。

Chrome设置 → 系统 → 关闭"使用硬件加速模式" → 重启浏览器。

再推流,码率正常了,但画面还是比OBS推的差一些。而且这个方案有个致命问题:你不可能要求每个用户去改浏览器设置。产品化完全走不通。

六、第三个尝试:降低参数勉强妥协

最后试了降分辨率、降帧率、降码率------VP8跑720P、1000kbps,CPU占用降到50%左右,勉强能用。但画质跟OBS推的同码率流比起来,差距明显。

七、回过头看:B站、抖音为什么不用浏览器推流?

踩完这些坑,我回头看B站的直播方案,突然就理解了。

B站直播有两种方式:

  1. 直播姬:B站自研的客户端。本质是OBS套壳,直接调用系统硬件编码器

  2. OBS等第三方工具:获取推流地址后手动配置

两种方式的共同点是:都用原生客户端,不用浏览器。

抖音更严格:根据平台规则,推流分辨率必须≥1080P、码率要达到6-8Mbps,否则会被限流。用浏览器VP8软件编码跑1080P 6Mbps,基本上是在开玩笑。

所以并不是这些大厂"做不到"浏览器推流,而是权衡之后主动选择了不用:

方案 编码方式 CPU占用 画质 码率稳定性 适合场景
OBS推流 GPU硬编码 (NVENC/QSV等) 极低 高 稳定 正式直播
浏览器+VP8 CPU软编码 (libvpx) 极高 中 一般 临时测试
浏览器+H.264 Windows硬编码 低 低 被卡 不推荐

八、最终结论:浏览器推流的定位

经过这一番折腾,我对"浏览器推流"这件事有了清晰的认识:

  1. Windows上浏览器推流有硬伤:MediaFoundation H.264硬编码的码率限制Bug是GPU驱动层面的问题,浏览器和应用层代码都绕不过去

  2. VP8软件编码能绕过限制,但性能代价太大:高清场景下CPU直接拉满,画面卡顿

  3. 浏览器推流适合的场景:快速测试、低分辨率应急开播、对画质要求不高的内部工具

  4. 正式直播还是乖乖用OBS:B站、抖音的选择不是没道理的

所以这个推流网页,我保留了,但定位改了------快速开播测试页,而不是正式的直播工具。主播正式开播时,引导他们用OBS。

技术选型有时候不是找到"最好的方案",而是找到"最适合你场景的方案"。浏览器推流这条路,我走了一遍,踩了坑,也摸清了边界。希望这篇记录能让你少踩几个坑。

相关推荐
子兮曰4 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰4 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万4 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝4 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋4 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁4 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95274 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大4 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师4 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学4 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端