searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Bilibili视频弹幕文件解析-后续

2023-08-10 08:50:55
84
0

在写了《Bilibili视频弹幕文件解析》之后,我突然意识到b站弹幕文件会不会就是protobuf,毕竟已经有现有的这么好这么成熟的工具,不聪明才会选择自己实现新的协议。

想到这里,赶紧使用protobuf测试一番。

proto

有了上次的经验,大概知道这个弹幕文件的结构,先写个proto文件,对上b站弹幕文件

dm.proto

syntax = "proto3";
​
message DmList {
    repeated Dm dmList = 1;
}
​
// 后面的tag数字要对上
message Dm {
    int32 stime = 2;
    int32 mode = 3;
    int32 size = 4;
    uint32 color = 5;
    string uhash = 6;
    string text = 7;
    int64 date = 8;
    int32 weight = 9;
    string action = 10;
    int32 pool = 11;
    string dmid = 12;
    int32 attr = 13;
    string animation = 22;
}

使用protoc生成代码,(关于protoc的安装,网上教程很多,这里不赘述了)

mkdir pythonout
protoc --python_out=./pythonout ./dm.proto

生成的代码如下

./pythonout/dm_pb2.py

# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: dm.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
​
_sym_db = _symbol_database.Default()
​
​
​
​
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x08\x64m.proto\"\x1d\n\x06\x44mList\x12\x13\n\x06\x64mList\x18\x01 \x03(\x0b\x32\x03.Dm\"\xc6\x01\n\x02\x44m\x12\r\n\x05stime\x18\x02 \x01(\x05\x12\x0c\n\x04mode\x18\x03 \x01(\x05\x12\x0c\n\x04size\x18\x04 \x01(\x05\x12\r\n\x05\x63olor\x18\x05 \x01(\r\x12\r\n\x05uhash\x18\x06 \x01(\t\x12\x0c\n\x04text\x18\x07 \x01(\t\x12\x0c\n\x04\x64\x61te\x18\x08 \x01(\x03\x12\x0e\n\x06weight\x18\t \x01(\x05\x12\x0e\n\x06\x61\x63tion\x18\n \x01(\t\x12\x0c\n\x04pool\x18\x0b \x01(\x05\x12\x0c\n\x04\x64mid\x18\x0c \x01(\t\x12\x0c\n\x04\x61ttr\x18\r \x01(\x05\x12\x11\n\tanimation\x18\x16 \x01(\tb\x06proto3')
​
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'dm_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
​
  DESCRIPTOR._options = None
  _DMLIST._serialized_start=12
  _DMLIST._serialized_end=41
  _DM._serialized_start=44
  _DM._serialized_end=242
# @@protoc_insertion_point(module_scope)


不得不说,protoc生成的python代码比golang简洁很多,我第一眼看到的这么代码行数这么少,还以为遇到什么意外了呢

使用dm_pb2

新建一个项目,拷贝./pythonout/dm_pb2.py这个文件到项目路径下以使用生成的pb代码

python要先安装protobuf包(pip install protobuf)

import dm_pb2
​
​
def main():
    dm_list_class = getattr(dm_pb2, 'DmList')
    dm_list = dm_list_class()
    # 这里的seg.so是下载到本地的弹幕文件,如果使用在线的,可以用
    # import requests
    # dm_list.ParseFromString(requests.get(url).content)
    dm_list.ParseFromString(open('seg.so', 'rb').read())
    for dm in dm_list.dmList:
        print(dm)
​
​
if __name__ == '__main__':
    main()

运行结果如下:

image-20230810150815728

成功~

总结

上一次折腾了大半天,其实就是写了一个解析protobuf文件的代码。不过也不是完全没有作用,要定义proto的message,需要知道弹幕文件的结构,同时一些字段的tag必须匹配上,否则偏移不对,无法解析出正确的数据,有了上次的分析结果,这次才能很快的写出proto。

0条评论
0 / 1000
moy
2文章数
0粉丝数
moy
2 文章 | 0 粉丝
moy
2文章数
0粉丝数
moy
2 文章 | 0 粉丝
原创

Bilibili视频弹幕文件解析-后续

2023-08-10 08:50:55
84
0

在写了《Bilibili视频弹幕文件解析》之后,我突然意识到b站弹幕文件会不会就是protobuf,毕竟已经有现有的这么好这么成熟的工具,不聪明才会选择自己实现新的协议。

想到这里,赶紧使用protobuf测试一番。

proto

有了上次的经验,大概知道这个弹幕文件的结构,先写个proto文件,对上b站弹幕文件

dm.proto

syntax = "proto3";
​
message DmList {
    repeated Dm dmList = 1;
}
​
// 后面的tag数字要对上
message Dm {
    int32 stime = 2;
    int32 mode = 3;
    int32 size = 4;
    uint32 color = 5;
    string uhash = 6;
    string text = 7;
    int64 date = 8;
    int32 weight = 9;
    string action = 10;
    int32 pool = 11;
    string dmid = 12;
    int32 attr = 13;
    string animation = 22;
}

使用protoc生成代码,(关于protoc的安装,网上教程很多,这里不赘述了)

mkdir pythonout
protoc --python_out=./pythonout ./dm.proto

生成的代码如下

./pythonout/dm_pb2.py

# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: dm.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
​
_sym_db = _symbol_database.Default()
​
​
​
​
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x08\x64m.proto\"\x1d\n\x06\x44mList\x12\x13\n\x06\x64mList\x18\x01 \x03(\x0b\x32\x03.Dm\"\xc6\x01\n\x02\x44m\x12\r\n\x05stime\x18\x02 \x01(\x05\x12\x0c\n\x04mode\x18\x03 \x01(\x05\x12\x0c\n\x04size\x18\x04 \x01(\x05\x12\r\n\x05\x63olor\x18\x05 \x01(\r\x12\r\n\x05uhash\x18\x06 \x01(\t\x12\x0c\n\x04text\x18\x07 \x01(\t\x12\x0c\n\x04\x64\x61te\x18\x08 \x01(\x03\x12\x0e\n\x06weight\x18\t \x01(\x05\x12\x0e\n\x06\x61\x63tion\x18\n \x01(\t\x12\x0c\n\x04pool\x18\x0b \x01(\x05\x12\x0c\n\x04\x64mid\x18\x0c \x01(\t\x12\x0c\n\x04\x61ttr\x18\r \x01(\x05\x12\x11\n\tanimation\x18\x16 \x01(\tb\x06proto3')
​
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'dm_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
​
  DESCRIPTOR._options = None
  _DMLIST._serialized_start=12
  _DMLIST._serialized_end=41
  _DM._serialized_start=44
  _DM._serialized_end=242
# @@protoc_insertion_point(module_scope)


不得不说,protoc生成的python代码比golang简洁很多,我第一眼看到的这么代码行数这么少,还以为遇到什么意外了呢

使用dm_pb2

新建一个项目,拷贝./pythonout/dm_pb2.py这个文件到项目路径下以使用生成的pb代码

python要先安装protobuf包(pip install protobuf)

import dm_pb2
​
​
def main():
    dm_list_class = getattr(dm_pb2, 'DmList')
    dm_list = dm_list_class()
    # 这里的seg.so是下载到本地的弹幕文件,如果使用在线的,可以用
    # import requests
    # dm_list.ParseFromString(requests.get(url).content)
    dm_list.ParseFromString(open('seg.so', 'rb').read())
    for dm in dm_list.dmList:
        print(dm)
​
​
if __name__ == '__main__':
    main()

运行结果如下:

image-20230810150815728

成功~

总结

上一次折腾了大半天,其实就是写了一个解析protobuf文件的代码。不过也不是完全没有作用,要定义proto的message,需要知道弹幕文件的结构,同时一些字段的tag必须匹配上,否则偏移不对,无法解析出正确的数据,有了上次的分析结果,这次才能很快的写出proto。

文章来自个人专栏
MT
2 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0