From 398babc3db8d1981e08ea9ff2b1fa3de0561caf5 Mon Sep 17 00:00:00 2001 From: rydesun Date: Tue, 11 Nov 2025 08:33:15 +0800 Subject: [PATCH] mpv config: add timemarks --- .config/mpv/input.conf | 4 +- .config/mpv/script-opts/uosc.conf | 5 + .config/mpv/scripts/autoload_series.lua | 1 + .config/mpv/scripts/timeline-marker.lua | 129 ++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 .config/mpv/script-opts/uosc.conf create mode 100644 .config/mpv/scripts/timeline-marker.lua diff --git a/.config/mpv/input.conf b/.config/mpv/input.conf index 31bdfe9..c01f795 100644 --- a/.config/mpv/input.conf +++ b/.config/mpv/input.conf @@ -1,7 +1,7 @@ UP add volume 2 DOWN add volume -2 -WHEEL_UP seek 10 -WHEEL_DOWN seek -10 +WHEEL_UP seek 1 +WHEEL_DOWN seek -1 Alt+LEFT add video-pan-x 0.01 Alt+RIGHT add video-pan-x -0.01 diff --git a/.config/mpv/script-opts/uosc.conf b/.config/mpv/script-opts/uosc.conf new file mode 100644 index 0000000..bd78d97 --- /dev/null +++ b/.config/mpv/script-opts/uosc.conf @@ -0,0 +1,5 @@ +top_bar=always + +use_trash=yes + +controls=menu,gap,subtitles,audio,video,editions,stream-quality,gap,command:add_location_alt:script_message xattr-append-timemark?添加时间标记,command:wrong_location:script_message xattr-remove-timemark?删除时间标记,space,shuffle,loop-playlist,loop-file,gap,prev,items,next,gap,command:rotate_90_degrees_cw:cycle_values video-rotate "90" "180" "270" "0";set geometry 90%x95%+50%+50%?旋转90°,command:fullscreen:set geometry 90%x95%+50%+50%?缩放至屏幕大小 diff --git a/.config/mpv/scripts/autoload_series.lua b/.config/mpv/scripts/autoload_series.lua index 0918223..6f3a16b 100644 --- a/.config/mpv/scripts/autoload_series.lua +++ b/.config/mpv/scripts/autoload_series.lua @@ -48,6 +48,7 @@ local function similar_files(dir, filename) goto continue end local basename, ext = file:match("(.+)%.(.+)") + if not ext then goto continue end ext = ext:lower() if ext ~= o_ext then goto continue diff --git a/.config/mpv/scripts/timeline-marker.lua b/.config/mpv/scripts/timeline-marker.lua new file mode 100644 index 0000000..c755451 --- /dev/null +++ b/.config/mpv/scripts/timeline-marker.lua @@ -0,0 +1,129 @@ +local mp = require 'mp' + +local function get_xattr_comment(path) + local p = io.popen(string.format( + "getfattr -n user.timemarks --only-values %q 2>/dev/null", path + )) + if not p then return nil end + local out = p:read("*a") + p:close() + return #out > 0 and out or nil +end + +local function set_xattr_comment(path, comment) + local cmd + if comment == "" then + cmd = string.format("setfattr -x user.timemarks %q", path) + else + cmd = string.format("setfattr -n user.timemarks -v %q %q", comment, path) + end + os.execute(cmd) +end + +local function parse_time(tstr) + local h, m, s + if tstr:match("^%d+:%d+:%d+$") then + h, m, s = tstr:match("^(%d+):(%d+):(%d+)$") + return tonumber(h) * 3600 + tonumber(m) * 60 + tonumber(s) + elseif tstr:match("^%d+:%d+$") then + m, s = tstr:match("^(%d+):(%d+)$") + return tonumber(m) * 60 + tonumber(s) + end +end + +local function format_time(sec) + local h = math.floor(sec / 3600) + local m = math.floor((sec % 3600) / 60) + local s = math.floor(sec % 60) + if h > 0 then + return string.format("%d:%02d:%02d", h, m, s) + else + return string.format("%02d:%02d", m, s) + end +end + +local function to_timemark(time_str, title) + local sec = parse_time(time_str) + if not sec then return end + return { time = sec, title = (#title > 0) and title or "" } +end + +local function get_timemarks() + local path = mp.get_property("path") + if not path then return end + local comment = get_xattr_comment(path) + if not comment then return end + + local marks = {} + for time_str, title in comment:gmatch("{(%d+:%d+:%d+)%s*([^:}]*)}") do + local mark = to_timemark(time_str, title) + if mark then table.insert(marks, mark) end + end + for time_str, title in comment:gmatch("{(%d+:%d+)%s*([^:}]*)}") do + local mark = to_timemark(time_str, title) + if mark then table.insert(marks, mark) end + end + table.sort(marks, function(a, b) return a.time < b.time end) + return marks +end + +local function create_chapters() + local marks = get_timemarks() + if marks and #marks > 0 then + mp.set_property_native("chapter-list", marks) + end +end + +local function get_current_chapter_pos() + local chapter_list = mp.get_property_native("chapter-list") + if not chapter_list or #chapter_list == 0 then return end + local current_time = mp.get_property_number("time-pos", 0) + + local current_chapter + for _, chapter in ipairs(chapter_list) do + if current_time >= chapter.time then + current_chapter = chapter + else + break + end + end + return current_chapter and current_chapter.time or nil +end + +local function append_current_time() + local path = mp.get_property("path") + if not path then return end + local pos = mp.get_property_number("time-pos") + if not pos then return end + local tstr = format_time(pos) + local comment = get_xattr_comment(path) or "" + comment = comment .. "{" .. tstr .. "}" + set_xattr_comment(path, comment) + mp.osd_message("添加时间标记:" .. tstr) + create_chapters() +end + +local function remove_current_time() + local current_chapter_pos = get_current_chapter_pos() + if not current_chapter_pos then return end + + mp.commandv("seek", current_chapter_pos, "absolute") + local tstr = format_time(current_chapter_pos) + local path = mp.get_property("path") + if not path then return end + local comment = get_xattr_comment(path) or "" + comment = comment:gsub("{" .. tstr .. "%s*[^}]*}", "") + set_xattr_comment(path, comment) + mp.osd_message("删除时间标记:" .. tstr) + local marks = get_timemarks() + if marks and #marks > 0 then + mp.set_property_native("chapter-list", marks) + else + -- 必须清空所有章节信息 + mp.set_property_native("chapter-list", {}) + end +end + +mp.register_event("file-loaded", create_chapters) +mp.register_script_message("xattr-append-timemark", append_current_time) +mp.register_script_message("xattr-remove-timemark", remove_current_time)