Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show chapter names on hover #3

Merged
merged 1 commit into from
Feb 12, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 64 additions & 1 deletion mordenx.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ local user_opts = {
visibility = 'auto', -- only used at init to set visibility_mode(...)
windowcontrols = 'auto', -- whether to show window controls
language = 'eng', -- eng=English, chs=Chinese
chapter_fmt = "Chapter: %s", -- chapter print format for seekbar-hover. "no" to disable
}

-- Localization
Expand Down Expand Up @@ -138,6 +139,7 @@ local state = {
osd = mp.create_osd_overlay('ass-events'),
lastvisibility = user_opts.visibility, -- save last visibility on pause if showonpause
fulltime = user_opts.timems,
chapter_list = {}, -- sorted by time
}

local window_control_box_width = 138
Expand Down Expand Up @@ -550,8 +552,36 @@ end
--
-- Element Rendering
--

-- returns nil or a chapter element from the native property chapter-list
function get_chapter(possec)
local cl = state.chapter_list -- sorted, get latest before possec, if any

for n=#cl,1,-1 do
if possec >= cl[n].time then
return cl[n]
end
end
end

function render_elements(master_ass)

-- when the slider is dragged or hovered and we have a target chapter name
-- then we use it instead of the normal title. we calculate it before the
-- render iterations because the title may be rendered before the slider.
state.forced_title = nil
local se, ae = state.slider_element, elements[state.active_element]
if user_opts.chapter_fmt ~= "no" and se and (ae == se or (not ae and mouse_hit(se))) then
local dur = mp.get_property_number("duration", 0)
if dur > 0 then
local possec = get_slider_value(se) * dur / 100 -- of mouse pos
local ch = get_chapter(possec)
if ch and ch.title and ch.title ~= "" then
state.forced_title = string.format(user_opts.chapter_fmt, ch.title)
end
end
end

for n=1, #elements do
local element = elements[n]
local style_ass = assdraw.ass_new()
Expand Down Expand Up @@ -1115,6 +1145,7 @@ function update_options(list)
validate_user_opts()
request_tick()
visibility_mode(user_opts.visibility, true)
update_duration_watch()
request_init()
end

Expand Down Expand Up @@ -1322,7 +1353,8 @@ function osc_init()
-- title
ne = new_element('title', 'button')
ne.content = function ()
local title = mp.command_native({'expand-text', user_opts.title})
local title = state.forced_title or
mp.command_native({"expand-text", user_opts.title})
if state.paused then
title = title:gsub('\\n', ' '):gsub('\\$', ''):gsub('{','\\{')
else
Expand All @@ -1336,6 +1368,7 @@ function osc_init()
ne = new_element('seekbar', 'slider')

ne.enabled = not (mp.get_property('percent-pos') == nil)
state.slider_element = ne.enabled and ne or nil -- used for forced_title
ne.slider.markerF = function ()
local duration = mp.get_property_number('duration', nil)
if not (duration == nil) then
Expand Down Expand Up @@ -1930,12 +1963,42 @@ function enable_osc(enable)
end
end

-- duration is observed for the sole purpose of updating chapter markers
-- positions. live streams with chapters are very rare, and the update is also
-- expensive (with request_init), so it's only observed when we have chapters
-- and the user didn't disable the livemarkers option (update_duration_watch).
function on_duration() request_init() end

local duration_watched = false
function update_duration_watch()
local want_watch = user_opts.livemarkers and
(mp.get_property_number("chapters", 0) or 0) > 0 and
true or false -- ensure it's a boolean

if (want_watch ~= duration_watched) then
if want_watch then
mp.observe_property("duration", nil, on_duration)
else
mp.unobserve_property(on_duration)
end
duration_watched = want_watch
end
end

validate_user_opts()
update_duration_watch()

mp.register_event('shutdown', shutdown)
mp.register_event('start-file', request_init)
mp.observe_property('track-list', nil, request_init)
mp.observe_property('playlist', nil, request_init)
mp.observe_property("chapter-list", "native", function(_, list)
list = list or {} -- safety, shouldn't return nil
table.sort(list, function(a, b) return a.time < b.time end)
state.chapter_list = list
update_duration_watch()
request_init()
end)

mp.register_script_message('osc-message', show_message)
mp.register_script_message('osc-chapterlist', function(dur)
Expand Down