头图

如今,市面上已经有不少开源项目可以用于连接 B 站直播 WebSocket 获取信息流。

但在实际使用中,常常发现它们并不能完全满足个性化需求。

为了更好地适配自己的业务场景,我决定自己动手实现一套连接方案。

因此,我整理了整个实现过程的一些关键步骤和注意事项,希望能够对有相似需求的朋友们有所帮助

PHP可以直接通过 composer 安装相关库来直接链接B站直播间并对数据进行解密,点击前往GitHub

也有现成的 B站机器人弹幕监控,支持礼物答谢、定时广告、关注感谢,自动回复等,内置积分商城,可通过 docker 快速部署,点击前往GitHub

接入前准备

获取直播间真实ID

网页版 直播间URL 携带的房间号可能是短号,并不保证一定为真实地址,因此建议调用该接口以确保房间号无误


请求方式:GET

请求地址:https://api.live.bilibili.com/room/v1/Room/get_info

参数名类型内容
room_idint直播间 ID
请求响应示例与字段说明
curl -G 'https://api.live.bilibili.com/room/v1/Room/get_info' \
--data-urlencode 'room_id=27668995'
{
    "code": 0,
    "msg": "ok",
    "message": "ok",
    "data": {
        "uid": 3493124609411229, // 主播id
        "room_id": 27668995, // 真实房间id
        "short_id": 0, // 直播间短号,0为无短号
        "attention": 13353, // 关注数量
        "online": 4173, // 观看人数
        "is_portrait": false, // 是否是竖屏
        "description": "一只屑狐狸,不专业的CV,新晋歌杂,不缺席你的每一天...直播时间: 晚22:00-02:00,下午3:00-7:00闪现打游戏", // 描述
        "live_status": 1, // 直播间状态:0-未开播,1-直播中,2-轮播中
        "area_id": 371, // 分区id
        "parent_area_id": 9, // 父分区id
        "parent_area_name": "虚拟主播", // 父分区名称
        "old_area_id": 6, // 旧版分区id
        "background": "", // 背景图片链接
        "title": "不给糖就捣蛋", // 标题
        "user_cover": "https://i0.hdslb.com/bfs/live/new_room_cover/22426f0ead9804fabd06ad1c4305e2641a4e6d11.jpg", // 封面
        "keyframe": "https://i0.hdslb.com/bfs/live-key-frame/keyframe11011431000027668995752wsi.jpg", // 关键帧
        "is_strict_room": false, // 待观测
        "live_time": "2024-11-01 14:25:09", // 开播时间
        "tags": "御姐,屑狐狸,狐仙,憨憨,温柔", // 标签
        "is_anchor": 0, // 待观测
        "room_silent_type": "", // 禁言状态
        "room_silent_level": 0, // 禁言等级
        "room_silent_second": 0, // 禁言等级(单位秒)
        "area_name": "虚拟日常", // 分区名称
        "pendants": "", // 待观测
        "area_pendants": "", // 待观测
        "hot_words": [
            "2333333",
            "喂,妖妖零吗",
            "红红火火恍恍惚惚",
            "FFFFFFFFFF",
            "Yooooooo",
            "啪啪啪啪啪",
            "666666666",
            "老司机带带我",
            "你为什么这么熟练啊",
            "gg",
            "prprpr",
            "向大佬低头",
            "请大家注意弹幕礼仪哦!",
            "还有这种操作!",
            "囍",
            "打call",
            "你气不气?",
            "队友呢?"
        ], // 热词
        "hot_words_status": 0, // 热词状态    
        "verify": "", // 待观测
        "new_pendants": { // 头像框
            "frame": { // 头像框信息
                "name": "大乱斗乱斗之王", // 名称
                "value": "https://i0.hdslb.com/bfs/live/fc28a2a4123154012e0ce3da1273de5f17e81b24.png", // 头像框图片URL
                "position": 0, // 位置
                "desc": "", // 描述
                "area": 0, // 分区
                "area_old": 0, // 旧分区
                "bg_color": "", // 背景色
                "bg_pic": "", // 背景图
                "use_old_area": false // 是否旧分区号
            },
            "badge": { // 大V才会有的信息
                "name": "v_person", // 认证类型:v_person=个人认证(黄),v_company=企业认证(蓝)
                "position": 3, // 位置,可能是个枚举
                "value": "", // 待观测
                "desc": "bilibili 知名UP主、直播高能主播" // 描述
            },
            "mobile_frame": { // 头像框信息,手机版,可能为null
                "name": "大乱斗乱斗之王", // 名称
                "value": "https://i0.hdslb.com/bfs/live/fc28a2a4123154012e0ce3da1273de5f17e81b24.png", // 头像框图片URL
                "position": 0, // 位置
                "desc": "", // 描述
                "area": 0, // 分区
                "area_old": 0, // 旧分区
                "bg_color": "", // 背景色
                "bg_pic": "", // 背景图
                "use_old_area": false // 是否旧分区号
            },
            "mobile_badge": { // 大V才会有的信息,手机版,可能为null
                "name": "v_person", // 认证类型:v_person=个人认证(黄),v_company=企业认证(蓝)
                "position": 3, // 位置,可能是个枚举
                "value": "", // 待观测
                "desc": "bilibili 知名UP主、直播高能主播" // 描述
            }
        },
        "up_session": "557568462506308099", // 待观测
        "pk_status": 0, // pk状态
        "pk_id": 0, // pk id    
        "battle_id": 0, // 待观测
        "allow_change_area_time": 0, // 待观测
        "allow_upload_cover_time": 0, // 待观测
        "studio_info": { // 待观测
            "status": 0, // 待观测
            "master_list": [

            ]
        }
    }
}

获取信息流认证秘钥

该接口可以获取到对应直播间信息流的链接地址,以及建立链接需要认证的token信息

注意: B 站更新了隐私政策, 连接建立 5 分钟左右, 若该连接认证时传入信息来自未登录用户, 会提示 为保护用户隐私,未注册登陆用户将无法查看他人昵称, 随后所有发送弹幕的用户 id 都为 0, 用户名部分也使用 * 保护,因此调用本接口时需要传递 cookie

注意: wswss 连接地址带有路径 /sub, 如 wss://tx-sh-live-comet-08.chat.bilibili.com:443/sub


请求方式:GET

请求地址:https://api.live.bilibili.com/xlive/web-room/v1/index/getDanm...

参数名类型内容
idint直播间真实id
请求响应示例与字段说明
curl -G 'https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo' \
--data-urlencode 'id=30118851'
{
    "code":0, // 0:成功,65530:token错误(登录错误),1:错误,60009:分区不存在,其他错误仍需观察
    "message":"0", // 错误信息
    "ttl":1, // 默认为1
    "data":{ // 信息本体
        "group":"live", // 不重要,默认live
        "business_id":0, // 不重要,默认 0
        "refresh_row_factor":0.125, // 不重要,默认0.125
        "refresh_rate":100, // 不重要,默认100
        "max_delay":5000, // 不重要,默认5000
        "token":"TrF6FaSlmxVBM4eBYGoaWPuZ-xVL-bhK80waLbGRfpj6JiLkjgaxLcu5whFM6iEBrQFw8wJwdraBJwkctMzMrkyP7kmWkRAmFUa_Z1aiXVDhyMwsiQe81KHMGC82tuyWF9iHNstIX-M0IhU=", // 认证密钥
        "host_list":[ // 信息流服务器节点列表
            {
                "host":"tx-sh-live-comet-08.chat.bilibili.com", // 服务器域名
                "port":2243, // tcp端口
                "wss_port":443, // wss 端口
                "ws_port":2244 // ws端口
            },
            {
                "host":"tx-bj-live-comet-08.chat.bilibili.com",
                "port":2243,
                "wss_port":443,
                "ws_port":2244
            },
            {
                "host":"broadcastlv.chat.bilibili.com",
                "port":2243,
                "wss_port":443,
                "ws_port":2244
            }
        ]
    }
}

信息流接入

数据包为MQ(Message Queue,消息队列)使用 Websocket 或 TCP 连接作为通道,具体格式为 弹幕协议 + 正文数据

操作流程:

连接信息流服务器节点 -> 发送认证包 -> 接收认证包回应 -> 接收普通包&(每30秒发送心跳包 -> 接收心跳回应)

协议格式:基于websocket之上的应用层协议,所有字段 大端 对齐
协议格式:基于websocket之上的应用层协议,所有字段 大端 对齐

  • Packet Length:整个Packet的长度,包含Header
  • Header Length:Header的长度,固定为16
  • Version:协议版本
  • Operation:操作码
  • Sequence ID:保留字段,可以忽略
  • Body:消息体,客户端解析Body之前请先解析Version字段

Version 说明:
0 - 普通包正文不使用压缩
1 - 心跳及认证包正文不使用压缩
2 - 普通包(zlib压缩)
3 - 普通包(brotli压缩)

Operation 说明:
2 - 客户端发送的心跳包(30秒发送一次)
3 - 服务器收到心跳包的回复
5 - 服务器推送的弹幕消息包
7 - 客户端发送的鉴权包(客户端发送的第一个包)
8 - 服务器收到鉴权包后的回复

注意:B站最近加强了风控,建议在建立连接时携带好用户的cookie以避免风控限流

认证包构建

注意: 认证包需要在握手成功 5 秒内发送, 否则强制断开连接

认证包头部信息基于上述协议格式不再赘述,仅说明 Body 如何构建

字段类型说明
uidint用户uid
roomidint主播房间id
protoverint协议版本,决定了后续数据包的 Version
buvidstring用户buvid3,可在cookie中获得
platformstring平台,传web即可
typeint不确定用途,目前B站网页版传2,照着传即可
keystring获取信息流认证秘钥接口提供的token
protover 说明:
2 - 后续正文以 zlib 方式返回
3 - 后续正文以 brotli 方式返回

示例:

00000000: 0000 0152 0010 0001 0000 0007 0000 0001  ...R............
00000001: 7b22 7569 6422 3a34 3332 3530 3531 2c22  {"uid":4325051,"
00000002: 726f 6f6d 6964 223a 3331 3432 3735 3432  roomid":31427542
00000003: 2c22 7072 6f74 6f76 6572 223a 332c 2262  ,"protover":3,"b
00000004: 7576 6964 223a 2232 4445 3846 4141 312d  uvid":"2DE8FAA1-
00000005: 3642 4643 2d45 3741 412d 3031 3041 2d31  6BFC-E7AA-010A-1
00000006: 3039 4544 3039 3443 4245 3537 3935 3139  09ED094CBE579519
00000007: 696e 666f 6322 2c22 706c 6174 666f 726d  infoc","platform
00000008: 223a 2277 6562 222c 2274 7970 6522 3a32  ":"web","type":2
00000009: 2c22 6b65 7922 3a22 375f 6573 4f70 564e  ,"key":"7_esOpVN
0000000a: 697a 5570 4732 7069 3169 7741 2d79 3651  izUpG2pi1iwA-y6Q
0000000b: 4545 4550 734a 7872 666a 6c4c 5f73 4e50  EEEPsJxrfjlL_sNP
0000000c: 6b77 4f55 385a 7255 4150 334a 7951 746e  kwOU8ZrUAP3JyQtn
0000000d: 4154 6748 474c 645f 514a 616b 794b 4d54  ATgHGLd_QJakyKMT
0000000e: 4b75 717a 3856 5174 6474 5479 5f75 476c  Kuqz8VQtdtTy_uGl
0000000f: 5541 3958 6d75 334f 507a 6944 5170 3952  UA9Xmu3OPziDQp9R
00000010: 5832 6f57 4366 5356 3345 7778 3554 4532  X2oWCfSV3Ewx5TE2
00000011: 6c6a 4552 616e 684f 3757 7230 695f 3641  ljERanhO7Wr0i_6A
00000012: 584f 3862 6d38 634f 5757 5649 4a31 7966  XO8bm8cOWWVIJ1yf
00000013: 5535 4c63 7638 484b 3864 564e 4954 6e74  U5Lcv8HK8dVNITnt
00000014: 7144 4669 7339 5471 586d 544f 344e 413d  qDFis9TqXmTO4NA=
00000015: 227d                                     "}

苏琢玉
1 声望0 粉丝