适用于B站直播间使用,功能有:+1楼上发言(按键可自定义,支持表情包),自定义快捷发言。
注:个人自用脚本,仅作存档。功能简单,未必通用。若恰好解决你的问题,那是缘分;若不适用,建议参考社区其他优秀项目,感谢理解。
如果你也需要自定义关于b站直播间的脚本,以下可供参考:
脚本运行环境是 ScriptCat/Tampermonkey 用户脚本,match 是 https://live.bilibili.com/*。
当前已经测试出的关键结论:
- 纯文字弹幕可以稳定通过接口发送:
POST https://api.live.bilibili.com/msg/send
普通文字参数:
- msg=文字内容
- dm_type 不传或为 0
- bubble=0
- color=16777215
- mode=1
- fontsize=25
- rnd=当前秒级时间戳
- roomid=真实直播间 room_id
- csrf=bili_jct
- csrf_token=bili_jct
- credentials=include
- content-type=application/x-www-form-urlencoded; charset=UTF-8
- 大号图片表情 / 粉丝团表情不能当普通文字发送,不能用 [表情名] 兜底。
真正可用的大表情接口方案是:
- dm_type=1
- msg=fileId
- emoticonOptions=JSON.stringify({...})
- 表情发送已测试方案结果:
- emoticonOptions + msg=表情名:失败
- emoticonOptions + msg=fileId:成功
- emoticon_options + msg=表情名:失败
- top-level + msg=表情名:失败
- top-level + msg=fileId:成功
最终推荐固定使用:
emoticonOptions + msg=fileId
- 大表情聊天项 DOM 里的关键字段:
chatItem.dataset.danmaku // 表情名,例如 "桀桀桀"
chatItem.dataset.image // 表情图片原始地址
chatItem.dataset.fileId // 表情唯一 ID,例如 "room_1859173915_115070"
例:
{
"danmaku": "桀桀桀",
"fileId": "room_1859173915_115070",
"image": "http://i0.hdslb.com/bfs/live/de1eaed678b38f532d158ecdc8b069e9dbb780d0.png"
}
- 表情接口推荐参数:
msg = emoji.fileId
dm_type = 1
emoticonOptions = JSON.stringify({
bulge_display: emoji.bulge ? 1 : 0,
emoticon_unique: emoji.fileId,
height: emoji.height || 40,
width: emoji.width || 40,
in_player_area: 1,
url: emoji.src
})
- 注意:表情消息不能再走普通文字发送路径。
只要识别到真实表情 data-file-id + data-image,就应 payload.text = ''。
否则会一次点击同时发出表情名文字和表情包。
- 但普通文字消息里也可能有头像、勋章、等级图标 img,不能误判成表情。
不能只靠 img[alt] 判断表情。
可靠判断大表情应要求:
- chatItem.dataset.fileId
- chatItem.dataset.image
并且最好外层类名满足:
- chat-emoticon
- bulge-emoticon
- emoticon
- 按钮交互方案:
不要把 +1 按钮插入聊天消息 DOM 内部,否则会触发 B站用户卡片。
应创建独立 fixed overlay:
- .sc-plus-one-overlay fixed inset:0 pointer-events:none
- .sc-plus-one-btn fixed pointer-events:auto
根据聊天项位置实时定位。
- 点击事件:
B站会吞掉 click/pointerup,所以稳定方案是 document 捕获阶段监听:
- pointerdown
- mousedown
- touchstart
- click
通过 elementFromPoint(x,y) 或 target.closest('.sc-plus-one-btn') 找到按钮。
点击时必须:
e.preventDefault()
e.stopPropagation()
e.stopImmediatePropagation()
- 按钮显示和清理:
直播间聊天 DOM 会滚动和复用,必须:
- 只给当前可见聊天项生成按钮
- 设置 maxButtons,比如 30
- 定时扫描和清理不可见/已移除按钮
- 按钮定位限制在聊天面板 rect 内,避免上下堆积和超出面板。
- 当前最终正式版思路:
如果是纯文字:
通过 /msg/send 发送 msg=文字,dm_type=0
如果是大表情/粉丝团表情:
必须有 data-file-id 和 data-image
payload.text 清空
通过 /msg/send 发送:
msg=fileId
dm_type=1
emoticonOptions={
bulge_display,
emoticon_unique:fileId,
height,
width,
in_player_area:1,
url:image
}
不要:
- 把表情名当普通文字发送
- 用 [表情名] 兜底
- 把头像/勋章/等级图片当表情
- 把按钮放入聊天 DOM 内部
- 连续尝试多个表情方案
- 最近遇到的问题:
正式版修到 1.0.1 时,普通文字又可以发;表情应使用 fileId 方案。若继续修,重点检查 extractDatasetEmoji 只识别真正大表情,不要误判普通消息图片。