跳转到主内容
极星编程网:以代码为星,赴技术山海!

php怎么调用B站直播开放平台_php如何获取直播间弹幕与礼物数据

必须用 WebSocket 连接 B站直播弹幕服务,先调用 HTTP 接口获取带 token 的 ws 地址,再发送二进制认证包;PHP 需借助 textalk/websocket 等库手动解析 TLV 协议,注意 token 时效性、心跳保活及风控限制。 PHP 调用 B站直播开放平台必须走 WebSocket,HTTP 接口只读不推 直接用
file_get_contents
或
curl
请求 B站弹幕接口会失败——官方没提供轮询式 HTTP 弹幕拉取接口。所有实时数据(弹幕、礼物、进入房间等)都得靠 WebSocket 长连接收发。PHP 本身不原生支持 WebSocket 客户端,得靠扩展或第三方库。 常见错误现象:
403 Forbidden
或空响应;
curl
返回
{"code":-400,"message":"invalid request"}
;或者连上就断开,没任何数据。 必须用
ws://
或
wss://
协议连接,不能用
http://
B站要求先通过 HTTP 接口
https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo
获取真实 WebSocket 地址和认证参数(
token
、
host_list
) 拿到地址后,要拼接
room_id
、
protover
(固定为
2
)、
platform
(如
web
)、
type
(
1
表示弹幕)和
key
(即
token
)作为 URL 查询参数 连接建立后,必须立刻发送认证包(
HEARTBEAT
前需先发
VERIFICATION
),格式是二进制协议(Bilibili 自定义的 TLV 结构),不是 JSON 用 php -websocket 库最省事,但要注意二进制协议解析 推荐用
textalk/websocket
(Composer 可装),它能处理连接和基础帧收发,但不自动解析 B站的二进制协议。你得自己拆包:每个包开头 4 字节是包总长度(含头),接着 2 字节是头部长度,2 字节是协议版本,2 字节是操作码(
3
是弹幕,
5
是礼物,
8
是心跳响应),最后是 JSON 数据体(需从
body
字段里提取)。 容易踩的坑:
json_decode($body, true)
直接报错,因为
$body
是原始二进制流,得先用
substr($raw, $headerLen)
截出有效载荷,再
json_decode
;另外,B站可能返回多个包粘连在一起,一次
recv()
可能含多条消息,得按包长循环切分。 立即学习 “ PHP免费学习笔记(深入) ”; 安装:
composer require textalk/websocket
别用
json_encode
发认证包——必须构造二进制字符串:
pack('N', $totalLen) . pack('n', 16) . pack('n', 1) . pack('n', 7) . pack('n', $roomId)
(简化示意,实际更复杂) 操作码
3
对应弹幕,
5
是礼物,
16
是用户入场,别硬编码成
1
或
2
心跳间隔官方建议 30 秒,超时未发
HEARTBEAT
包会被服务器断连 获取直播间弹幕与礼物数据前,务必处理好鉴权和防封策略 B站对非官方客户端有严格风控:单 IP 短时间连多个房间、频繁重连、无心跳、消息体格式错误,都会触发限流甚至封禁 IP。这不是“调不通”,而是“被拒绝”。 PHP 8.5.5 PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。 下载 真实使用场景中,多数人卡在 token 过期或房间号无效。注意:
getDanmuInfo
接口返回的
token
有效期约 1–2 分钟,且绑定具体
room_id
和
uid
(如果登录了),不能复用;若房间已下播,
getDanmuInfo
会返回
code=1
(房间不存在)或
code=400
(状态异常)。 每次重连前,必须重新调用
getDanmuInfo
拿新
token
和
host
不要用个人账号 Cookie 去请求
getDanmuInfo
——除非你明确做了登录态维护(
SESSDATA
+
bili_jct
),否则大概率
412
(未登录) 测试阶段用小号房间(在线人数 生产环境建议加随机延迟(500–2000ms)再发心跳,避免整齐划一的请求节奏 PHP 不适合长期运行弹幕服务,别硬扛高并发连接 一个 PHP-FPM 进程只能维持一个 WebSocket 连接,没法像 Node.js 或 Go 那样单进程管几千连接。如果你要监控 50 个直播间,就得启 50 个独立进程(比如用
nohup php danmu.php &
),内存和 CPU 开销会迅速失控,且进程挂了没人拉起。 性能影响很实际:每条弹幕平均 300–800 字节,千人房每秒 10–50 条,单连接带宽不高,但 PHP 解析二进制 + JSON + 业务逻辑(比如写数据库、触发通知)容易成为瓶颈,尤其用
file_put_contents
写日志时磁盘 I/O 会拖慢整个循环。 用
pcntl_fork
启子进程管理单个房间,主进程负责保活和日志汇总(但 Windows 不支持) 更稳妥的做法是把 PHP 当“协议翻译层”:WebSocket 收到数据后,用
stream_socket_client
转发给本地 Node.js/Python 服务处理,PHP 只做轻量胶水 别在
while(true)
里用
sleep(1)
轮询——用
socket_select
或事件循环(如
reactphp/socket
)才靠谱 记录弹幕时,批量插入(
INSERT INTO ... VALUES (...),(...)
)比逐条
INSERT
快 10 倍以上 真正难的不是连上,是稳住连接、正确解包、扛住风控、不崩进程。这些细节没对齐,代码写得再“完整”,跑半天就断了。

相关文章