2020-09-25 B站更新了互动弹幕功能,包括UP主头像弹幕、关联视频弹幕、视频内嵌引导关注按钮三大功能
详情见:
请求方式:GET
认证方式:仅可Cookie(SESSDATA)
url参数:
参数名 | 类型 | 内容 | 必要性 | 备注 |
---|---|---|---|---|
type | num | 弹幕类 | 必要 | 1:视频弹幕 |
oid | num | 视频CID | 必要 | |
pid | num | 稿件avID | 非必要 |
proto回复:
消息DmWebViewReply
:
名称 | 类型 | 含义 | 备注 |
---|---|---|---|
state | int32 | 弹幕开放状态 | 0:开放弹幕 1:禁止弹幕 |
text | string | ? | |
textSide | string | ? | |
dmSge | DmSegConfig | 分段弹幕包信息? | |
flag | DanmakuFlagConfig | ? | |
specialDms | repeated string | BAS(代码)弹幕专包url | |
checkBox | bool | ? | |
count | int64 | 实际弹幕总数 | 具有1500-6000不等的上限 |
commandDms | repeated CommandDm | 互动弹幕条目 | |
dmSetting | DanmuWebPlayerConfig | 弹幕个人配置 | 仅登录后存在 |
消息dmSge
:
名称 | 类型 | 含义 | 备注 |
---|---|---|---|
pageSize | int64 | 分段时间? | 单位为毫秒 |
total | int64 | 最大分页数? |
消息flag
:
名称 | 类型 | 含义 | 备注 |
---|---|---|---|
recFlag | int32 | ? | |
recText | string | ? | |
recSwitch | int32 | ? |
消息commandDms
:
名称 | 类型 | 含义 | 备注 |
---|---|---|---|
id | int64 | 弹幕dmID | |
oid | int64 | 视频CID | |
mid | int64 | 发送者UID | |
command | string | 弹幕指令 | #UP# :UP主头像弹幕#LINK# :关联视频弹幕#ATTENTION# :视频内嵌引导关注按钮 |
content | string | 弹幕文字 | |
progress | int32 | 弹幕出现时间 | 单位为毫秒 |
ctime | string | 创建时间? | 此项为空 |
mtime | string | 修改时间? | 此项为空 |
extra | string | 弹幕负载数据 | json序列字串 |
idStr | string | 弹幕dmID | 字串形式 |
extra
json序列:
类型为【UP主头像弹幕】时:
字段 | 类型 | 内容 | 备注 |
---|---|---|---|
icon | str | UP主头像url |
类型为【关联视频弹幕】时:类型为【关联视频弹幕】时:
字段 | 类型 | 内容 | 备注 |
---|---|---|---|
aid | num | 关联视频的avID | |
title | str | 关联视频的标题 | |
icon | str | 关联视频按钮图片url | |
bvid | str | 关联视频的bvID |
类型为【视频内嵌引导关注按钮】时:
字段 | 类型 | 内容 | 备注 |
---|---|---|---|
duration | num | 持续时间 | 单位为毫秒 |
posX | num | X坐标 | 区间:[118-549] |
posY | num | Y坐标 | 区间:[82-293] |
icon | str | 按钮图片url | 不应该是关注按钮吗,但这个是圆形的 |
type | num | 关注按钮类型 | 0:仅关注 1:仅三联 2:关注+三联 |
消息dmSetting
:
名称 | 类型 | 含义 | 备注 |
---|---|---|---|
dmSwitch | bool | 弹幕开关 | true:开启 false:关闭 |
aiSwitch | bool | 智能云屏蔽 | 同上 |
aiLevel | int32 | 智能云屏蔽级别 | 区间:[1-10] |
blocktop | bool | 屏蔽类型-顶部 | true:不屏蔽 false:屏蔽 |
blockscroll | bool | 屏蔽类型-滚动 | 同上 |
blockbottom | bool | 屏蔽类型-底部 | 同上 |
blockcolor | bool | 屏蔽类型-彩色 | 同上 |
blockspecial | bool | 屏蔽类型-特殊 | 同上 |
preventshade | bool | 防挡弹幕(底部15%) | true:开启 false:关闭 |
dmask | bool | 智能防挡弹幕(人像蒙版) | 同上 |
opacity | float | 弹幕不透明度 | 区间:[0-1] |
dmarea | int32 | 弹幕显示区域 | 100:不重叠 75:3/4屏 50:半瓶 25:1/4屏 0:不限 |
speedplus | float | 弹幕速度 | 区间:[0.4-1.6] |
fontsize | float | 字体大小 | 区间:[0.4-1.6] |
screensync | bool | 跟随屏幕缩放比例 | |
speedsync | bool | 根据播放倍速调整速度 | |
fontfamily | string | 字体类型? | 未启用 |
bold | bool | 粗体? | 未启用 |
fontborder | int32 | 描边类型 | 0:重墨 1:描边 2:45°投影 |
drawType | string | 渲染类型? | 未启用 |
protobuf结构体:
web_dmview.proto
syntax = "proto3";
//分段弹幕包信息?
message DmSegConfig {
int64 pageSize = 1; //分段时间?
int64 total = 2; //最大分页数?
}
//
message DanmakuFlagConfig {
int32 recFlag = 1; //
string recText = 2; //
int32 recSwitch = 3; //
}
// 互动弹幕条目
message CommandDm {
int64 id = 1; //弹幕dmID
int64 oid = 2; //视频CID
int64 mid = 3; //发送者UID
string command = 4; //弹幕指令
string content = 5; //弹幕文字
int32 progress = 6; //弹幕出现时间
string ctime = 7; //
string mtime = 8; //
string extra = 9; //弹幕负载数据
string idStr = 10; //弹幕dmID(字串形式)
}
//弹幕个人配置
message DanmuWebPlayerConfig{
bool dmSwitch=1; //弹幕开关
bool aiSwitch=2; //智能云屏蔽
int32 aiLevel=3; //智能云屏蔽级别
bool blocktop=4; //屏蔽类型-顶部
bool blockscroll=5; //屏蔽类型-滚动
bool blockbottom=6; //屏蔽类型-底部
bool blockcolor=7; //屏蔽类型-彩色
bool blockspecial=8; //屏蔽类型-特殊
bool preventshade=9; //防挡弹幕(底部15%)
bool dmask=10; //智能防挡弹幕(人像蒙版)
float opacity=11; //弹幕不透明度
int32 dmarea=12; //弹幕显示区域
float speedplus=13; //弹幕速度
float fontsize=14; //字体大小
bool screensync=15; //跟随屏幕缩放比例
bool speedsync=16; //根据播放倍速调整速度
string fontfamily=17; //字体类型?
bool bold=18; //粗体?
int32 fontborder=19; //描边类型
string drawType=20; //渲染类型?
}
message DmWebViewReply {
int32 state = 1; //弹幕开放状态
string text = 2; //
string textSide = 3; //
DmSegConfig dmSge = 4; //分段弹幕包信息?
DanmakuFlagConfig flag = 5; //
repeated string specialDms = 6; //BAS(代码)弹幕专包url
bool checkBox = 7; //
int64 count = 8; //实际弹幕总数
repeated CommandDm commandDms = 9; //互动弹幕条目
DanmuWebPlayerConfig dmSetting = 10; //弹幕个人配置
}
示例:
获取视频av797164471(CID=236871317)
的弹幕元数据
curl -G 'http://api.bilibili.com/x/v2/dm/web/view' \
--data-urlencode 'type=1' \
--data-urlencode 'oid=236871317' \
--data-urlencode 'pid=797164471' \
-b 'SESSDATA=xxx' \
-o 'danmaku_view.bin'
响应正文为protubuf二进制数据
获取并显示视频av797164471(CID=236871317)
的所有互动弹幕
import web_dmview_pb2
import requests
AVID = 797164471
CID = 236871317
url = f'http://api.bilibili.com/x/v2/dm/web/view?type=1&oid={CID}&pid={AVID}'
data = requests.get(url)
target = web_dmview_pb2.DmWebViewReply()
target.ParseFromString(data.content)
print(f'互动弹幕数={len(target.commandDms)}')
for i in target.commandDms:
print(f'''\
---弹幕ID={i.id}
---视频CID={i.oid}
---发送者UID={i.mid}
---弹幕指令={i.command}
---弹幕文字={i.content}
---弹幕出现时间={i.progress}
---弹幕负载数据={i.extra}
---弹幕ID(字串)={i.idStr}'''
)
输出为:
互动弹幕数=1
---弹幕ID=38469676112019463
---视频CID=236871317
---发送者UID=501183549
---弹幕指令=#UP#
---弹幕文字=这个视频没有恰饭!别紧张!
---弹幕出现时间=157818
---弹幕负载数据={"icon":"http://i1.hdslb.com/bfs/face/559abe31f561f71f3106d8ee7b2065cac50c1235.jpg"}
---弹幕ID(字串)=38469676112019463
BAS弹幕(pool=2
mode=9
)只能从此包获取,代码弹幕(pool=2
mode=8
)也能从此包获取
获取并显示视频av2(CID=62131)
的所有BAS(代码)弹幕专包
import web_dmview_pb2
import requests
AVID = 2
CID = 62131
url = f'http://api.bilibili.com/x/v2/dm/web/view?type=1&oid={CID}&pid={AVID}'
data = requests.get(url)
target = web_dmview_pb2.DmWebViewReply()
target.ParseFromString(data.content)
print(f'特殊弹幕包数={len(target.specialDms)}')
for i in target.specialDms:
print(f'特殊弹幕包url={i}')
输出为:
特殊弹幕包数=1
特殊弹幕包url=http://i0.hdslb.com/bfs/dm/b0d5f08c12be59292aa0d4e09b6dd8e54c2ba886.bin
使用普通分段包弹幕的proto结构体反序列化此bin数据