Skip to content

Commit

Permalink
Support danmaku mask (#245)
Browse files Browse the repository at this point in the history
* Support danmaku mask
https://www.bilibili.com/read/cv24222913/

* Fix ntohll missing in some platform

* Fix build error

* import ntohll

* Support PS4

* remove useless code

* Fix incomplete display of danmaku in blank areas

* Fix danmaku not following video speed
Intrduced by: 5a3bf75

* Fix PS4 GPU crash

* Add ui option

* Update borealis
  • Loading branch information
xfangfang authored Dec 7, 2023
1 parent 9a00d4b commit 2700519
Show file tree
Hide file tree
Showing 27 changed files with 711 additions and 20 deletions.
2 changes: 1 addition & 1 deletion library/borealis
Submodule borealis updated 33 files
+2 −1 README.md
+10 −2 demo/main.cpp
+7 −4 library/CMakeLists.txt
+1 −0 library/cmake/commonOption.cmake
+6 −1 library/cmake/toolchain.cmake
+12 −16 library/include/borealis/core/logger.hpp
+17 −0 library/include/borealis/extern/nanovg/nanovg.h
+1,566 −0 library/include/borealis/extern/nanovg/nanovg_d3d11.h
+42 −3 library/include/borealis/extern/nanovg/nanovg_gl.h
+2 −2 library/include/borealis/extern/nanovg/nanovg_ps4.h
+630 −0 library/include/borealis/extern/nanovg/nvg_shader/D3D11PixelShader.h
+107 −0 library/include/borealis/extern/nanovg/nvg_shader/D3D11PixelShader.hlsl
+688 −0 library/include/borealis/extern/nanovg/nvg_shader/D3D11PixelShaderAA.h
+2 −0 library/include/borealis/extern/nanovg/nvg_shader/D3D11PixelShaderAA.hlsl
+2 −0 library/include/borealis/extern/nanovg/nvg_shader/D3D11PixelShaderNoAA.hlsl
+242 −0 library/include/borealis/extern/nanovg/nvg_shader/D3D11VertexShader.h
+25 −0 library/include/borealis/extern/nanovg/nvg_shader/D3D11VertexShader.hlsl
+6 −0 library/include/borealis/extern/nanovg/nvg_shader/d3d_shaders.bat
+11 −0 library/include/borealis/extern/nanovg/nvg_shader/d3d_shaders.ps1
+48 −45 library/include/borealis/platforms/driver/d3d11.hpp
+0 −7 library/include/borealis/platforms/driver/winrt.hpp
+1 −1 library/lib/core/application.cpp
+5 −0 library/lib/core/logger.cpp
+17 −0 library/lib/extern/nanovg/nanovg.c
+563 −5 library/lib/extern/nanovg/ps4/nanovg_ps4.c
+12 −0 library/lib/platforms/desktop/desktop_winrt.cpp
+251 −277 library/lib/platforms/driver/d3d11.cpp
+0 −26 library/lib/platforms/driver/winrt.cpp
+31 −36 library/lib/platforms/glfw/glfw_video.cpp
+44 −26 library/lib/platforms/sdl/sdl_video.cpp
+2 −24 library/lib/platforms/switch/switch_wrapper.c
+7 −10 library/lib/views/debug_layer.cpp
+0 −1 xmake.lua
1 change: 1 addition & 0 deletions resources/i18n/en-US/wiliwili.json
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@
},
"filter": {
"header": "Danmaku filter",
"mask": "Smart mask",
"top": "Top",
"scroll": "Scroll",
"bottom": "Bottom",
Expand Down
1 change: 1 addition & 0 deletions resources/i18n/zh-Hans/wiliwili.json
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@
},
"filter": {
"header": "弹幕过滤",
"mask": "智能防挡",
"top": "顶部弹幕",
"scroll": "滚动弹幕",
"bottom": "底部弹幕",
Expand Down
1 change: 1 addition & 0 deletions resources/i18n/zh-Hant/wiliwili.json
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@
},
"filter": {
"header": "彈幕篩選",
"mask": "智慧防擋",
"top": "頂部",
"scroll": "滾動",
"bottom": "底部",
Expand Down
5 changes: 5 additions & 0 deletions resources/svg/ico-space-activate.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions resources/svg/ico-space.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions resources/xml/fragment/player_danmaku_setting.xml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@
<SelectorCell
id="player/danmaku/filter/level"/>

<brls:BooleanCell
id="player/danmaku/filter/mask"/>

<brls:BooleanCell
id="player/danmaku/filter/scroll"/>

Expand Down
6 changes: 6 additions & 0 deletions resources/xml/fragment/space_tab.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<brls:Box
id="space/container"
axis="column"
width="auto"
height="auto">
</brls:Box>
65 changes: 65 additions & 0 deletions scripts/psv/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
FROM vitasdk/vitasdk:latest

MAINTAINER xfangfang <[email protected]>

RUN apk update && \
apk add cmake ninja meson pkgconf bash git zstd tar patch && \
git config --global --add safe.directory $(pwd)

# Copy PVR_PSP2 (GLES) to vita toolchain dir
RUN mkdir -p /vita/dependencies/include && \
mkdir -p /vita/dependencies/lib && \
mkdir -p /vita/dependencies/suprx && \
pvr_psp2_version=3.9 && \
wget https://github.com/GrapheneCt/PVR_PSP2/archive/refs/tags/v$pvr_psp2_version.zip -P/tmp && \
unzip /tmp/v$pvr_psp2_version.zip -d/tmp && \
cp -r /tmp/PVR_PSP2-$pvr_psp2_version/include/* /vita/dependencies/include && \
sed -i -e s/__drvkhrplatform_h_/__khrplatform_h_/ /vita/dependencies/include/KHR/khrplatform.h && \
wget https://github.com/GrapheneCt/PVR_PSP2/releases/download/v$pvr_psp2_version/vitasdk_stubs.zip -P/tmp && \
unzip /tmp/vitasdk_stubs.zip -d/tmp/pvr_psp2_stubs && \
find /tmp/pvr_psp2_stubs -type f -name "*.a" -exec cp {} /vita/dependencies/lib \; && \
wget https://github.com/GrapheneCt/PVR_PSP2/releases/download/v$pvr_psp2_version/PSVita_Release.zip -P/tmp && \
unzip /tmp/PSVita_Release.zip -d/tmp/PSVita_Release && \
rm /tmp/PSVita_Release/libGLESv1_CM.suprx && \
rm /tmp/PSVita_Release/libpvr2d.suprx && \
mv /tmp/PSVita_Release/*.suprx /vita/dependencies/suprx/ && \
cp -rv /vita/dependencies/* ${VITASDK}/arm-vita-eabi && \
rm -rf /vita && \
rm -rf /tmp/*

# Install VDPM Dependencies
ADD . /vdpm
RUN vdpm mbedtls libass harfbuzz fribidi freetype libpng libwebp && \
adduser --gecos '' --disabled-password builder && \
echo 'builder ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/builder && \
chown -R builder:builder /vdpm && \
ls -l /vdpm && \
su - builder -c "cd /vdpm/ffmpeg && vita-makepkg" && \
su - builder -c "cd /vdpm/curl && vita-makepkg" && \
su - builder -c "cd /vdpm/sdl2 && vita-makepkg" && \
vdpm /vdpm/ffmpeg/*-arm.tar.xz && \
vdpm /vdpm/sdl2/*-arm.tar.xz && \
touch /tmp/vdpm_install_ffmpeg && \
touch /tmp/vdpm_install_sdl2 && \
su - builder -c "cd /vdpm/mpv && vita-makepkg" && \
vdpm /vdpm/curl/*-arm.tar.xz && \
vdpm /vdpm/mpv/*-arm.tar.xz && \
touch /tmp/vdpm_install_curl && \
touch /tmp/vdpm_install_mpv && \
rm -rf /vdpm

RUN mkdir /src/ &&\
echo \#\!/bin/bash -i >> /entrypoint.sh &&\
echo >> /entrypoint.sh &&\
echo "set -e" >> /entrypoint.sh &&\
echo "make -p /src/scripts/psv/module/" >> /entrypoint.sh &&\
echo "cp ${VITASDK}/arm-vita-eabi/suprx/*.suprx /src/scripts/psv/module/" >> /entrypoint.sh &&\
echo "cd /src" >> /entrypoint.sh &&\
echo "echo \"\$@\"" >> /entrypoint.sh &&\
echo "bash -c \"\$@\"" >> /entrypoint.sh &&\
chmod +x /entrypoint.sh

VOLUME /src/
WORKDIR /src/
SHELL ["/bin/bash", "-i", "-c"]
ENTRYPOINT ["/entrypoint.sh"]
1 change: 1 addition & 0 deletions scripts/switch/mpv_deko3d/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mpv.patch
8 changes: 7 additions & 1 deletion wiliwili/include/api/bilibili.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ using Cookies = std::map<std::string, std::string>;
using ErrorCallback = std::function<void(const std::string&, int code)>;

#define BILI bilibili::BilibiliClient
#define BILI_ERR const std::string& error, int code
#define BILI_ERR const std::string &error, int code

class BilibiliClient {
inline static std::function<void(Cookies, std::string)>
Expand Down Expand Up @@ -246,6 +246,12 @@ class BilibiliClient {
const std::function<void(VideoPageResult)>& callback = nullptr,
const ErrorCallback& error = nullptr);

/// 获取视频防遮挡数据
static void get_webmask(
const std::string& url,
const std::function<void(std::string)>& callback = nullptr,
const ErrorCallback& error = nullptr);

/// get video pagelist by aid
static void get_video_pagelist(
int aid,
Expand Down
12 changes: 10 additions & 2 deletions wiliwili/include/api/bilibili/result/video_detail_result.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,8 @@ inline void from_json(const nlohmann::json& nlohmann_json_j,
} else {
nlohmann_json_t.upper = 0;
}
if (nlohmann_json_j.contains("root") && !nlohmann_json_j.at("root").is_null()) {
if (nlohmann_json_j.contains("root") &&
!nlohmann_json_j.at("root").is_null()) {
nlohmann_json_j.at("root").get_to(nlohmann_json_t.root);
}
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, cursor));
Expand Down Expand Up @@ -637,6 +638,7 @@ class VideoPageResult {
int64_t last_play_time;
int last_play_cid;
VideoPageSubtitleList subtitles;
std::string mask_url;
};
inline void from_json(const nlohmann::json& nlohmann_json_j,
VideoPageResult& nlohmann_json_t) {
Expand All @@ -649,6 +651,12 @@ inline void from_json(const nlohmann::json& nlohmann_json_j,
}
}
}
if (nlohmann_json_j.contains("dm_mask") &&
nlohmann_json_j.at("dm_mask").is_object()) {
nlohmann_json_j.at("dm_mask")
.at("mask_url")
.get_to(nlohmann_json_t.mask_url);
}
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, online_count,
last_play_time, last_play_cid));
}
Expand Down Expand Up @@ -705,7 +713,7 @@ class VideoHighlightProgress {
std::vector<float> data;
};
inline void from_json(const nlohmann::json& nlohmann_json_j,
VideoHighlightProgress& nlohmann_json_t) {
VideoHighlightProgress& nlohmann_json_t) {
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, step_sec));
if (!nlohmann_json_j.contains("events")) return;
if (!nlohmann_json_j.at("events").is_object()) return;
Expand Down
1 change: 1 addition & 0 deletions wiliwili/include/fragment/player_danmaku_setting.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class PlayerDanmakuSetting : public brls::Box {

private:
BRLS_BIND(SelectorCell, cellLevel, "player/danmaku/filter/level");
BRLS_BIND(brls::BooleanCell, cellMask, "player/danmaku/filter/mask");
BRLS_BIND(brls::BooleanCell, cellScroll, "player/danmaku/filter/scroll");
BRLS_BIND(brls::BooleanCell, cellTop, "player/danmaku/filter/top");
BRLS_BIND(brls::BooleanCell, cellBottom, "player/danmaku/filter/bottom");
Expand Down
48 changes: 48 additions & 0 deletions wiliwili/include/fragment/space_tab.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// Created by fang on 2022/6/14.
//

// register this fragment in main.cpp
//#include "fragment/home_recommends.hpp"
// brls::Application::registerXMLView("HomeRecommends", HomeRecommends::create);
// <brls:View xml=@res/xml/fragment/home_recommends.xml

#pragma once

#include "presenter/home_recommends.hpp"
#include "view/auto_tab_frame.hpp"

namespace brls {
class Box;
}

class SpaceTab : public AttachedView, public Home {
public:
SpaceTab();

void onRecommendVideoList(
const bilibili::RecommendVideoListResultWrapper &result) override;

~SpaceTab() override;

static View *create();

void onCreate() override;

void draw(NVGcontext *vg, float x, float y, float width, float height,
brls::Style style, brls::FrameContext *ctx) override;

void onLayout() override;

void willDisappear(bool resetState) override;

void willAppear(bool resetState) override;

void onResume();

void onError(const std::string &error) override;

private:
BRLS_BIND(brls::Box, recyclingGrid, "space/container");
brls::Rect oldRect = brls::Rect(-1, -1, -1, -1);
};
1 change: 1 addition & 0 deletions wiliwili/include/utils/config_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ enum class SettingItem {
DANMAKU_FILTER_TOP,
DANMAKU_FILTER_BOTTOM,
DANMAKU_FILTER_COLOR,
DANMAKU_SMART_MASK,
DANMAKU_STYLE_AREA,
DANMAKU_STYLE_ALPHA,
DANMAKU_STYLE_FONTSIZE,
Expand Down
2 changes: 2 additions & 0 deletions wiliwili/include/utils/string_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ std::string base64Encode(const std::string &in);

int base64Decode(const std::string &in, std::string &out);

std::string decompressGzipData(const std::string &compressedData);

template <typename... Args> inline std::string format(fmt::string_view fmt, Args&&... args) {
return fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...);
}
Expand Down
53 changes: 49 additions & 4 deletions wiliwili/include/view/danmaku_core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,42 @@

#include <mutex>

#include <borealis.hpp>
#include <borealis/core/singleton.hpp>
#include "nanovg.h"

// 每个分片内的svg数据,一般 1/30 s 一帧
class MaskSvg {
public:
MaskSvg(const std::string &svg, uint64_t t) : svg(svg), showTime(t) {}
std::string svg;
uint64_t showTime;
};

// 一般 10s 一个分片
class MaskSlice {
public:
MaskSlice(uint64_t time, uint64_t offsetStart, uint64_t offsetEnd)
: time(time), offsetStart(offsetStart), offsetEnd(offsetEnd) {}
uint64_t time{};
uint64_t offsetStart{};
uint64_t offsetEnd{};
std::vector<MaskSvg> svgData;
};

class WebMask {
public:
std::string url;
uint32_t version, check, length;
std::vector<MaskSlice> sliceData;

const MaskSlice &getSlice(size_t index);

void parse(const std::string &text);

void clear();

private:
std::string rawData;
};

class DanmakuItem {
public:
Expand Down Expand Up @@ -79,8 +112,8 @@ class DanmakuCore : public brls::Singleton<DanmakuCore> {
* @param height 绘制区域的高度
* @param alpha 组件的透明度,与弹幕本身的透明度叠加
*/
void draw(NVGcontext *vg, float x, float y, float width,
float height, float alpha);
void draw(NVGcontext *vg, float x, float y, float width, float height,
float alpha);

/**
* 加载弹幕数据
Expand All @@ -100,13 +133,20 @@ class DanmakuCore : public brls::Singleton<DanmakuCore> {
*/
std::vector<DanmakuItem> getDanmakuData();

/**
* 加载遮罩数据
* @param data 遮罩数据
*/
void loadMaskData(const WebMask &data);

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

static inline bool DANMAKU_FILTER_SHOW_TOP = true;
static inline bool DANMAKU_FILTER_SHOW_BOTTOM = true;
static inline bool DANMAKU_FILTER_SHOW_SCROLL = true;
static inline bool DANMAKU_FILTER_SHOW_COLOR = true;
static inline bool DANMAKU_SMART_MASK = true;

/// [25, 50, 75, 100]
static inline int DANMAKU_STYLE_AREA = 100;
Expand Down Expand Up @@ -135,6 +175,11 @@ class DanmakuCore : public brls::Singleton<DanmakuCore> {
// 弹幕列表
std::vector<DanmakuItem> danmakuData;

WebMask maskData{};
size_t maskIndex = 0;
size_t maskSliceIndex = 0;
int maskTex = 0;

// 滚动弹幕的信息 <起始时间,结束时间>
std::vector<std::pair<float, float>> scrollLines;

Expand Down
23 changes: 23 additions & 0 deletions wiliwili/source/api/video_detail_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,29 @@ void BilibiliClient::get_page_detail(
callback, error);
}

void BilibiliClient::get_webmask(
const std::string& url,
const std::function<void(std::string)>& callback,
const ErrorCallback& error) {
cpr::GetCallback<>(
[callback, error](const cpr::Response& r) {
try {
callback(r.text);
} catch (const std::exception& e) {
ERROR_MSG("Network error. [Status code: " +
std::to_string(r.status_code) + " ]",
r.status_code);
printf("data: %s\n", r.text.c_str());
printf("ERROR: %s\n", e.what());
}
},
#ifndef VERIFY_SSL
cpr::VerifySsl{false},
#endif
cpr::Url{url}, HTTP::HEADERS, HTTP::COOKIES,
cpr::Timeout{HTTP::TIMEOUT});
}

void BilibiliClient::get_video_pagelist(
const std::string& bvid,
const std::function<void(VideoDetailPageListResult Result)>& callback,
Expand Down
Loading

0 comments on commit 2700519

Please sign in to comment.