wiliwili弹幕发送功能:API调用与权限控制
在B站观看视频时,弹幕(Danmaku)是增强互动体验的核心功能。wiliwili作为专为手柄控制设计的跨平台B站客户端,其弹幕系统需要在多种设备上稳定运行,同时确保符合B站API的权限要求。本文将深入解析wiliwili弹幕发送功能的实现细节,包括API调用流程、权限控制机制及相关代码结构。
弹幕系统架构概览
wiliwili的弹幕功能基于B站官方API实现,主要涉及两个核心模块:
- 弹幕数据接收:通过WebSocket连接实时获取直播间弹幕
- 弹幕发送控制:处理用户输入并通过API提交弹幕内容
核心实现文件包括:
- wiliwili/include/api/bilibili.h:定义B站API接口
- wiliwili/source/api/danmaku_live.cpp:实现直播弹幕接收与发送逻辑
- wiliwili/source/view/danmaku_core.hpp:弹幕渲染与显示控制
API调用流程
1. 弹幕服务器连接
在发送弹幕前,客户端需要先建立与B站弹幕服务器的WebSocket连接。这一过程通过get_live_danmaku_info接口实现:
void BilibiliClient::get_live_danmaku_info(int roomid,
const std::function<void(LiveDanmakuinfo)>& callback,
const ErrorCallback& error) {
HTTP::getResultWithWbiAsync<LiveDanmakuinfo>(
Api::LiveDanmakuInfo,
{{"type", "0"}, {"id", std::to_string(roomid)}},
callback,
error
);
}
该接口向B站API请求弹幕服务器信息,返回包含服务器地址、端口和认证Token的LiveDanmakuinfo结构体。客户端使用这些信息建立WebSocket连接:
std::string host = "ws://" + info.host_list[0].host + ":" +
std::to_string(info.host_list[0].ws_port) + "/sub";
nc = mg_ws_connect(mgr, host.c_str(), mongoose_event_handler, this, nullptr);
2. 身份认证与权限检查
发送弹幕需要用户登录状态,wiliwili通过Cookie管理实现身份验证。在wiliwili/include/api/bilibili.h中定义了Cookie存储机制:
class BilibiliClient {
public:
static Cookies cookies;
// ...
static void init(Cookies& data, std::function<void(Cookies, std::string)> callback);
};
登录状态通过get_login_url和get_login_info接口获取,成功登录后,客户端会保存认证Cookie用于后续API调用。
3. 弹幕发送实现
弹幕发送功能在LiveDanmaku类中实现,核心方法为send_text_message:
void LiveDanmaku::send_text_message(const std::string& message) {
if (!is_connected() || !mgr || !nc) return;
json danmaku = {
{"cmd", "SEND_DANMAKU"},
{"roomid", room_id},
{"content", message},
{"color", 16777215}, // 白色
{"fontsize", 25},
{"mode", 1} // 滚动弹幕
};
std::string data = danmaku.dump();
std::vector<uint8_t> packet = encode_packet(0, 7, data);
auto* packet_ptr = new std::string(packet.begin(), packet.end());
mg_wakeup(mgr, nc->id, &packet_ptr, sizeof(void*));
}
弹幕内容经过JSON序列化和特殊协议封装后,通过WebSocket发送到服务器。
权限控制机制
1. CSRF保护
B站API要求所有修改操作(包括发送弹幕)必须包含CSRF令牌。在wiliwili中,CSRF令牌从登录Cookie中提取:
std::string csrf_token;
for (const auto& cookie : BilibiliClient::cookies) {
if (cookie.first == "bili_jct") {
csrf_token = cookie.second;
break;
}
}
2. 频率限制
为防止滥用,wiliwili实现了本地弹幕发送频率控制:
bool LiveDanmaku::can_send_danmaku() {
time_t now = time(nullptr);
if (now - last_send_time < 5) { // 5秒冷却
return false;
}
last_send_time = now;
return true;
}
3. 内容过滤
客户端会对弹幕内容进行基本过滤,防止发送违规内容:
bool filter_danmaku_content(const std::string& content) {
if (content.length() > 200) return false; // 长度限制
if (ban_word_check(content)) return false; // 敏感词检查
return true;
}
多平台适配考量
wiliwili支持多种设备,弹幕功能在不同平台上有特殊处理:
- 手柄输入适配:在wiliwili/source/activity/live_player_activity.cpp中实现了手柄输入到文字的转换逻辑
- 性能优化:针对低性能设备(如PSVita),在wiliwili/source/view/danmaku_core.hpp中实现了弹幕渲染优化
- 网络适配:在wiliwili/source/api/bilibili.cpp中提供了网络代理设置:
void BilibiliClient::setProxy(const std::string& httpProxy, const std::string& httpsProxy) {
HTTP::PROXIES = {};
if (!httpProxy.empty() && !httpsProxy.empty()) {
HTTP::PROXIES = {{"http", httpProxy}, {"https", httpsProxy}};
}
}
常见问题与调试
连接失败排查
如果弹幕功能无法使用,可通过以下步骤排查:
- 检查网络连接状态
- 确认已登录账号(wiliwili/source/activity/mine_qr_login.cpp)
- 查看日志输出:
brls::Logger::info("(LiveDanmaku) join_request:{}", join_request_str);
错误码参考
| 错误码 | 含义 | 解决方案 |
|---|---|---|
| -403 | 权限不足 | 重新登录账号 |
| -100 | 连接超时 | 检查网络或更换服务器 |
| 34002 | 弹幕内容违规 | 修改内容后重试 |
总结
wiliwili弹幕发送功能通过合理的API调用流程和严格的权限控制,实现了跨平台环境下的稳定运行。核心代码位于wiliwili/source/api/danmaku_live.cpp和wiliwili/include/api/bilibili.h,通过WebSocket实时通信和Cookie身份验证,确保弹幕功能既安全又高效。
如需进一步扩展功能,可参考以下方向:
- 添加弹幕样式自定义(字体大小、颜色)
- 实现弹幕发送历史记录
- 增加弹幕翻译功能
通过本文的解析,希望能帮助开发者更好地理解和扩展wiliwili的弹幕系统。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考





