b站 实时弹幕和历史弹幕 Protobuf 格式解析

本文介绍了B站从XML格式转变为protobuf传输弹幕的原因及protobuf的优势。详细阐述了如何解析protobuf弹幕,包括下载Protoc编译器、protobuf-Python库,以及弹幕的.proto定义和编译。还提供了实时弹幕与历史弹幕的Python解析示例代码,帮助理解protobuf在B站弹幕系统中的应用。
该文章已生成可运行项目,

参考:

b站弹幕传输的格式由原来的 xml 改为了 protobuf,这个格式为二进制编码传输,其传输销量远高于原来的 xml,因此在移动端可以减小网络的压力具有一定的优势。但带来的一个问题就是,这个格式的弹幕解析起来变得十分困难,通常从 api 获得的数据直接看是一通乱码,需要特定的方式才能看到真正的内容,让人比较头疼。

B站没有使用 protobuf 协议前的弹幕接口

1、什么是 Protobuf

Protocol buffers are Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages.

上面这段话来自谷歌 Protobuf 官网的介绍,简单来讲就是一种传输的协议,比 xml 更小、更快、更简单,更多信息可以见:https://developers.google.com/protocol-buffers/

2、如何解析 Protobuf 的弹幕

2.1 下载 Protoc 编译器

Protoc 是用于将 .proto 文件编译成各种编程语言(如 Python、Golang 等)的编译器,是进行 Protobuf 解析的必要条件,可在下面的链接中下载:https://github.com/protocolbuffers/protobuf

 下载完成后解压出来是 exe 文件,不需要安装,但是需要手动添加到 Path 中。

 通过在终端中运行如下代码来确定是否安装成功:protoc --version

2.2 下载 Protobuf-Python 以便在 Python 中解析 Protobuf

下载地址:https://github.com/protocolbuffers/protobuf

下载完成后解压,然后进入 python 进入目录,

 执行以下命令行代码:

python setup.py clean
python setup.py build
python setup.py install
python setup.py test

2.3 弹幕的 proto 定义并编译

弹幕格式,protobuf 结构体:

dm.proto

syntax = "proto3";

package dm;

message DmSegMobileReply{
  repeated DanmakuElem elems = 1;
}
message DanmakuElem{
  int64 id = 1;
  int32 progress = 2;
  int32 mode = 3;
  int32 fontsize = 4;
  uint32 color = 5;
  string midHash = 6;
  string content = 7;
  int64 ctime = 8;
  int32 weight = 9;
  string action = 10;
  int32 pool = 11;
  string idStr = 12;
}
名称含义类型备注
id弹幕dmIDint64唯一 可用于操作参数
progress视频内弹幕出现时间int32毫秒
mode弹幕类型int321 2 3:普通弹幕
4:底部弹幕
5:顶部弹幕
6:逆向弹幕
7:高级弹幕
8:代码弹幕
9:BAS弹幕
fontsize弹幕字号int3218:小
25:标准
36:大
color弹幕颜色uint32十进制RGB888值
midHash发送者UID的HASHstring用于屏蔽用户和查看用户发送的所有弹幕 也可反查用户ID
content弹幕内容stringutf-8编码
ctime弹幕发送时间int64时间戳
weight权重int32用于智能屏蔽级别
action动作string未知
pool弹幕池int320:普通池
1:字幕池
2:特殊池(代码/BAS弹幕)
idStr弹幕dmID的字符串类型string唯一 可用于操作参数

2.4 解析 seg.so 格式的弹幕数据

示例视频:https://www.bilibili.com/video/av98919207

解析之前需要先安装 python 的 probuf 包: pip install protobuf

编译 proto 结构文件,

protoc --python_out=. dm.proto

执行完成后会生成 dm_pb2.py,代码中引入这个 python 文件,

 dm_pj.py 代码如下:

注意:

  • 实时弹幕 不需要 cookie,直接请求即可得到 seg.so 
  • 历史弹幕 需要 cookie 才能得到 seg.so 
# -*- coding: utf-8 -*-
# @Author  : 
# @Date    :
# @File    : dm_pj.py
# @description : XXX


import json
import requests
from dm_pb2 import DmSegMobileReply
from google.protobuf.json_format import MessageToJson, Parse


b_web_cookie = 'SESSDATA=fd25e2e6%2C1660373048%2C287c9%2A21;'


def get_date_list():
    url = "https://api.bilibili.com/x/v2/dm/history/index?type=1&oid=168855206&month=2022-02"
    headers = {
        'cookie': b_web_cookie
    }
    response = requests.get(url, headers=headers)
    print(json.dumps(response.json(), ensure_ascii=False, indent=4))


def dm_real_time():
    url_real_time = 'https://api.bilibili.com/x/v2/dm/web/seg.so?type=1&oid=168855206&pid=98919207&segment_index=1'
    resp = requests.get(url_real_time)

    DM = DmSegMobileReply()
    DM.ParseFromString(resp.content)
    data_dict = json.loads(MessageToJson(DM))
    # print(data_dict)
    list(map(lambda x=None: print(x['content']), data_dict.get('elems', [])))


def dm_history():
    url_history = 'https://api.bilibili.com/x/v2/dm/web/history/seg.so?type=1&oid=168855206&date=2022-02-23'
    headers = {
        'cookie': b_web_cookie
    }
    resp = requests.get(url_history, headers=headers)
    DM = DmSegMobileReply()
    DM.ParseFromString(resp.content)
    data_dict = json.loads(MessageToJson(DM))
    # print(data_dict)
    list(map(lambda x=None: print(x['content']), data_dict.get('elems', [])))


if __name__ == '__main__':
    # dm_real_time()
    get_date_list()
    # dm_history()
    pass

 执行结果截图:

弹幕对比:

本文章已经生成可运行项目
<think>嗯,用户想了解B弹幕Protobuf协议解析格式。首先,我需要回忆一下之前关于Protobuf的知识,以及B弹幕处理的相关资料。记得Protobuf是Google开发的一种数据序列化协议,它比XML、JSON更高效,适合网络传输。B使用它来处理实时历史弹幕,可能是因为传输效率高,节省带宽。 根据用户提供的引用内容,特别是引用[1]、[2]、[3],里面提到了Protobuf在B弹幕中的应用,以及需要用到Protoc编译器逆向工程的方法。用户可能想知道具体的解析步骤,或者协议结构是怎样的。 首先,我应该解释Protobuf的基本概念,然后结合B的实际情况说明弹幕数据是如何使用Protobuf编码的。可能需要提到.proto文件的结构,因为Protobuf需要根据定义好的数据结构来序列化反序列化数据。不过用户提供的引用中提到需要逆向分析,可能B没有公开.proto文件,所以需要通过解析二进制的Protobuf数据来推断结构。 接下来,用户可能需要了解具体的解析步骤,比如如何获取弹幕数据,使用Protoc编译器生成对应的解析代码,或者通过逆向工程来分析协议结构。引用[2]提到了配置Protoc到环境变量,以及Python的使用,可能需要这些工具来解析数据。 另外,引用[3]提到JS断点调试分析,这可能是在浏览器中抓取弹幕数据时使用的调试方法,用于找到Protobuf的编码位置解码方式。可能需要结合网络请求,找到弹幕的API接口,然后捕获Protobuf格式的响应数据,再用工具解析。 可能还需要提到具体的字段,比如弹幕的时间、内容、用户信息、位置等,这些是弹幕数据中常见的部分,对应Protobuf消息结构中的各个字段。例如,B弹幕Protobuf消息可能包含id、text、color、time等字段。 此外,用户可能对实际解析过程感兴趣,比如使用Python的protobuf库加载编译后的.py文件,然后解析二进制数据。需要指出的是,如果没有.proto文件,可能需要逆向工程来推测消息结构,这会比较复杂,涉及到分析二进制数据的格式,如字段编号、数据类型等。 最后,应该总结解析的关键点,比如获取.proto文件或逆向分析,使用Protoc生成解析代码,以及处理网络请求中的Protobuf数据。同时,用户可能需要相关的问题,比如如何捕获弹幕数据、优化解析效率,或者处理不同版本的协议变化。</think>### B弹幕Protobuf协议解析格式说明 B弹幕使用的Protobuf协议是一种高效的数据序列化格式,其核心是通过预定义的`.proto`文件结构将弹幕内容编码为二进制数据流。以下是关键解析步骤格式说明: --- #### 1. **协议结构基础** 弹幕数据通过多个嵌套的Protobuf消息体传递,主要包含以下层级: $$ \text{Message} \rightarrow \text{DmSegMobileReply} \rightarrow \text{DanmakuElem} $$ - **DanmakuElem**:单个弹幕元素定义,包含弹幕文本、颜色、位置等字段[^3] - 典型字段示例(通过逆向分析得出): ```protobuf message DanmakuElem { int64 id = 1; string text = 2; // 弹幕内容 int32 color = 3; // RGB颜色值 int64 time = 4; // 出现时间戳(毫秒) int32 position = 5; // 0:滚动 1:顶部 2:底部 int32 fontSize = 6; // 字体大小等级 } ``` --- #### 2. **解析工具链** 需使用以下工具进行解析: - **Protoc编译器**:将.proto文件编译为对应语言解析代码(需配置环境变量)[^1] - **Python解析示例**: ```python import danmaku_pb2 # 编译生成的Python文件 with open('danmaku.pb', 'rb') as f: data = f.read() dm = danmaku_pb2.DmSegMobileReply() dm.ParseFromString(data) for elem in dm.elems: print(f"[{elem.time}ms] {elem.text}") ``` --- #### 3. **数据获取与处理** 1. **实时弹幕获取**:通过WebSocket接口`wss://broadcast.chat.bilibili.com/sub`接收Protobuf格式数据流[^2] 2. **历史弹幕解析**:从`https://api.bilibili.com/x/v2/dm/web/history/seg.so`接口获取二进制文件 3. **网络请求特征**:请求头中需包含`Content-Type: application/grpc`标识[^3] --- #### 4. **逆向分析要点** - **字段定位**:通过JS调试分析网络请求响应,定位弹幕二进制数据的解码过程 - **动态测试**:发送不同颜色/位置的弹幕,观察二进制数据变化规律 - **版本兼容**:B可能更新协议结构,需持续跟踪`.proto`字段变化 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值