Skip to content

Commit

Permalink
Refresh video link after error
Browse files Browse the repository at this point in the history
  • Loading branch information
xfangfang committed Nov 9, 2023
1 parent f355389 commit 54c49e1
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 25 deletions.
9 changes: 6 additions & 3 deletions wiliwili/include/activity/live_player_activity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class LiveActivity : public brls::Activity, public LiveDataRequest {

explicit LiveActivity(const bilibili::LiveVideoResult& live);
explicit LiveActivity(int roomid, const std::string& name = "",
const std::string& views = "");
const std::string& views = "");

void setCommonData();

Expand All @@ -37,9 +37,12 @@ class LiveActivity : public brls::Activity, public LiveDataRequest {
private:
BRLS_BIND(VideoView, video, "fullscreen/video");

// 暂停的延时函数 handle
size_t toggleDelayIter = 0;
// 遇到错误重试的延时函数 handle
size_t errorDelayIter = 0;

bilibili::LiveVideoResult liveData;
// 视频超时的时间戳
std::chrono::system_clock::time_point videoExpires{};

//更新timeLabel
MPVEvent::Subscription tl_event_id;
Expand Down
10 changes: 7 additions & 3 deletions wiliwili/include/presenter/live_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ class LiveDataRequest : public Presenter {
onLiveData(liveRoomPlayInfo);
},
[ASYNC_TOKEN](BILI_ERR) {
ASYNC_RELEASE
this->onError(error);
brls::sync([ASYNC_TOKEN, error]() {
ASYNC_RELEASE
this->onError(error);
});
});

reportHistory(roomid);
Expand All @@ -66,7 +68,9 @@ class LiveDataRequest : public Presenter {
[roomid]() {
brls::Logger::debug("report live history {}", roomid);
},
[this](BILI_ERR) { this->onError(error); });
[](BILI_ERR) {
brls::Logger::error("report live history:", error);
});
}

std::string getQualityDescription(int qn) {
Expand Down
1 change: 1 addition & 0 deletions wiliwili/include/view/mpv_core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ class MPVCore : public brls::Singleton<MPVCore> {
double playback_time = 0;
double percent_pos = 0;
int64_t video_progress = 0;
int mpv_error_code = 0;

// 低画质解码,剔除解码过程中的部分步骤,可以用来节省cpu
inline static bool LOW_QUALITY = false;
Expand Down
61 changes: 42 additions & 19 deletions wiliwili/source/activity/live_player_activity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ static void onDanmakuReceived(std::string&& message) {
LiveActivity::LiveActivity(const bilibili::LiveVideoResult& live)
: liveData(live) {
brls::Logger::debug("LiveActivity: create: {}", live.roomid);
MPVCore::instance().command_async("set", "loop-playlist", "force");
this->setCommonData();
GA("open_live", {{"id", std::to_string(live.roomid)}})
GA("open_live", {{"live_id", std::to_string(live.roomid)}})
Expand All @@ -74,7 +73,6 @@ LiveActivity::LiveActivity(const bilibili::LiveVideoResult& live)
LiveActivity::LiveActivity(int roomid, const std::string& name,
const std::string& views) {
brls::Logger::debug("LiveActivity: create: {}", roomid);
MPVCore::instance().command_async("set", "loop-playlist", "force");
this->liveData.roomid = roomid;
this->liveData.title = name;
this->liveData.watched_show.text_large = views;
Expand Down Expand Up @@ -102,19 +100,34 @@ void LiveActivity::setCommonData() {
tl_event_id = MPV_E->subscribe([this](MpvEventEnum e) {
if (e == UPDATE_PROGRESS) {
if (!liveRoomPlayInfo.live_time) return;
auto timeNow = std::chrono::system_clock::now();
std::chrono::time_point<std::chrono::system_clock> _zero;
size_t now = std::chrono::duration_cast<std::chrono::seconds>(
timeNow - _zero)
std::chrono::system_clock::now() - _zero)
.count();
this->video->setStatusLabelLeft(
wiliwili::sec2Time(now - liveRoomPlayInfo.live_time));
if (timeNow > videoExpires) {
MPVCore::instance().pause();
// 十秒后再次检查,避免链接获取失败
videoExpires = timeNow + std::chrono::seconds(10);
requestData(liveData.roomid);
} else if (e == MPV_FILE_ERROR) {
this->video->showOSD(false);
this->video->setStatusLabelLeft("播放错误");

switch (MPVCore::instance().mpv_error_code) {
case MPV_ERROR_UNKNOWN_FORMAT:
this->video->setOnlineCount("暂不支持当前视频格式");
break;
case MPV_ERROR_LOADING_FAILED:
this->video->setOnlineCount("加载失败");
// 加载失败时,获取直播间信息,查看是否直播间已经关闭
// 如果直播间信息获取失败,则认定为断网,每隔N秒重试一次
this->requestData(liveData.roomid);
default:
this->video->setOnlineCount(
{mpv_error_string(MPVCore::instance().mpv_error_code)});
}
} else if (e == END_OF_FILE) {
// flv 直播遇到网络错误不会报错,而是输出 END_OF_FILE
// 直播间关闭时也可能进入这里
this->video->setOnlineCount("加载失败");
this->requestData(liveData.roomid);
}
});
}
Expand Down Expand Up @@ -170,8 +183,9 @@ void LiveActivity::onContentAvailable() {
} else {
this->video->showOSD(false);
MPVCore::instance().pause();
brls::cancelDelay(toggleDelayIter);
ASYNC_RETAIN
brls::delay(5000, [ASYNC_TOKEN]() {
toggleDelayIter = brls::delay(5000, [ASYNC_TOKEN]() {
ASYNC_RELEASE
if (MPVCore::instance().isPaused()) {
MPVCore::instance().stop();
Expand Down Expand Up @@ -208,9 +222,13 @@ int LiveActivity::getCurrentQualityIndex() {
}

void LiveActivity::onLiveData(const bilibili::LiveRoomPlayInfo& result) {
// todo:定时获取在线人数
this->video->setOnlineCount(liveData.watched_show.text_large);

if (result.live_status != 1) {
// 未开播
brls::Logger::error("LiveActivity: not live");
this->video->showOSD(false);
this->video->setStatusLabelLeft("未开播");
return;
}
Expand All @@ -227,13 +245,6 @@ void LiveActivity::onLiveData(const bilibili::LiveRoomPlayInfo& result) {
for (const auto& i : liveUrl.url_info) {
auto url = i.host + liveUrl.base_url + i.extra;

// 查找过期时间
// 链接中写的超时时间为1小时,但是实际测试能播放6小时
// 暂时设置为固定的5小时,避免系统时间是错误的没办法直接和视频链接中的 expires 进行比较。
// 另外的解决办法是获取一下网络时间
videoExpires =
std::chrono::system_clock::now() + std::chrono::seconds(18000);

// 设置视频链接
brls::Logger::debug("Live stream url: {}", url);
this->video->setUrl(url);
Expand All @@ -243,15 +254,27 @@ void LiveActivity::onLiveData(const bilibili::LiveRoomPlayInfo& result) {

void LiveActivity::onError(const std::string& error) {
brls::Logger::error("ERROR request live data: {}", error);
this->video->showOSD(false);
this->video->setOnlineCount(error);

// 每隔1秒自动重试
brls::cancelDelay(errorDelayIter);
ASYNC_RETAIN
errorDelayIter = brls::delay(1000, [ASYNC_TOKEN]() {
ASYNC_RELEASE
this->requestData(liveData.roomid);
});
}

LiveActivity::~LiveActivity() {
brls::Logger::debug("LiveActivity: delete");
this->video->stop();
LiveDanmaku::instance().disconnect();
// 取消监控mpv
MPV_CE->unsubscribe(event_id);
MPV_E->unsubscribe(tl_event_id);
MPVCore::instance().command_async("set", "loop-playlist", "1");
// 在取消监控之后再停止播放器,避免在播放器停止时触发事件 (尤其是:END_OF_FILE)
this->video->stop();
LiveDanmakuCore::instance().reset();
brls::cancelDelay(toggleDelayIter);
brls::cancelDelay(errorDelayIter);
}
2 changes: 2 additions & 0 deletions wiliwili/source/view/mpv_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,7 @@ void MPVCore::eventMainLoop() {
disableDimming(false);
auto node = (mpv_event_end_file *)event->data;
if (node->reason == MPV_END_FILE_REASON_ERROR) {
mpv_error_code = node->error;
brls::Logger::error("========> MPV ERROR: {}",
mpv_error_string(node->error));
mpvCoreEvent.fire(MpvEventEnum::MPV_FILE_ERROR);
Expand Down Expand Up @@ -887,6 +888,7 @@ void MPVCore::reset() {
this->cache_speed = 0; // Bps
this->playback_time = 0;
this->video_progress = 0;
this->mpv_error_code = 0;

// 软硬解切换后应该手动设置一次渲染尺寸
// 切换视频前设置渲染尺寸可以顺便将上一条视频的最后一帧画面清空
Expand Down

0 comments on commit 54c49e1

Please sign in to comment.