From 77fd392f7e4b1cfede1bd4d9dfc135b3fc1335f1 Mon Sep 17 00:00:00 2001 From: Tony Cebzanov Date: Tue, 26 Nov 2019 18:21:47 -0500 Subject: [PATCH] Update patched_osc.lua to match upstream version b278360 --- src/patched_osc.lua | 563 ++++++++++++++++++++++---------------------- 1 file changed, 286 insertions(+), 277 deletions(-) diff --git a/src/patched_osc.lua b/src/patched_osc.lua index cdc345b..69c2aa2 100644 --- a/src/patched_osc.lua +++ b/src/patched_osc.lua @@ -2,7 +2,7 @@ This is mpv's original player/lua/osc.lua patched to display thumbnails Sections are denoted with -- mpv_thumbnail_script.lua -- -Current osc.lua version: 97816bbef0f97cfda7abdbe560707481d5f68ccd +Current osc.lua version: b27836011e26f04ec51645e41ac31b84d3d593da ]]-- local assdraw = require 'mp.assdraw' @@ -10,11 +10,9 @@ local msg = require 'mp.msg' local opt = require 'mp.options' local utils = require 'mp.utils' - -- -- Parameters -- - -- default user option values -- do not touch, change them in osc.conf local user_opts = { @@ -40,16 +38,20 @@ local user_opts = { -- internal track list management (and some -- functions that depend on it) layout = "bottombar", - seekbarstyle = "bar", -- slider (diamond marker), knob (circle - -- marker with guide), or bar (fill) + seekbarstyle = "bar", -- bar, diamond or knob + seekbarhandlesize = 0.6, -- size ratio of the diamond and knob handle + seekrangestyle = "inverted",-- bar, line, slider, inverted or none + seekrangeseparate = true, -- wether the seekranges overlay on the bar-style seekbar + seekrangealpha = 200, -- transparency of seekranges + seekbarkeyframes = true, -- use keyframes when dragging the seekbar title = "${media-title}", -- string compatible with property-expansion -- to be shown as OSC title tooltipborder = 1, -- border of tooltip in bottom/topbar timetotal = false, -- display total time instead of remaining time? timems = false, -- display timecodes with milliseconds? - seekranges = true, -- display seek ranges? visibility = "auto", -- only used at init to set visibility_mode(...) boxmaxchars = 80, -- title crop threshold for box layout + boxvideo = false, -- apply osc_param.video_margins to video } -- read_options may modify hidetimeout, so save the original default value in @@ -295,6 +297,9 @@ local osc_param = { -- calculated by osc_init() display_aspect = 1, unscaled_y = 0, areas = {}, + video_margins = { + l = 0, r = 0, t = 0, b = 0, -- left/right/top/bottom + }, } local osc_styles = { @@ -340,6 +345,8 @@ local state = { enabled = true, input_enabled = true, showhide_enabled = false, + dmx_cache = 0, + using_video_margins = false, } @@ -349,6 +356,13 @@ local state = { -- Helperfunctions -- +local margins_opts = { + {"l", "video-margin-ratio-left"}, + {"r", "video-margin-ratio-right"}, + {"t", "video-margin-ratio-top"}, + {"b", "video-margin-ratio-bottom"}, +} + -- scale factor for translating between real and virtual ASS coordinates function get_virt_scale_factor() local w, h = mp.get_osd_size() @@ -484,6 +498,37 @@ function add_area(name, x1, y1, x2, y2) table.insert(osc_param.areas[name], {x1=x1, y1=y1, x2=x2, y2=y2}) end +function ass_append_alpha(ass, alpha, modifier) + local ar = {} + + for ai, av in pairs(alpha) do + av = mult_alpha(av, modifier) + if state.animation then + av = mult_alpha(av, state.animation) + end + ar[ai] = av + end + + ass:append(string.format("{\\1a&H%X&\\2a&H%X&\\3a&H%X&\\4a&H%X&}", + ar[1], ar[2], ar[3], ar[4])) +end + +function ass_draw_rr_h_cw(ass, x0, y0, x1, y1, r1, hexagon, r2) + if hexagon then + ass:hexagon_cw(x0, y0, x1, y1, r1, r2) + else + ass:round_rect_cw(x0, y0, x1, y1, r1, r2) + end +end + +function ass_draw_rr_h_ccw(ass, x0, y0, x1, y1, r1, hexagon, r2) + if hexagon then + ass:hexagon_ccw(x0, y0, x1, y1, r1, r2) + else + ass:round_rect_ccw(x0, y0, x1, y1, r1, r2) + end +end + -- -- Tracklist Management @@ -628,25 +673,30 @@ function prepare_elements() if (element.type == "box") then --draw box static_ass:draw_start() - static_ass:round_rect_cw(0, 0, elem_geo.w, elem_geo.h, - element.layout.box.radius) + ass_draw_rr_h_cw(static_ass, 0, 0, elem_geo.w, elem_geo.h, + element.layout.box.radius, element.layout.box.hexagon) static_ass:draw_stop() - elseif (element.type == "slider") then --draw static slider parts + local r1 = 0 + local r2 = 0 local slider_lo = element.layout.slider -- offset between element outline and drag-area local foV = slider_lo.border + slider_lo.gap -- calculate positions of min and max points - if (slider_lo.stype == "slider") or - (slider_lo.stype == "knob") then + if (slider_lo.stype ~= "bar") then + r1 = elem_geo.h / 2 element.slider.min.ele_pos = elem_geo.h / 2 element.slider.max.ele_pos = elem_geo.w - (elem_geo.h / 2) - - elseif (slider_lo.stype == "bar") then + if (slider_lo.stype == "diamond") then + r2 = (elem_geo.h - 2 * slider_lo.border) / 2 + elseif (slider_lo.stype == "knob") then + r2 = r1 + end + else element.slider.min.ele_pos = slider_lo.border + slider_lo.gap element.slider.max.ele_pos = @@ -663,11 +713,12 @@ function prepare_elements() static_ass:draw_start() -- the box - static_ass:rect_cw(0, 0, elem_geo.w, elem_geo.h); + ass_draw_rr_h_cw(static_ass, 0, 0, elem_geo.w, elem_geo.h, r1, slider_lo.stype == "diamond") -- the "hole" - static_ass:rect_ccw(slider_lo.border, slider_lo.border, - elem_geo.w - slider_lo.border, elem_geo.h - slider_lo.border) + ass_draw_rr_h_ccw(static_ass, slider_lo.border, slider_lo.border, + elem_geo.w - slider_lo.border, elem_geo.h - slider_lo.border, + r2, slider_lo.stype == "diamond") -- marker nibbles if not (element.slider.markerF == nil) and (slider_lo.gap > 0) then @@ -743,18 +794,7 @@ function render_elements(master_ass) local style_ass = assdraw.ass_new() style_ass:merge(element.style_ass) - - --alpha - local ar = element.layout.alpha - if not (state.animation == nil) then - ar = {} - for ai, av in pairs(element.layout.alpha) do - ar[ai] = mult_alpha(av, state.animation) - end - end - - style_ass:append(string.format("{\\1a&H%X&\\2a&H%X&\\3a&H%X&\\4a&H%X&}", - ar[1], ar[2], ar[3], ar[4])) + ass_append_alpha(style_ass, element.layout.alpha, 0) if element.eventresponder and (state.active_element == n) then @@ -795,48 +835,110 @@ function render_elements(master_ass) local s_max = element.slider.max.value -- draw pos marker + local foH, xp local pos = element.slider.posF() + local foV = slider_lo.border + slider_lo.gap + local innerH = elem_geo.h - (2 * foV) + local seekRanges = element.slider.seekRangesF() + local seekRangeLineHeight = innerH / 5 - if not (pos == nil) then + if slider_lo.stype ~= "bar" then + foH = elem_geo.h / 2 + else + foH = slider_lo.border + slider_lo.gap + end - local foV = slider_lo.border + slider_lo.gap - local foH = 0 - if (slider_lo.stype == "slider") or - (slider_lo.stype == "knob") then - foH = elem_geo.h / 2 - elseif (slider_lo.stype == "bar") then - foH = slider_lo.border + slider_lo.gap + if pos then + xp = get_slider_ele_pos_for(element, pos) + + if slider_lo.stype ~= "bar" then + local r = (user_opts.seekbarhandlesize * innerH) / 2 + ass_draw_rr_h_cw(elem_ass, xp - r, foH - r, + xp + r, foH + r, + r, slider_lo.stype == "diamond") + else + local h = 0 + if seekRanges and user_opts.seekrangeseparate and slider_lo.rtype ~= "inverted" then + h = seekRangeLineHeight + end + elem_ass:rect_cw(foH, foV, xp, elem_geo.h - foV - h) + + if seekRanges and not user_opts.seekrangeseparate and slider_lo.rtype ~= "inverted" then + -- Punch holes for the seekRanges to be drawn later + for _,range in pairs(seekRanges) do + if range["start"] < pos then + local pstart = get_slider_ele_pos_for(element, range["start"]) + local pend = xp + + if pos > range["end"] then + pend = get_slider_ele_pos_for(element, range["end"]) + end + elem_ass:rect_ccw(pstart, elem_geo.h - foV - seekRangeLineHeight, pend, elem_geo.h - foV) + end + end + end end - local xp = get_slider_ele_pos_for(element, pos) - - -- the filling - local innerH = elem_geo.h - (2*foV) - - if (slider_lo.stype == "bar") then - elem_ass:rect_cw(foH, foV, xp, elem_geo.h - foV) - elseif (slider_lo.stype == "slider") then - elem_ass:move_to(xp, foV) - elem_ass:line_to(xp+(innerH/2), (innerH/2)+foV) - elem_ass:line_to(xp, (innerH)+foV) - elem_ass:line_to(xp-(innerH/2), (innerH/2)+foV) - elseif (slider_lo.stype == "knob") then - elem_ass:rect_cw(xp, (9*innerH/20) + foV, - elem_geo.w - foH, (11*innerH/20) + foV) - elem_ass:rect_cw(foH, (3*innerH/8) + foV, - xp, (5*innerH/8) + foV) - elem_ass:round_rect_cw(xp - innerH/2, foV, - xp + innerH/2, foV + innerH, innerH/2.0) + if slider_lo.rtype == "slider" then + ass_draw_rr_h_cw(elem_ass, foH - innerH / 6, foH - innerH / 6, + xp, foH + innerH / 6, + innerH / 6, slider_lo.stype == "diamond", 0) + ass_draw_rr_h_cw(elem_ass, xp, foH - innerH / 15, + elem_geo.w - foH + innerH / 15, foH + innerH / 15, + 0, slider_lo.stype == "diamond", innerH / 15) + for _,range in pairs(seekRanges or {}) do + local pstart = get_slider_ele_pos_for(element, range["start"]) + local pend = get_slider_ele_pos_for(element, range["end"]) + ass_draw_rr_h_ccw(elem_ass, pstart, foH - innerH / 21, + pend, foH + innerH / 21, + innerH / 21, slider_lo.stype == "diamond") + end end end - -- seek ranges - local seekRanges = element.slider.seekRangesF() - if not (seekRanges == nil) then + if seekRanges then + if slider_lo.rtype ~= "inverted" then + elem_ass:draw_stop() + elem_ass:merge(element.style_ass) + ass_append_alpha(elem_ass, element.layout.alpha, user_opts.seekrangealpha) + elem_ass:merge(element.static_ass) + end + for _,range in pairs(seekRanges) do local pstart = get_slider_ele_pos_for(element, range["start"]) local pend = get_slider_ele_pos_for(element, range["end"]) - elem_ass:rect_ccw(pstart, (elem_geo.h/2)-1, pend, (elem_geo.h/2) + 1) + + if slider_lo.rtype == "slider" then + ass_draw_rr_h_cw(elem_ass, pstart, foH - innerH / 21, + pend, foH + innerH / 21, + innerH / 21, slider_lo.stype == "diamond") + elseif slider_lo.rtype == "line" then + if slider_lo.stype == "bar" then + elem_ass:rect_cw(pstart, elem_geo.h - foV - seekRangeLineHeight, pend, elem_geo.h - foV) + else + ass_draw_rr_h_cw(elem_ass, pstart - innerH / 8, foH - innerH / 8, + pend + innerH / 8, foH + innerH / 8, + innerH / 8, slider_lo.stype == "diamond") + end + elseif slider_lo.rtype == "bar" then + if slider_lo.stype ~= "bar" then + ass_draw_rr_h_cw(elem_ass, pstart - innerH / 2, foV, + pend + innerH / 2, foV + innerH, + innerH / 2, slider_lo.stype == "diamond") + elseif range["end"] >= (pos or 0) then + elem_ass:rect_cw(pstart, foV, pend, elem_geo.h - foV) + else + elem_ass:rect_cw(pstart, elem_geo.h - foV - seekRangeLineHeight, pend, elem_geo.h - foV) + end + elseif slider_lo.rtype == "inverted" then + if slider_lo.stype ~= "bar" then + ass_draw_rr_h_ccw(elem_ass, pstart, (elem_geo.h / 2) - 1, pend, + (elem_geo.h / 2) + 1, + 1, slider_lo.stype == "diamond") + else + elem_ass:rect_ccw(pstart, (elem_geo.h / 2) - 1, pend, (elem_geo.h / 2) + 1) + end + end end end @@ -881,18 +983,7 @@ function render_elements(master_ass) elem_ass:pos(tx, ty) elem_ass:an(an) elem_ass:append(slider_lo.tooltip_style) - - --alpha - local ar = slider_lo.alpha - if not (state.animation == nil) then - ar = {} - for ai, av in pairs(slider_lo.alpha) do - ar[ai] = mult_alpha(av, state.animation) - end - end - elem_ass:append(string.format("{\\1a&H%X&\\2a&H%X&\\3a&H%X&\\4a&H%X&}", - ar[1], ar[2], ar[3], ar[4])) - + ass_append_alpha(elem_ass, slider_lo.alpha, 0) elem_ass:append(tooltiplabel) -- mpv_thumbnail_script.lua -- @@ -1099,7 +1190,7 @@ function add_layout(name) alpha = {[1] = 0, [2] = 255, [3] = 88, [4] = 255}, } elseif (elements[name].type == "box") then - elements[name].layout.box = {radius = 0} + elements[name].layout.box = {radius = 0, hexagon = false} end return elements[name].layout @@ -1265,9 +1356,7 @@ layouts["box"] = function () lo.style = osc_styles.timecodes lo.slider.tooltip_style = osc_styles.vidtitle lo.slider.stype = user_opts["seekbarstyle"] - if lo.slider.stype == "knob" then - lo.slider.border = 0 - end + lo.slider.rtype = user_opts["seekrangestyle"] -- -- Timecodes + Cache @@ -1356,6 +1445,7 @@ layouts["slimbox"] = function () lo.alpha[3] = 0 if not (user_opts["seekbarstyle"] == "bar") then lo.box.radius = osc_geo.r + lo.box.hexagon = user_opts["seekbarstyle"] == "diamond" end @@ -1367,6 +1457,7 @@ layouts["slimbox"] = function () lo.slider.gap = 1.5 lo.slider.tooltip_style = styles.tooltip lo.slider.stype = user_opts["seekbarstyle"] + lo.slider.rtype = user_opts["seekrangestyle"] lo.slider.adjust_tooltip = false -- @@ -1399,12 +1490,12 @@ layouts["slimbox"] = function () end -layouts["bottombar"] = function() +function bar_layout(direction) local osc_geo = { x = -2, - y = osc_param.playresy - 54 - user_opts.barmargin, - an = 7, - w = osc_param.playresx + 4, + y, + an = (direction < 0) and 7 or 1, + w, h = 56, } @@ -1418,12 +1509,16 @@ layouts["bottombar"] = function() if ((osc_param.display_aspect > 0) and (osc_param.playresx < minW)) then osc_param.playresy = minW / osc_param.display_aspect osc_param.playresx = osc_param.playresy * osc_param.display_aspect - osc_geo.y = osc_param.playresy - 54 - user_opts.barmargin - osc_geo.w = osc_param.playresx + 4 end - local line1 = osc_geo.y + 9 + padY - local line2 = osc_geo.y + 36 + padY + osc_geo.y = direction * (54 + user_opts.barmargin) + osc_geo.w = osc_param.playresx + 4 + if direction < 0 then + osc_geo.y = osc_geo.y + osc_param.playresy + end + + local line1 = osc_geo.y - direction * (9 + padY) + local line2 = osc_geo.y - direction * (36 + padY) osc_param.areas = {} @@ -1431,9 +1526,18 @@ layouts["bottombar"] = function() osc_geo.w, osc_geo.h)) local sh_area_y0, sh_area_y1 - sh_area_y0 = get_align(-1 + (2*user_opts.deadzonesize), - osc_geo.y - (osc_geo.h / 2), 0, 0) - sh_area_y1 = osc_param.playresy - user_opts.barmargin + if direction > 0 then + -- deadzone below OSC + sh_area_y0 = user_opts.barmargin + sh_area_y1 = (osc_geo.y + (osc_geo.h / 2)) + + get_align(1 - (2*user_opts.deadzonesize), + osc_param.playresy - (osc_geo.y + (osc_geo.h / 2)), 0, 0) + else + -- deadzone above OSC + sh_area_y0 = get_align(-1 + (2*user_opts.deadzonesize), + osc_geo.y - (osc_geo.h / 2), 0, 0) + sh_area_y1 = osc_param.playresy - user_opts.barmargin + end add_area("showhide", 0, sh_area_y0, osc_param.playresx, sh_area_y1) local lo, geo @@ -1553,196 +1657,65 @@ layouts["bottombar"] = function() lo.style = osc_styles.timecodesBar lo.alpha[1] = math.min(255, user_opts.boxalpha + (255 - user_opts.boxalpha)*0.8) - - lo = add_layout("seekbar") - lo.geometry = geo - lo.style = osc_styles.timecodes - lo.slider.border = 0 - lo.slider.gap = 2 - lo.slider.tooltip_style = osc_styles.timePosBar - lo.slider.tooltip_an = 5 - lo.slider.stype = user_opts["seekbarstyle"] -end - -layouts["topbar"] = function() - local osc_geo = { - x = -2, - y = 54 + user_opts.barmargin, - an = 1, - w = osc_param.playresx + 4, - h = 56, - } - - local padX = 9 - local padY = 3 - local buttonW = 27 - local tcW = (state.tc_ms) and 170 or 110 - local tsW = 90 - local minW = (buttonW + padX)*5 + (tcW + padX)*4 + (tsW + padX)*2 - - if ((osc_param.display_aspect > 0) and (osc_param.playresx < minW)) then - osc_param.playresy = minW / osc_param.display_aspect - osc_param.playresx = osc_param.playresy * osc_param.display_aspect - osc_geo.y = 54 + user_opts.barmargin - osc_geo.w = osc_param.playresx + 4 + if not (user_opts["seekbarstyle"] == "bar") then + lo.box.radius = geo.h / 2 + lo.box.hexagon = user_opts["seekbarstyle"] == "diamond" end - local line1 = osc_geo.y - 36 - padY - local line2 = osc_geo.y - 9 - padY - - osc_param.areas = {} - - add_area("input", get_hitbox_coords(osc_geo.x, osc_geo.y, osc_geo.an, - osc_geo.w, osc_geo.h)) - - local sh_area_y0, sh_area_y1 - sh_area_y0 = user_opts.barmargin - sh_area_y1 = (osc_geo.y + (osc_geo.h / 2)) + - get_align(1 - (2*user_opts.deadzonesize), - osc_param.playresy - (osc_geo.y + (osc_geo.h / 2)), 0, 0) - add_area("showhide", 0, sh_area_y0, osc_param.playresx, sh_area_y1) - - local lo, geo - - -- Background bar - new_element("bgbox", "box") - lo = add_layout("bgbox") - - lo.geometry = osc_geo - lo.layer = 10 - lo.style = osc_styles.box - lo.alpha[1] = user_opts.boxalpha - - - -- Playback control buttons - geo = { x = osc_geo.x + padX, y = line1, an = 4, - w = buttonW, h = 36 - padY*2 } - lo = add_layout("playpause") - lo.geometry = geo - lo.style = osc_styles.smallButtonsBar - - geo = { x = geo.x + geo.w + padX, y = geo.y, an = geo.an, w = geo.w, h = geo.h } - lo = add_layout("ch_prev") - lo.geometry = geo - lo.style = osc_styles.smallButtonsBar - - geo = { x = geo.x + geo.w + padX, y = geo.y, an = geo.an, w = geo.w, h = geo.h } - lo = add_layout("ch_next") - lo.geometry = geo - lo.style = osc_styles.smallButtonsBar - - - -- Left timecode - geo = { x = geo.x + geo.w + padX + tcW, y = geo.y, an = 6, - w = tcW, h = geo.h } - lo = add_layout("tc_left") - lo.geometry = geo - lo.style = osc_styles.timecodesBar - - local sb_l = geo.x + padX - - -- Fullscreen button - geo = { x = osc_geo.x + osc_geo.w - buttonW - padX, y = geo.y, an = 4, - w = buttonW, h = geo.h } - lo = add_layout("tog_fs") - lo.geometry = geo - lo.style = osc_styles.smallButtonsBar - - -- Volume - geo = { x = geo.x - geo.w - padX, y = geo.y, an = geo.an, w = geo.w, h = geo.h } - lo = add_layout("volume") - lo.geometry = geo - lo.style = osc_styles.smallButtonsBar - - -- Track selection buttons - geo = { x = geo.x - tsW - padX, y = geo.y, an = geo.an, w = tsW, h = geo.h } - lo = add_layout("cy_sub") - lo.geometry = geo - lo.style = osc_styles.smallButtonsBar - - geo = { x = geo.x - geo.w - padX, y = geo.y, an = geo.an, w = geo.w, h = geo.h } - lo = add_layout("cy_audio") - lo.geometry = geo - lo.style = osc_styles.smallButtonsBar - - - -- Right timecode - geo = { x = geo.x - geo.w - padX - tcW - 10, y = geo.y, an = 4, - w = tcW, h = geo.h } - lo = add_layout("tc_right") - lo.geometry = geo - lo.style = osc_styles.timecodesBar - - local sb_r = geo.x - padX - - - -- Seekbar - geo = { x = sb_l, y = user_opts.barmargin, an = 7, - w = math.max(0, sb_r - sb_l), h = geo.h } - new_element("bgbar1", "box") - lo = add_layout("bgbar1") - - lo.geometry = geo - lo.layer = 15 - lo.style = osc_styles.timecodesBar - lo.alpha[1] = - math.min(255, user_opts.boxalpha + (255 - user_opts.boxalpha)*0.8) - lo = add_layout("seekbar") lo.geometry = geo lo.style = osc_styles.timecodesBar lo.slider.border = 0 lo.slider.gap = 2 lo.slider.tooltip_style = osc_styles.timePosBar - lo.slider.stype = user_opts["seekbarstyle"] lo.slider.tooltip_an = 5 + lo.slider.stype = user_opts["seekbarstyle"] + lo.slider.rtype = user_opts["seekrangestyle"] + if direction < 0 then + osc_param.video_margins.b = osc_geo.h / osc_param.playresy + else + osc_param.video_margins.t = osc_geo.h / osc_param.playresy + end +end - -- Playlist prev/next - geo = { x = osc_geo.x + padX, y = line2, an = 4, w = 18, h = 18 - padY } - lo = add_layout("pl_prev") - lo.geometry = geo - lo.style = osc_styles.topButtonsBar - - geo = { x = geo.x + geo.w + padX, y = geo.y, an = geo.an, w = geo.w, h = geo.h } - lo = add_layout("pl_next") - lo.geometry = geo - lo.style = osc_styles.topButtonsBar - - local t_l = geo.x + geo.w + padX - - -- Cache - geo = { x = osc_geo.x + osc_geo.w - padX, y = geo.y, - an = 6, w = 150, h = geo.h } - lo = add_layout("cache") - lo.geometry = geo - lo.style = osc_styles.vidtitleBar - - local t_r = geo.x - geo.w - padX*2 +layouts["bottombar"] = function() + bar_layout(-1) +end - -- Title - geo = { x = t_l, y = geo.y, an = 4, - w = t_r - t_l, h = geo.h } - lo = add_layout("title") - lo.geometry = geo - lo.style = string.format("%s{\\clip(%f,%f,%f,%f)}", - osc_styles.vidtitleBar, - geo.x, geo.y-geo.h, geo.w, geo.y+geo.h) +layouts["topbar"] = function() + bar_layout(1) end -- Validate string type user options function validate_user_opts() if layouts[user_opts.layout] == nil then msg.warn("Invalid setting \""..user_opts.layout.."\" for layout") - user_opts.layout = "box" + user_opts.layout = "bottombar" end - if user_opts.seekbarstyle ~= "slider" and - user_opts.seekbarstyle ~= "bar" and + if user_opts.seekbarstyle ~= "bar" and + user_opts.seekbarstyle ~= "diamond" and user_opts.seekbarstyle ~= "knob" then msg.warn("Invalid setting \"" .. user_opts.seekbarstyle .. "\" for seekbarstyle") - user_opts.seekbarstyle = "slider" + user_opts.seekbarstyle = "bar" + end + + if user_opts.seekrangestyle ~= "bar" and + user_opts.seekrangestyle ~= "line" and + user_opts.seekrangestyle ~= "slider" and + user_opts.seekrangestyle ~= "inverted" and + user_opts.seekrangestyle ~= "none" then + msg.warn("Invalid setting \"" .. user_opts.seekrangestyle + .. "\" for seekrangestyle") + user_opts.seekrangestyle = "inverted" + end + + if user_opts.seekrangestyle == "slider" and + user_opts.seekbarstyle == "bar" then + msg.warn("Using \"slider\" seekrangestyle together with \"bar\" seekbarstyle is not supported") + user_opts.seekrangestyle = "inverted" end end @@ -1775,6 +1748,8 @@ function osc_init() end osc_param.playresx = osc_param.playresy * osc_param.display_aspect + -- stop seeking with the slider to prevent skipping files + state.active_element = nil @@ -1997,7 +1972,7 @@ function osc_init() end end ne.slider.seekRangesF = function() - if not (user_opts.seekranges) then + if user_opts.seekrangestyle == "none" then return nil end local cache_state = mp.get_property_native("demuxer-cache-state", nil) @@ -2013,6 +1988,9 @@ function osc_init() range["start"] = 100 * range["start"] / duration range["end"] = 100 * range["end"] / duration end + if #ranges == 0 then + return nil + end return ranges end ne.eventresponder["mouse_move"] = --keyframe seeking when mouse is dragged @@ -2023,8 +2001,8 @@ function osc_init() local seekto = get_slider_value(element) if (element.state.lastseek == nil) or (not (element.state.lastseek == seekto)) then - mp.commandv("seek", seekto, - "absolute-percent", "keyframes") + mp.commandv("seek", seekto, "absolute-percent", + user_opts.seekbarkeyframes and "keyframes" or "exact") element.state.lastseek = seekto end @@ -2077,28 +2055,24 @@ function osc_init() ne = new_element("cache", "button") ne.content = function () - local dmx_cache = mp.get_property_number("demuxer-cache-duration") - local cache_used = mp.get_property_number("cache-used") - local dmx_cache_state = mp.get_property_native("demuxer-cache-state", {}) - local is_network = mp.get_property_native("demuxer-via-network") - local show_cache = cache_used and not dmx_cache_state["eof"] - if dmx_cache then - dmx_cache = string.format("%3.0fs", dmx_cache) - end - if dmx_cache_state["fw-bytes"] then - cache_used = (cache_used or 0)*1024 + dmx_cache_state["fw-bytes"] + local cache_state = mp.get_property_native("demuxer-cache-state", {}) + if not (cache_state["seekable-ranges"] and + #cache_state["seekable-ranges"] > 0) then + -- probably not a network stream + return "" end - if (is_network and dmx_cache) or show_cache then - -- Only show dmx-cache-duration by itself if it's a network file. - -- Cache can be forced even for local files, so always show that. - return string.format("Cache: %s%s%s", - (dmx_cache and dmx_cache or ""), - ((dmx_cache and show_cache) and " | " or ""), - (show_cache and - utils.format_bytes_humanized(cache_used) or "")) + local dmx_cache = mp.get_property_number("demuxer-cache-duration") + if dmx_cache and (dmx_cache > state.dmx_cache * 1.1 or + dmx_cache < state.dmx_cache * 0.9) then + state.dmx_cache = dmx_cache else - return "" + dmx_cache = state.dmx_cache end + local min = math.floor(dmx_cache / 60) + local sec = dmx_cache % 60 + return "Cache: " .. (min > 0 and + string.format("%sm%02.0fs", min, sec) or + string.format("%3.0fs", dmx_cache)) end -- volume @@ -2130,9 +2104,40 @@ function osc_init() --do something with the elements prepare_elements() -end + if user_opts.boxvideo then + -- check whether any margin option has a non-default value + local margins_used = false + for _, opt in ipairs(margins_opts) do + if mp.get_property_number(opt[2], 0.0) ~= 0.0 then + margins_used = true + end + end + if not margins_used then + local margins = osc_param.video_margins + for _, opt in ipairs(margins_opts) do + local v = margins[opt[1]] + if v ~= 0 then + mp.set_property_number(opt[2], v) + state.using_video_margins = true + end + end + end + else + reset_margins() + end + +end + +function reset_margins() + if state.using_video_margins then + for _, opt in ipairs(margins_opts) do + mp.set_property_number(opt[2], 0.0) + end + state.using_video_margins = false + end +end -- -- Other important stuff @@ -2544,6 +2549,7 @@ end validate_user_opts() +mp.register_event("shutdown", reset_margins) mp.register_event("start-file", request_init) mp.register_event("tracks-changed", request_init) mp.observe_property("playlist", nil, request_init) @@ -2600,6 +2606,9 @@ mp.set_key_bindings({ function(e) process_event("shift+mbtn_left", "down") end}, {"mbtn_right", function(e) process_event("mbtn_right", "up") end, function(e) process_event("mbtn_right", "down") end}, + -- alias to shift_mbtn_left for single-handed mouse use + {"mbtn_mid", function(e) process_event("shift+mbtn_left", "up") end, + function(e) process_event("shift+mbtn_left", "down") end}, {"wheel_up", function(e) process_event("wheel_up", "press") end}, {"wheel_down", function(e) process_event("wheel_down", "press") end}, {"mbtn_left_dbl", "ignore"}, @@ -2656,4 +2665,4 @@ visibility_mode(user_opts.visibility, true) mp.register_script_message("osc-visibility", visibility_mode) mp.add_key_binding(nil, "visibility", function() visibility_mode("cycle") end) -set_virt_mouse_area(0, 0, 0, 0, "input") \ No newline at end of file +set_virt_mouse_area(0, 0, 0, 0, "input")