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

[WIP] mpv osc.lua theme #13

Open
Zren opened this issue Mar 17, 2022 · 4 comments
Open

[WIP] mpv osc.lua theme #13

Zren opened this issue Mar 17, 2022 · 4 comments

Comments

@Zren
Copy link
Owner

Zren commented Mar 17, 2022

Ever since my GPU died, I've been using mpv since my super-old GPU has terrible OpenGL support (so I'm stuck with vo=x11). Past few days I've been trying to turn the bomi/mpvz look into an osc.lua theme which can be used with mpv itself. It'll be far more complicated to code, but it'll work for anyone who just want's it to look nice without losing mpv's feature set.

Screenshot_20220316_210402

Here's the base osc.lua we can copy to ~/.config/mpv/scripts/osc.lua.

Then I added this to ~/.config/mpv/mpv.conf

keep-open=yes
sub-scale-with-window=no
osd-scale-by-window=no
keepaspect-window=no
osc=no
border=no

Layout

I created a new layout section based on bottombar.

local user_opts = {
    ...
    -- layout = "bottombar",
    layout = "tethys",
}

layouts["tethys"] = function()
    local direction = -1
    local seekbarHeight = 20
    local controlsHeight = 64
    ...
end

I basically ended doing the buttons like so:

    ---- Left Section (Added Left-to-Right)
    -- Playback control buttons
    geo = {
        x = leftX + leftSectionWidth + buttonW/2,
        y = line1Y + buttonH/2,
        an = 5, -- x,y is center
        w = buttonW,
        h = buttonH,
    }
    lo = add_layout("playpause")
    lo.geometry = geo
    lo.style = buttonStyle
    setButtonTooltip(lo, "Play (p / Space)")
    leftSectionWidth = leftSectionWidth + geo.w

Icons

Eventually I noticed the mpv icon (and santa hat during December) when mpv is launched with no video is drawn using a path!

local logo_lines = {
    -- White border
    "{\\c&HE5E5E5&\\p6}m 895 10 b 401 10 0 410 0 905 0 1399 401 1800 895 1800 1390 1800 1790 1399 1790 905 1790 410 1390 10 895 10 {\\p0}",
    -- Purple fill
    "{\\c&H682167&\\p6}m 925 42 b 463 42 87 418 87 880 87 1343 463 1718 925 1718 1388 1718 1763 1343 1763 880 1763 418 1388 42 925 42{\\p0}",
    ...
}
...
        local ass = assdraw.ass_new()
        -- mpv logo
        for i, line in ipairs(logo_lines) do
            ass:new_event()
            ass:append(line_prefix .. line)
        end

I tried taking the path in the SVG and placing it there. Unfortunately, the SVG path is a little different. I noticed that mpv used the b command which doesn't appear in the mozilla docs.

However even if we assume the b is the same as a bezier curve, the SVG path uses delta c coordinates instead of absolute C coordinates which is what the b seems to be using.

<path d="m 31.000001,21 c 2.964454,2.052317 2.964454,2.947684 0,5.000001 C 20.963866,32.948092 12,39 9.9999997,39 8,39 8,36 8,23.499999 8,12 8,9 9.9999997,9 12,9 20.963866,14.051906 31.000001,21 Z">
<path d="m 31 21 c 3 2 3 3 0 5 C 21 33 12 39 10 39 8 39 8 36 8 23 8 12 8 9 10 9 12 9 21 14 31 21">

I ended up needing to export the svg as an .html file with Inkscape, then manually convert

ctx.moveTo(31.000001, 21.000000);
ctx.bezierCurveTo(33.964455, 23.052317, 33.964455, 23.947684, 31.000001, 26.000001);
ctx.bezierCurveTo(20.963866, 32.948092, 12.000000, 39.000000, 10.000000, 39.000000);
ctx.bezierCurveTo(8.000000, 39.000000, 8.000000, 36.000000, 8.000000, 23.499999);
ctx.bezierCurveTo(8.000000, 12.000000, 8.000000, 9.000000, 10.000000, 9.000000);
ctx.bezierCurveTo(12.000000, 9.000000, 20.963866, 14.051906, 31.000001, 21.000000);

to the following path:

local tethys_icon_play = {
    "{\\c&HC0C0C0&\\p1}m 31 21   b 34 23 34 24 31 26   b 21 33 12 39 10 39   b 8 39 8 36 8 23.5   b 8 12 8 9 10 9   b 12 9 21 14 31 21{\\p0}",
}

As a final note, it seems the {\\p1} stands for scale. The mpv/santa hat icons use {\\p6} which I assume stands for 1/6th scale since the coordinates given are huge (401 10 0 410 0 905). I needed to change it to 1/1 scale to even see my 44x44 icon.

I still need to adjust the icon position a little, so it's not a drop in replacement.

Screenshot_20220316_205902

Hover Effect

mpv doesn't have any hover animations, the only hover effect is for the seekbar timestamp.

I Managed to create a hover effect by adding the following to the bottom of render_elements() under the button section.

            local buttonHovered = mouse_hit(element)
            if buttonHovered then
                buttontext = "{\\c&HFFFFFF}" .. buttontext

                local shadow_ass = assdraw.ass_new()
                shadow_ass:merge(style_ass)
                shadow_ass:append("{\\blur5}" .. buttontext .. "{\\blur0}")
                master_ass:merge(shadow_ass)
            end

            elem_ass:append(buttontext)

Tooltips

I added rough tooltips by adding this to render_elements() under the button section.

            elem_ass:append(buttontext)

            -- Tooltip
            local button_lo = element.layout.button
            if buttonHovered and (not (button_lo.tooltip == nil)) then
                -- tooltip label
                local tx = button_lo.tooltip_geo.x -- element.hitbox.x1
                local ty = button_lo.tooltip_geo.y -- element.hitbox.y1
                local tooltipAlpha =  {[1] = 0, [2] = 255, [3] = 88, [4] = 255}
                elem_ass:new_event()
                elem_ass:pos(tx, ty)
                elem_ass:an(button_lo.tooltip_an)
                elem_ass:append(button_lo.tooltip_style)
                ass_append_alpha(elem_ass, tooltipAlpha, 0)
                elem_ass:append(button_lo.tooltip)
            end

and the following setter to adjust the tooltip based on how close to the window edge it is.

    local buttonTooltipStyle = ("{\\blur0\\bord(1)\\1c&HFFFFFF\\3c&H000000\\fs(%d)}"):format(24)

    function setButtonTooltip(button_lo, text)
        button_lo.button.tooltip = text
        button_lo.button.tooltip_style = buttonTooltipStyle
        local hw = button_lo.geometry.w/2
        local ty = osc_geo.y + padY * direction
        local an
        local tx
        local edgeThreshold = 60
        if button_lo.geometry.x - edgeThreshold < osc_geo.x + padX then
            an = 1 -- x,y is bottom-left
            tx = math.max(osc_geo.x + padX, button_lo.geometry.x - hw)
        elseif osc_geo.x + osc_geo.w - padX < button_lo.geometry.x + edgeThreshold then
            an = 3 -- x,y is bottom-right
            tx = math.min(button_lo.geometry.x + hw, osc_geo.x + osc_geo.w - padX)
        else
            an = 2 -- x,y is bottom-center
            tx = button_lo.geometry.x
        end
        button_lo.button.tooltip_an = an
        button_lo.button.tooltip_geo = { x = tx , y = ty }
    end

Right now, the tooltips are very basic. I'll need to work improving them to have a rounded bg and support multiple lines of text since MPV has multiple actions like Left navigating 10s and Shift+Left navigating 1s.

Track Selection

It would be coo to create a merged audio/subtitle button with a popup like Netflix. Might be too complicated to have multiple generated lists of buttons though.

Playlist

Since mpv has seek fwd/back and chapter next/prev buttons, I've moved the playlist next/prev buttons to the right side like Netflix.

Seekbar Thumbnails

This is probably the most unlikely feature to add. I do remember a lua script that would call ffmpeg to generate a cache of thumbnails every 10sec or so. However that would be an ugly approach.

@Zren
Copy link
Owner Author

Zren commented Mar 18, 2022

Progress Update

Screenshot_20220318_150204

I've managed to iron out the custom button icons. Needed to heavily modify the slider code to support multiple colors for the handle/bg/progress. I've just noticed the cache color is the progress color instead of a gray/white when taking the screenshot.

Since I haven't uploaded a screenshot, here's what the blurred hover effect and tooltip looks like:

Screenshot_20220318_150608

https://gist.github.com/Zren/53afba67b4c6cd27eabe47d11a729815


TODO:

  • Cache seekbar color should be gray and drawn under handle.
  • Smaller text in subtitle selector
  • Nicer looking chapter ticks like bomi.
  • Possible make the seek "snap" to the chapter start on hover.
  • Change sub-pos-y when osd visible/hidden

Anything else besides those will probably just get modified when I grow bored. The existing icons aren't rounded like tethys but most are fine for now.

@Zren Zren changed the title [WIP] mpv osd.lua theme [WIP] mpv osc.lua theme Mar 18, 2022
@Zren
Copy link
Owner Author

Zren commented Mar 19, 2022

Screenshot_20220319_160012

I might eventually modify the window controls to be larger, as they're annoying to click when the player is smaller and the osc scales super small.

@Zren
Copy link
Owner Author

Zren commented Mar 19, 2022

@Zren
Copy link
Owner Author

Zren commented May 17, 2022

I just figured out that I can add m 0 0 m 44 44 in front of the path to create a "viewbox" around the icon so that the icon retains the whitespace around it when aligned. This is particularly important when dealing with the volume icons as their width changes. Up till now we couldn't use a center alignment for the volume icon, but instead used center-left to keep the "speaker" from as volume went up/down.

More can be found out in the Zren/mpv-osc-tethys@master...iconrefactor branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant