Chrome DevTools では、バイナリタイプのデータパケットを直接表示できます!
リンク#
Chrome DevTools を使用すると、Web 版 Bilibili のライブ弾幕は wss://tx-sh3-live-comet-04.chat.bilibili.com/sub
を介して送信されます。このアドレスは毎回異なります。wss アドレスを取得するには、 https://api.live.bilibili.com/room/v1/Danmu/getConf?room_id=ルームID&platform=pc&player=web
を使用する必要があります(おそらく負荷分散のためであり、実際のテストでは任意の 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 形式のデータ |
クライアントが接続した後、5 秒以内にルームに参加(認証)するデータパケットを送信する必要があります。そうしないと、サーバーによって強制的に接続が切断されます。ペイロードのキーの内容は、以前の https://api.live.bilibili.com/room/v1/Danmu/getConf?room_id=ルームID&platform=pc&player=web
から取得できます。認証パケットの形式が間違っている場合、サーバーは即座に接続を強制的に切断します。JSON フィールドの詳細な説明については、以下の表を参照してください。
フィールド | タイプ | 必須 | 意味 |
---|---|---|---|
uid | number | × | ユーザー UID |
roomid | number | √ | ルーム ID |
protover | number | × | プロトコルバージョン、現在は 2 |
platform | string | × | プラットフォーム、web であることができます |
clientver | string | × | クライアントのバージョン、 "1.8.5" などができます |
type | number | × | 不明、2 であることができます |
key | string | × | ユーザー識別子、前述のインターフェースから取得します |
ハートビート#
ハートビートパケットは 30 秒ごとに送信することをお勧めします。ヘッダーの 16 バイトは前述のルールに従い、ペイロードの内容は任意です。(Bilibili は空のオブジェクトを渡してハートビートパケットを生成し、以前は理解できなかったハートビートパケットの内容が表示されるようになりました)
通知(弾幕、お知らせ、ギフトなど)#
新しい弾幕、ギフト、または他のお知らせがある場合、サーバーは以下のようなデータパケットを送信します。まず、データ本体部分(ヘッダーの 16 バイトを除く)を 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 のタイプです)
{
"cmd": "SEND_GIFT",
"data": {
"giftName": "辣条",
"num": 5,
"uname": "迪多玛索",
"face": "http://i2.hdslb.com/bfs/face/1a3b795aafc5887f3f33909c7e66876d23911979.jpg",
"guard_level": 0,
"rcost": 42593386,
"uid": 415822879,
"top_list": [],
"timestamp": 1570368091,
"giftId": 1,
"giftType": 0,
"action": "喂食",
"super": 0,
"super_gift_num": 0,
"price": 100,
"rnd": "EF27025C-4C20-440F-B36F-64CCFABBF68E",
"newMedal": 0,
"newTitle": 0,
"medal": [],
"title": "",
"beatId": "",
"biz_source": "live",
"metadata": "",
"remain": 0,
"gold": 0,
"silver": 0,
"eventScore": 0,
"eventNum": 0,
"smalltv_msg": [],
"specialGift": null,
"notice_msg": [],
"capsule": null,
"addFollow": 0,
"effect_block": 1,
"coin_type": "silver",
"total_coin": 500,
"effect": 0,
"broadcast_id": 0,
"draw": 0,
"crit_prob": 0,
"tag_image": "",
"user_count": 0,
"send_master": null
}
}
{
"cmd": "ACTIVITY_BANNER_UPDATE_V2",
"data": {
"id": 378,
"title": "第6名",
"cover": "",
"background": "https://i0.hdslb.com/bfs/activity-plat/static/20190904/b5e210ef68e55c042f407870de28894b/14vZu7h9pK.png",
"jump_url": "https://live.bilibili.com/p/html/live-app-rankcurrent/index.html?is_live_half_webview=1&hybrid_half_ui=1,5,85p,70p,FFE293,0,30,100,10;2,2,320,100p,FFE293,0,30,100,0;4,2,320,100p,FFE293,0,30,100,0;6,5,65p,60p,FFE293,0,30,100,10;5,5,55p,60p,FFE293,0,30,100,10;3,5,85p,70p,FFE293,0,30,100,10;7,5,65p,60p,FFE293,0,30,100,10;&anchor_uid=22550271&is_new_rank_container=1&area_v2_id=163&area_v2_parent_id=3&rank_type=master_realtime_area_hour&area_hour=1",
"title_color": "#8B5817",
"closeable": 1,
"banner_type": 4,
"weight": 18,
"add_banner": 0
}
}
{
"cmd": "ROOM_REAL_TIME_MESSAGE_UPDATE",
"data": {
"roomid": 101526,
"fans": 294665,
"red_notice": -1
}
}
追記:Chrome は WebSocket のバイナリパケットを直接表示できるため、非常に時間を節約できます。Chrome 最高!