Skip to content

Commit

Permalink
fix live danmaku
Browse files Browse the repository at this point in the history
  • Loading branch information
maye76 committed Nov 1, 2023
1 parent 86ccf4b commit 8ab3093
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 20 deletions.
5 changes: 4 additions & 1 deletion wiliwili/include/view/danmaku_core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ class DanmakuItem {
int64_t startTime = 0;
NVGcolor color = nvgRGBA(255, 255, 255, 160);
NVGcolor borderColor = nvgRGBA(0, 0, 0, 160);
int level; // 弹幕等级 1-10
int level; // 弹幕等级 1-10 直播弹幕等级0-60
int is_live; // 是否为直播弹幕
// 暂时用不到的信息,先不使用
// int pubDate; // 弹幕发送时间
// int pool; // 弹幕池类型
Expand Down Expand Up @@ -102,6 +103,8 @@ class DanmakuCore : public brls::Singleton<DanmakuCore> {

/// range: [1 - 10], 1: show all danmaku, 10: the most strong filter
static inline int DANMAKU_FILTER_LEVEL = 1;
//0-60
static inline int DANMAKU_FILTER_LEVEL_LIVE = 0;

static inline bool DANMAKU_FILTER_SHOW_TOP = true;
static inline bool DANMAKU_FILTER_SHOW_BOTTOM = true;
Expand Down
16 changes: 9 additions & 7 deletions wiliwili/source/activity/live_player_activity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@

using namespace brls::literals;

static void process_danmaku(danmaku_t* dan) {
//做其他处理
static void process_danmaku(const float time, danmaku_t* dan) {
//TODO:做其他处理
//...

//弹幕加载到视频中去
float time = MPVCore::instance().getPlaybackTime() + 0.1;
DanmakuCore::instance().addSingleDanmaku(DanmakuItem(time, dan));
float _time = MPVCore::instance().getPlaybackTime() + time;
DanmakuCore::instance().addSingleDanmaku(DanmakuItem(_time, dan));

danmaku_t_free(dan);
}
Expand All @@ -36,13 +36,15 @@ static void onDanmakuReceived(std::string&& message) {
return;
}

float time = 0.1f;
for (const auto& live_msg : extract_messages(messages)) {
if (live_msg.type == danmaku) {
if (!live_msg.ptr) continue;
process_danmaku((danmaku_t*)live_msg.ptr);
process_danmaku(time, (danmaku_t*)live_msg.ptr);
free(live_msg.ptr);
time += 0.2f;
} else if (live_msg.type == watched_change) {
//todo
//TODO: 更新在线人数
free(live_msg.ptr);
}
}
Expand Down Expand Up @@ -71,7 +73,7 @@ LiveActivity::LiveActivity(int roomid, const std::string& name,

void LiveActivity::setCommonData() {
DanmakuCore::instance().reset();
LiveDanmaku::instance().connect(liveData.roomid, 0 /*liveData.uid*/);
LiveDanmaku::instance().connect(liveData.roomid, liveData.uid);

// 清空字幕
SubtitleCore::instance().reset();
Expand Down
60 changes: 50 additions & 10 deletions wiliwili/source/api/danmaku_live.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
//

#include "live/danmaku_live.hpp"
#include "bilibili/util/http.hpp"
#include "live/ws_utils.hpp"

#include <iostream>
#include <queue>
#include <condition_variable>
#include <string>
#ifdef _WIN32
#include <winsock2.h>
#endif
Expand All @@ -16,7 +18,46 @@

using json = nlohmann::json;

const std::string url = "ws://broadcastlv.chat.bilibili.com:2244/sub";
static std::string url = "ws://broadcastlv.chat.bilibili.com:2244/sub";
static std::string buvid = "";
static std::string key = "";

void get_live_s(int room_id) {
for (const auto &i : bilibili::HTTP::COOKIES) {
if (i.GetName() == "buvid3") {
buvid = i.GetValue();
break;
}
}

auto res = bilibili::HTTP::get(
"https://api.live.bilibili.com/xlive/web-room/v1/index/"
"getDanmuInfo?type=0&id=" +
std::to_string(room_id));

if (res.status_code != 200) {
std::cout << "getDanmuInfo error" << std::endl;
} else {
std::cout << "getDanmuInfo success" << std::endl;
json _json;
try {
_json = json::parse(res.text);
} catch (const std::exception &e) {
std::cout << "getDanmuInfo json parse error" << std::endl;
}
if (_json["code"].get<int>() == 0) {
url = "ws://" +
_json["data"]["host_list"][0]["host"]
.get_ref<const std::string &>() +
":" +
std::to_string(
_json["data"]["host_list"][0]["ws_port"].get<int>()) +
"/sub";
std::cout << url << std::endl;
key = _json["data"]["token"].get_ref<const std::string &>();
}
}
}

LiveDanmaku::LiveDanmaku() {
#ifdef _WIN32
Expand Down Expand Up @@ -78,6 +119,8 @@ void LiveDanmaku::connect(int room_id, int uid) {
return;
}

get_live_s(room_id);

mg_log_set(MG_LL_NONE);
mg_mgr_init(this->mgr);

Expand Down Expand Up @@ -154,10 +197,10 @@ bool LiveDanmaku::is_connected() {

bool LiveDanmaku::is_evOK() { return ms_ev_ok.load(std::memory_order_acquire); }

void LiveDanmaku::send_join_request(int room_id, int uid) {
json join_request = {{"clientver", "1.6.3"}, {"platform", "web"},
{"protover", 2}, {"roomid", room_id},
{"uid", uid}, {"type", 2}};
void LiveDanmaku::send_join_request(const int room_id, const int uid) {
json join_request = {{"uid", uid}, {"roomid", room_id}, {"protover", 2},
{"buvid", buvid}, {"platform", "web"}, {"type", 2},
{"key", key}};
std::string join_request_str = join_request.dump();
std::vector<uint8_t> packet = encode_packet(0, 7, join_request_str);
std::string packet_str(packet.begin(), packet.end());
Expand Down Expand Up @@ -187,22 +230,19 @@ static void mongoose_event_handler(struct mg_connection *nc, int ev,
LiveDanmaku *liveDanmaku = static_cast<LiveDanmaku *>(user_data);
liveDanmaku->ms_ev_ok.store(true, std::memory_order_release);
if (ev == MG_EV_OPEN) {
nc->is_hexdumping = 1;
nc->is_hexdumping = 0;
} else if (ev == MG_EV_ERROR) {
//MG_ERROR(("%p %s", nc->fd, (char *) ev_data));
//liveDanmaku->disconnect();
MG_ERROR(("%p %s", nc->fd, (char *)ev_data));
liveDanmaku->ms_ev_ok.store(false, std::memory_order_release);
} else if (ev == MG_EV_WS_OPEN) {
liveDanmaku->send_join_request(liveDanmaku->room_id, liveDanmaku->uid);
mg_timer_add(liveDanmaku->mgr, 30000, MG_TIMER_REPEAT, heartbeat_timer,
user_data);
} else if (ev == MG_EV_WS_MSG) {
struct mg_ws_message *wm = (struct mg_ws_message *)ev_data;
//liveDanmaku->onMessage(std::string(wm->data.ptr, wm->data.len));
add_task(liveDanmaku->onMessage,
std::string(wm->data.ptr, wm->data.len));
} else if (ev == MG_EV_CLOSE) {
//liveDanmaku->disconnect();
liveDanmaku->ms_ev_ok.store(false, std::memory_order_release);
}
}
Expand Down
7 changes: 5 additions & 2 deletions wiliwili/source/view/danmaku_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ DanmakuItem::DanmakuItem(std::string content, const char *attributes)
fontSize = atoi(attrs[2].c_str());
fontColor = atoi(attrs[3].c_str());
level = atoi(attrs[8].c_str());
is_live = 0;

int r = (fontColor >> 16) & 0xff;
int g = (fontColor >> 8) & 0xff;
Expand Down Expand Up @@ -58,6 +59,7 @@ DanmakuItem::DanmakuItem(const float _time, danmaku_t *dan) {
fontSize = dan->dan_size;
fontColor = dan->dan_color;
level = dan->user_level;
is_live = 1;

int r = (fontColor >> 16) & 0xff;
int g = (fontColor >> 8) & 0xff;
Expand Down Expand Up @@ -270,7 +272,7 @@ void DanmakuCore::drawDanmaku(NVGcontext *vg, float x, float y, float width,
}
//滑动弹幕
float position = 0;
if (MPVCore::instance().isPaused()) {
if (!i.is_live && MPVCore::instance().isPaused()) {
// 暂停状态弹幕也要暂停
position = i.speed * (playbackTime - i.time);
i.startTime =
Expand Down Expand Up @@ -316,7 +318,8 @@ void DanmakuCore::drawDanmaku(NVGcontext *vg, float x, float y, float width,
/// 过滤弹幕
i.canShow = false;
// 1. 过滤显示的弹幕级别
if (i.level < DANMAKU_FILTER_LEVEL) continue;
if (!i.is_live && i.level < DANMAKU_FILTER_LEVEL) continue;
if (i.is_live && i.level < DANMAKU_FILTER_LEVEL_LIVE) continue;

if (i.type == 4) {
// 2. 过滤底部弹幕
Expand Down

0 comments on commit 8ab3093

Please sign in to comment.