戴兜

戴兜的小屋

Coding the world.
github
bilibili
twitter

B站のライブ弾幕wsプロトコルの分析

image

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

オフセット長さタイプ意味
04intデータパケットの長さ
42intデータパケットのヘッダーの長さ、固定値は 16
62intデータパケットのプロトコルバージョン(後述)
84intデータパケットのタイプ(後述)
124int固定値は 1
16byte[]データ本体
データパケットのプロトコルバージョン意味
0データパケットのペイロードは圧縮されていない JSON 形式のデータ
1クライアントのハートビートパケット、またはサーバーのハートビート応答(人気値を含む)
2データパケットのペイロードは zlib で圧縮された JSON 形式のデータ

クライアントが接続した後、5 秒以内にルームに参加(認証)するデータパケットを送信する必要があります。そうしないと、サーバーによって強制的に接続が切断されます。ペイロードのキーの内容は、以前の https://api.live.bilibili.com/room/v1/Danmu/getConf?room_id=ルームID&platform=pc&player=web から取得できます。認証パケットの形式が間違っている場合、サーバーは即座に接続を強制的に切断します。JSON フィールドの詳細な説明については、以下の表を参照してください。

image

フィールドタイプ必須意味
uidnumber×ユーザー UID
roomidnumberルーム ID
protovernumber×プロトコルバージョン、現在は 2
platformstring×プラットフォーム、web であることができます
clientverstring×クライアントのバージョン、 "1.8.5" などができます
typenumber×不明、2 であることができます
keystring×ユーザー識別子、前述のインターフェースから取得します

ハートビート#

ハートビートパケットは 30 秒ごとに送信することをお勧めします。ヘッダーの 16 バイトは前述のルールに従い、ペイロードの内容は任意です。(Bilibili は空のオブジェクトを渡してハートビートパケットを生成し、以前は理解できなかったハートビートパケットの内容が表示されるようになりました)

image

通知(弾幕、お知らせ、ギフトなど)#

新しい弾幕、ギフト、または他のお知らせがある場合、サーバーは以下のようなデータパケットを送信します。まず、データ本体部分(ヘッダーの 16 バイトを除く)を zlib.inflate を使用して解凍する必要があります。解凍されたデータのヘッダーは元のデータのヘッダーと同じ 16 バイトであり、ヘッダーを除いた部分は JSON 形式のデータです。

ここでは、弾幕データパケットを例に説明します。

image

image

解凍されたデータには、ヘッダー(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 最高!

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。