Skip to content

Commit 53aa359

Browse files
committed
update osc to mpv-player/mpv@448fe02
1 parent ddb8b1d commit 53aa359

File tree

1 file changed

+110
-16
lines changed

1 file changed

+110
-16
lines changed

src/patched_osc.lua

Lines changed: 110 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ local user_opts = {
4848
windowcontrols = "auto", -- whether to show window controls
4949
windowcontrols_alignment = "right", -- which side to show window controls on
5050
greenandgrumpy = false, -- disable santa hat
51+
livemarkers = true, -- update seekbar chapter markers on duration change
52+
chapters_osd = true, -- whether to show chapters OSD on next/prev
53+
playlist_osd = true, -- whether to show playlist OSD on next/prev
54+
chapter_fmt = "Chapter: %s", -- chapter print format for seekbar-hover. "no" to disable
5155
}
5256

5357
-- read options from config and command-line
@@ -358,6 +362,12 @@ local is_december = os.date("*t").month == 12
358362
-- Helperfunctions
359363
--
360364

365+
function kill_animation()
366+
state.anistart = nil
367+
state.animation = nil
368+
state.anitype = nil
369+
end
370+
361371
function set_osd(res_x, res_y, text)
362372
if state.osd.res_x == res_x and
363373
state.osd.res_y == res_y and
@@ -819,8 +829,38 @@ end
819829
-- Element Rendering
820830
--
821831

832+
-- returns nil or a chapter element from the native property chapter-list
833+
function get_chapter(possec)
834+
local cl = mp.get_property_native("chapter-list", {})
835+
local ch = nil
836+
837+
-- chapters might not be sorted by time. find nearest-before/at possec
838+
for n=1, #cl do
839+
if possec >= cl[n].time and (not ch or cl[n].time > ch.time) then
840+
ch = cl[n]
841+
end
842+
end
843+
return ch
844+
end
845+
822846
function render_elements(master_ass)
823847

848+
-- when the slider is dragged or hovered and we have a target chapter name
849+
-- then we use it instead of the normal title. we calculate it before the
850+
-- render iterations because the title may be rendered before the slider.
851+
state.forced_title = nil
852+
local se, ae = state.slider_element, elements[state.active_element]
853+
if user_opts.chapter_fmt ~= "no" and se and (ae == se or (not ae and mouse_hit(se))) then
854+
local dur = mp.get_property_number("duration", 0)
855+
if dur > 0 then
856+
local possec = get_slider_value(se) * dur / 100 -- of mouse pos
857+
local ch = get_chapter(possec)
858+
if ch and ch.title and ch.title ~= "" then
859+
state.forced_title = string.format(user_opts.chapter_fmt, ch.title)
860+
end
861+
end
862+
end
863+
824864
for n=1, #elements do
825865
local element = elements[n]
826866

@@ -1919,6 +1959,7 @@ function update_options(list)
19191959
validate_user_opts()
19201960
request_tick()
19211961
visibility_mode(user_opts.visibility, true)
1962+
update_duration_watch()
19221963
request_init()
19231964
end
19241965

@@ -1970,7 +2011,8 @@ function osc_init()
19702011
ne = new_element("title", "button")
19712012

19722013
ne.content = function ()
1973-
local title = mp.command_native({"expand-text", user_opts.title})
2014+
local title = state.forced_title or
2015+
mp.command_native({"expand-text", user_opts.title})
19742016
-- escape ASS, and strip newlines and trailing slashes
19752017
title = title:gsub("\\n", " "):gsub("\\$", ""):gsub("{","\\{")
19762018
return not (title == "") and title or "mpv"
@@ -1998,7 +2040,9 @@ function osc_init()
19982040
ne.eventresponder["mbtn_left_up"] =
19992041
function ()
20002042
mp.commandv("playlist-prev", "weak")
2001-
show_message(get_playlist(), 3)
2043+
if user_opts.playlist_osd then
2044+
show_message(get_playlist(), 3)
2045+
end
20022046
end
20032047
ne.eventresponder["shift+mbtn_left_up"] =
20042048
function () show_message(get_playlist(), 3) end
@@ -2013,7 +2057,9 @@ function osc_init()
20132057
ne.eventresponder["mbtn_left_up"] =
20142058
function ()
20152059
mp.commandv("playlist-next", "weak")
2016-
show_message(get_playlist(), 3)
2060+
if user_opts.playlist_osd then
2061+
show_message(get_playlist(), 3)
2062+
end
20172063
end
20182064
ne.eventresponder["shift+mbtn_left_up"] =
20192065
function () show_message(get_playlist(), 3) end
@@ -2068,7 +2114,9 @@ function osc_init()
20682114
ne.eventresponder["mbtn_left_up"] =
20692115
function ()
20702116
mp.commandv("add", "chapter", -1)
2071-
show_message(get_chapterlist(), 3)
2117+
if user_opts.chapters_osd then
2118+
show_message(get_chapterlist(), 3)
2119+
end
20722120
end
20732121
ne.eventresponder["shift+mbtn_left_up"] =
20742122
function () show_message(get_chapterlist(), 3) end
@@ -2083,7 +2131,9 @@ function osc_init()
20832131
ne.eventresponder["mbtn_left_up"] =
20842132
function ()
20852133
mp.commandv("add", "chapter", 1)
2086-
show_message(get_chapterlist(), 3)
2134+
if user_opts.chapters_osd then
2135+
show_message(get_chapterlist(), 3)
2136+
end
20872137
end
20882138
ne.eventresponder["shift+mbtn_left_up"] =
20892139
function () show_message(get_chapterlist(), 3) end
@@ -2147,6 +2197,7 @@ function osc_init()
21472197
ne = new_element("seekbar", "slider")
21482198

21492199
ne.enabled = not (mp.get_property("percent-pos") == nil)
2200+
state.slider_element = ne.enabled and ne or nil -- used for forced_title
21502201
ne.slider.markerF = function ()
21512202
local duration = mp.get_property_number("duration", nil)
21522203
if not (duration == nil) then
@@ -2275,10 +2326,10 @@ function osc_init()
22752326
dmx_cache = state.dmx_cache
22762327
end
22772328
local min = math.floor(dmx_cache / 60)
2278-
local sec = dmx_cache % 60
2329+
local sec = math.floor(dmx_cache % 60) -- don't round e.g. 59.9 to 60
22792330
return "Cache: " .. (min > 0 and
22802331
string.format("%sm%02.0fs", min, sec) or
2281-
string.format("%3.0fs", dmx_cache))
2332+
string.format("%3.0fs", sec))
22822333
end
22832334

22842335
-- volume
@@ -2492,7 +2543,14 @@ function render()
24922543
end
24932544

24942545
-- init management
2495-
if state.initREQ then
2546+
if state.active_element then
2547+
-- mouse is held down on some element - keep ticking and igore initReq
2548+
-- till it's released, or else the mouse-up (click) will misbehave or
2549+
-- get ignored. that's because osc_init() recreates the osc elements,
2550+
-- but mouse handling depends on the elements staying unmodified
2551+
-- between mouse-down and mouse-up (using the index active_element).
2552+
request_tick()
2553+
elseif state.initREQ then
24962554
osc_init()
24972555
state.initREQ = false
24982556

@@ -2529,14 +2587,10 @@ function render()
25292587
if (state.anitype == "out") then
25302588
osc_visible(false)
25312589
end
2532-
state.anistart = nil
2533-
state.animation = nil
2534-
state.anitype = nil
2590+
kill_animation()
25352591
end
25362592
else
2537-
state.anistart = nil
2538-
state.animation = nil
2539-
state.anitype = nil
2593+
kill_animation()
25402594
end
25412595

25422596
--mouse show/hide area
@@ -2719,8 +2773,10 @@ function process_event(source, what)
27192773
if element_has_action(elements[n], action) then
27202774
elements[n].eventresponder[action](elements[n])
27212775
end
2722-
request_tick()
27232776
end
2777+
2778+
-- ensure rendering after any (mouse) event - icons could change etc
2779+
request_tick()
27242780
end
27252781

27262782

@@ -2806,7 +2862,17 @@ function tick()
28062862
state.tick_last_time = mp.get_time()
28072863

28082864
if state.anitype ~= nil then
2809-
request_tick()
2865+
-- state.anistart can be nil - animation should now start, or it can
2866+
-- be a timestamp when it started. state.idle has no animation.
2867+
if not state.idle and
2868+
(not state.anistart or
2869+
mp.get_time() < 1 + state.anistart + user_opts.fadeduration/1000)
2870+
then
2871+
-- animating or starting, or still within 1s past the deadline
2872+
request_tick()
2873+
else
2874+
kill_animation()
2875+
end
28102876
end
28112877
end
28122878

@@ -2834,6 +2900,28 @@ function enable_osc(enable)
28342900
end
28352901
end
28362902

2903+
-- duration is observed for the sole purpose of updating chapter markers
2904+
-- positions. live streams with chapters are very rare, and the update is also
2905+
-- expensive (with request_init), so it's only observed when we have chapters
2906+
-- and the user didn't disable the livemarkers option (update_duration_watch).
2907+
function on_duration() request_init() end
2908+
2909+
local duration_watched = false
2910+
function update_duration_watch()
2911+
local want_watch = user_opts.livemarkers and
2912+
(mp.get_property_number("chapters", 0) or 0) > 0 and
2913+
true or false -- ensure it's a boolean
2914+
2915+
if (want_watch ~= duration_watched) then
2916+
if want_watch then
2917+
mp.observe_property("duration", nil, on_duration)
2918+
else
2919+
mp.unobserve_property(on_duration)
2920+
end
2921+
duration_watched = want_watch
2922+
end
2923+
end
2924+
28372925
-- mpv_thumbnail_script.lua --
28382926

28392927
local builtin_osc_enabled = mp.get_property_native('osc')
@@ -2850,11 +2938,16 @@ end
28502938

28512939

28522940
validate_user_opts()
2941+
update_duration_watch()
28532942

28542943
mp.register_event("shutdown", shutdown)
28552944
mp.register_event("start-file", request_init)
28562945
mp.observe_property("track-list", nil, request_init)
28572946
mp.observe_property("playlist", nil, request_init)
2947+
mp.observe_property("chapter-list", nil, function()
2948+
update_duration_watch()
2949+
request_init()
2950+
end)
28582951

28592952
mp.register_script_message("osc-message", show_message)
28602953
mp.register_script_message("osc-chapterlist", function(dur)
@@ -2990,6 +3083,7 @@ function visibility_mode(mode, no_osd)
29903083
end
29913084

29923085
user_opts.visibility = mode
3086+
utils.shared_script_property_set("osc-visibility", mode)
29933087

29943088
if not no_osd and tonumber(mp.get_property("osd-level")) >= 1 then
29953089
mp.osd_message("OSC visibility: " .. mode)

0 commit comments

Comments
 (0)