From 7b16993a0bbd8789521e0c572ec30624be96b9bc Mon Sep 17 00:00:00 2001 From: dyphire Date: Wed, 20 Nov 2024 12:00:48 +0800 Subject: [PATCH 1/2] fix: danmaku loading logic --- api.lua | 28 ++++++++++++++-------------- main.lua | 2 +- render.lua | 4 ++-- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/api.lua b/api.lua index ee269d0..1dd0bc9 100644 --- a/api.lua +++ b/api.lua @@ -672,13 +672,13 @@ function add_danmaku_source(query, from_menu) end if is_protocol(query) then - add_danmaku_source_online(query) + add_danmaku_source_online(query, from_menu) else - add_danmaku_source_local(query) + add_danmaku_source_local(query, from_menu) end end -function add_danmaku_source_local(query) +function add_danmaku_source_local(query, from_menu) local path = normalize(query) if not file_exists(path) then msg.verbose("无效的文件路径") @@ -696,11 +696,11 @@ function add_danmaku_source_local(query) convert_with_danmaku_factory(danmaku_input) local danmaku_file = utils.join_path(danmaku_path, "danmaku.ass") - load_danmaku(danmaku_file) + load_danmaku(danmaku_file, from_menu) end --通过输入源url获取弹幕库 -function add_danmaku_source_online(query) +function add_danmaku_source_online(query, from_menu) local url = options.api_server .. "/api/v2/extcomment?url=" .. url_encode(query) mp.osd_message("弹幕加载中...", 30) msg.verbose("尝试获取弹幕:" .. url) @@ -749,7 +749,7 @@ function add_danmaku_source_online(query) convert_with_danmaku_factory(danmaku_input) local danmaku_file = utils.join_path(danmaku_path, "danmaku.ass") - load_danmaku(danmaku_file) + load_danmaku(danmaku_file, from_menu) end -- 将弹幕转换为factory可读的json格式 @@ -920,7 +920,7 @@ function get_danmaku_with_hash(file_name, file_path) end -- 从用户添加过的弹幕源添加弹幕 -function addon_danmaku(path) +function addon_danmaku(path, from_menu) local history_json = read_file(history_path) if history_json ~= nil then @@ -928,7 +928,7 @@ function addon_danmaku(path) local history_record = history[path] if history_record ~= nil then for _, source in ipairs(history_record) do - add_danmaku_source(source) + add_danmaku_source(source, from_menu) end end end @@ -967,7 +967,7 @@ function load_danmaku_for_bilibili(path) if path:match("video/BV.-/.*") then path = path:gsub("/[^/]+$", "") end - add_danmaku_source_online(path) + add_danmaku_source_online(path, true) return end if cid ~= nil then @@ -995,7 +995,7 @@ function load_danmaku_for_bilibili(path) local res = mp.command_native(cmd) if res.status == 0 and file_exists(danmaku_xml) then - add_danmaku_source_local(danmaku_xml) + add_danmaku_source_local(danmaku_xml, true) end end end @@ -1048,7 +1048,7 @@ function load_danmaku_for_bahamut(path) local res = mp.command_native(cmd) if res.status ~= 0 or not file_exists(danmaku_json) then local url = "https://ani.gamer.com.tw/animeVideo.php?sn=" .. sn - add_danmaku_source_online(url) + add_danmaku_source_online(url, true) return end @@ -1082,7 +1082,7 @@ function load_danmaku_for_bahamut(path) convert_with_danmaku_factory(json_filename) local danmaku_file = utils.join_path(danmaku_path, "danmaku.ass") - load_danmaku(danmaku_file) + load_danmaku(danmaku_file, true) end @@ -1142,13 +1142,13 @@ function init(path) if dir then local danmaku_xml = utils.join_path(dir, filename .. ".xml") if file_exists(danmaku_xml) then - add_danmaku_source_local(danmaku_xml) + add_danmaku_source_local(danmaku_xml, true) return end end get_danmaku_with_hash(filename, path) if options.add_from_source then - addon_danmaku(path) + addon_danmaku(path, true) end end end diff --git a/main.lua b/main.lua index 196394c..b9f53c2 100644 --- a/main.lua +++ b/main.lua @@ -328,7 +328,7 @@ mp.register_script_message("show_danmaku_keyboard", function() load_danmaku_for_bahamut(path) return end - init(path) + init(path) else if danmaku.anime and danmaku.episode then mp.osd_message("加载弹幕:" .. danmaku.anime .. "-" .. danmaku.episode.. ",共计" .. #comments .. "条弹幕", 3) diff --git a/render.lua b/render.lua index 8e5c58e..cec575d 100644 --- a/render.lua +++ b/render.lua @@ -176,11 +176,11 @@ function parse_danmaku(ass_file_path, from_menu) if enabled and (from_menu or get_danmaku_visibility()) then show_danmaku_func() - mp.commandv("script-message-to", "uosc", "set", "show_danmaku", "on") show_loaded() + mp.commandv("script-message-to", "uosc", "set", "show_danmaku", "on") else - enabled = false mp.osd_message("") + hide_danmaku_func() end end From d10bee7f967bd40cf7c71665172bdb8f8cb097f7 Mon Sep 17 00:00:00 2001 From: dyphire Date: Wed, 20 Nov 2024 12:58:52 +0800 Subject: [PATCH 2/2] feat: add `vf_fps` options to improve danmaku smoothness --- README.md | 17 +++++++++++++++++ options.lua | 2 ++ render.lua | 26 +++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c5f9303..9612bbc 100644 --- a/README.md +++ b/README.md @@ -317,6 +317,23 @@ user_agent=mpv_danmaku/1.0 ``` proxy=127.0.0.1:7890 ``` +### vf_fps + +#### 功能说明 + +指定是否使用 fps 视频滤镜`@danmaku:fps=fps=60/1.001`,可大幅提升弹幕平滑度。默认禁用 + +注意该视频滤镜的性能开销较大,需在确保设备性能足够的前提下开启 + +启用选项后仅在视频帧率小于 60 及显示器刷新率大于等于 60 时生效 + +#### 使用方法 + +想要使用此选项,请在mpv配置文件夹下的`script-opts`中创建`uosc_danmaku.conf`文件并指定如下内容: + +``` +vf_fps=yes +``` ### transparency diff --git a/options.lua b/options.lua index e879b38..d7a9cef 100644 --- a/options.lua +++ b/options.lua @@ -10,6 +10,8 @@ options = { add_from_source = false, user_agent = "mpv_danmaku/1.0", proxy = "", + -- 使用 fps 视频滤镜,大幅提升弹幕平滑度。默认禁用 + vf_fps = false, -- 透明度:0(不透明)到255(完全透明) transparency = 0x30, -- 指定合并重复弹幕的时间间隔的容差值,单位为秒。默认值: -1,表示禁用 diff --git a/render.lua b/render.lua index cec575d..86f2a87 100644 --- a/render.lua +++ b/render.lua @@ -175,8 +175,8 @@ function parse_danmaku(ass_file_path, from_menu) end if enabled and (from_menu or get_danmaku_visibility()) then - show_danmaku_func() show_loaded() + show_danmaku_func() mp.commandv("script-message-to", "uosc", "set", "show_danmaku", "on") else mp.osd_message("") @@ -184,6 +184,16 @@ function parse_danmaku(ass_file_path, from_menu) end end +local function filter_state(label, key, value) + local filters = mp.get_property_native("vf") + for _, filter in pairs(filters) do + if filter["label"] == label and (not key or key and filter[key] == value) then + return true + end + end + return false +end + function show_danmaku_func() render() if not pause then @@ -191,6 +201,14 @@ function show_danmaku_func() end enabled = true set_danmaku_visibility(true) + if options.vf_fps then + local display_fps = mp.get_property_number('display-fps') + local video_fps = mp.get_property_number('estimated-vf-fps') + if (display_fps and display_fps < 58) or (video_fps and video_fps > 58) then + return + end + mp.commandv("vf", "append", "@danmaku:fps=fps=60/1.001") + end end function hide_danmaku_func() @@ -198,6 +216,9 @@ function hide_danmaku_func() overlay:remove() enabled = false set_danmaku_visibility(false) + if filter_state("danmaku") then + mp.commandv("vf", "remove", "@danmaku") + end end mp.observe_property('osd-width', 'number', function(_, value) osd_width = value or osd_width end) @@ -234,6 +255,9 @@ mp.add_hook("on_unload", 50, function() comments, delay = nil, 0 timer:kill() overlay:remove() + if filter_state("danmaku") then + mp.commandv("vf", "remove", "@danmaku") + end local danmaku_path = os.getenv("TEMP") or "/tmp/" local rm1 = utils.join_path(danmaku_path, "danmaku.json")