-
Notifications
You must be signed in to change notification settings - Fork 12
Description
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.
Here's the base osc.lua
we can copy to ~/.config/mpv/scripts/osc.lua
.
- https://github.com/mpv-player/mpv/blob/master/player/lua/osc.lua
osc_tethys.lua
WIP: https://gist.github.com/Zren/53afba67b4c6cd27eabe47d11a729815
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
an
stands for alignment, which adds{\\an(5)}
to the ass text.- https://github.com/mpv-player/mpv/blob/master/player/lua/assdraw.lua#L43
- https://github.com/libass/libass/wiki/ASSv5-Override-Tags#alignment---ainteger2-x
1
means the (x,y) is the bottom-left,4
iscenter-left
,7
is top-left.5
is center and9
is top-right.- When aligning a button to the top-left, it's text inside the button is also aligned to the top-left (which is annoying).
Icons
- The
mpv-osd-symbols
font is bundled, and basically forced for the OSD.- https://github.com/mpv-player/mpv/blob/master/sub/osd_libass.c#L57
- I tried creating a modified font with the tethys play icon. I installed it to the local user using KFontView. Then I placed
{\\fn(tethys-osd-symbols)}}
in front of the playpause icon contents. It doesn't appear to have worked. Creating a custom font and distributing it is too complicated anyways, but was an annoying setback. - https://github.com/mpv-player/mpv/blob/master/player/lua/osc.lua#L1839-L1850
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.
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)
- It seems the
{{\\blur0}}
formatting accepts a value between0
and20
.
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.