Chrome DevTools可以直接查看binary类型数据包了!
连接
通过Chrome DevTools可以看到,网页版B站直播的弹幕通过 wss://tx-sh3-live-comet-04.chat.bilibili.com/sub 传输,这个地址每次是不一样的。需要通过 https://api.live.bilibili.com/room/v1/Danmu/getConf?room_id=房间号&platform=pc&player=web 获得wss地址 (应该是负载均衡的需要,实际测试连接任意wss地址都能正常获取弹幕) 。
封包头部16个字节用于标识数据包的长度及类型,数据包格式详见下表。字节序均为大端模式。参考:https://blog.csdn.net/xfgryujk/article/details/80306776
| 偏移 | 长度 | 类型 | 含义 |
|---|---|---|---|
| 0 | 4 | int | 数据包长度 |
| 4 | 2 | int | 数据包头部长度,固定为 16 |
| 6 | 2 | int | 数据包协议版本(见下文) |
| 8 | 4 | int | 数据包类型 (见下文) |
| 12 | 4 | int | 固定为 1 |
| 16 | – | byte[] | 数据主体 |
| 数据包协议版本 | 含义 |
|---|---|
| 0 | 数据包有效负载为未压缩的JSON格式数据 |
| 1 | 客户端心跳包,或服务器心跳回应(带有人气值) |
| 2 | 数据包有效负载为通过zlib压缩后的JSON格式数据 |
| 数据包类型 | 发送方 | 名称 | 含义 |
|---|---|---|---|
| 2 | 客户端 | 心跳 | 不发送心跳包,50-60秒后服务器会强制断开连接 |
| 3 | 服务器 | 心跳回应 | 有效负载为直播间人气值 |
| 5 | 服务器 | 通知 | 有效负载为礼物、弹幕、公告等内容数据 |
| 7 | 客户端 | 认证(加入房间) | 客户端成功建立连接后发送的第一个数据包(见下文) |
| 8 | 服务器 | 认证成功回应 | 服务器接受认证包后回应的第一个数据包 |
客户端建立连接后,需要在5秒内发出加入房间(认证)的数据包,否则会被服务器强制断开连接。其中有效负载的key字段内容可以从之前的 https://api.live.bilibili.com/room/v1/Danmu/getConf?room_id=房间号&platform=pc&player=web 获取。如发送的认证包格式错误,服务器会立刻强制断开连接,JSON字段的详细说明见下表。

| 字段 | 类型 | 必选 | 含义 |
|---|---|---|---|
| uid | number | × | 用户UID |
| roomid | number | √ | 房间号 |
| protover | number | × | 协议版本,目前为 2 |
| platform | string | × | 平台,可以是 web |
| clientver | string | × | 客户端版本,可以是 “1.8.5” |
| type | number | × | 未知,可以是 2 |
| key | string | × | 用户标识,通过之前提到的接口获取 |
心跳
心跳包建议每30秒发一次,头部16字节遵守上文规则,负载内容随意。(b站通过传入一个空对象来生成心跳包,然后就有了我之前无法理解的心跳包内容)

通知(弹幕、公告、礼物等)
有新的弹幕、礼物或其他公告时,服务器会发送类似下图的数据包,首先需要使用 zlib.inflate 解压数据主体部分(除头部16字节外)。解压后的数据头部十六字节与原数据头相同,去除头部后即为JSON格式数据
这里我们以一个弹幕数据包为例子


可以看到解压后的数据依然带有头部(16字节),去除头部后即为JSON格式数据,其中的cmd字段更为详细地描述了数据包类型。其中比较明显的是,['info'][1] 代表弹幕内容, ['info'][2][1] 为发送者,['info'][9]['ts'] 为发送时间戳,cmd的已知格式参考下表
| cmd字段 | 含义 |
|---|---|
| DANMU_MSG | 收到弹幕 |
| SEND_GIFT | 有人送礼 |
| WELCOME | 欢迎加入房间 |
| WELCOME_GUARD | 欢迎房管加入房间 |
| SYS_MSG | 系统消息 |
| PREPARING | 主播准备中 |
| LIVE | 直播开始 |
下面我展示了几个常见cmd的数据包JSON格式,还有很多活动通知cmd,各位可以自行抓取(如下面的 ACTIVITY_BANNER_UPDATE_V2 就是我写文章当天出现的活动通知cmd类型)
后记:Chrome支持直接显示WebSocket二进制包真的能节省很多时间。吹爆 Chrome!
