219 lines
8.1 KiB
Lua
219 lines
8.1 KiB
Lua
--[[
|
|
|
|
A simple script that shows a pause indicator, on pause
|
|
https://github.com/Samillion/ModernZ/tree/main/extras/pause-indicator-lite
|
|
|
|
--]]
|
|
|
|
local options = {
|
|
-- indicator icon type
|
|
indicator_icon = "pause", -- indicator icon type. "pause", "play"
|
|
indicator_stay = true, -- keep indicator visibile during pause
|
|
indicator_timeout = 0.6, -- timeout (seconds) if indicator doesn't stay
|
|
|
|
-- keybind
|
|
keybind_allow = true, -- allow keybind to toggle pause
|
|
keybind_set = "mbtn_left", -- the used keybind to toggle pause
|
|
keybind_mode = "onpause", -- mode to activate keybind. "onpause", "always"
|
|
keybind_eof_disable = true, -- disable keybind on eof (end of file)
|
|
|
|
-- icon colors & opacity
|
|
icon_color = "#FFFFFF", -- icon fill color
|
|
icon_border_color = "#111111", -- icon border color
|
|
icon_border_width = 1.5, -- icon border width
|
|
icon_opacity = 40, -- icon opacity (0-100)
|
|
|
|
-- pause icon
|
|
rectangles_width = 30, -- width of rectangles
|
|
rectangles_height = 80, -- height of rectangles
|
|
rectangles_spacing = 20, -- spacing between the two rectangles
|
|
|
|
-- play icon
|
|
triangle_width = 80, -- width of triangle
|
|
triangle_height = 80, -- height of triangle
|
|
|
|
-- best with pause icon
|
|
flash_play_icon = true, -- flash play icon on unpause
|
|
flash_icon_timeout = 0.3, -- timeout (seconds) for flash icon
|
|
|
|
-- icon style used in ModernZ osc
|
|
fluent_icons = false, -- requires fonts/fluent-system-icons.ttf
|
|
fluent_icon_size = 80, -- fluent icon size
|
|
|
|
-- mute options
|
|
mute_indicator = false, -- show a mute indicator (requires fluent font)
|
|
mute_indicator_pos = "middle_right", -- position of mute indicator. top_left, top_right, top_center
|
|
-- also: middle_*, bottom_* same as top_* (ie: bottom_right)
|
|
}
|
|
|
|
local msg = require "mp.msg"
|
|
require 'mp.options'.read_options(options, "pause_indicator_lite")
|
|
|
|
-- convert color from hex (adjusted from mpv/osc.lua)
|
|
local function convert_color(color)
|
|
if color:find("^#%x%x%x%x%x%x$") == nil then
|
|
msg.warn("'" .. color .. "' is not a valid color, using default '#FFFFFF'")
|
|
return "FFFFFF" -- color fallback
|
|
end
|
|
return color:sub(6,7) .. color:sub(4,5) .. color:sub(2,3)
|
|
end
|
|
|
|
-- convert percentage opacity (0-100) to ASS alpha values
|
|
local function convert_opacity(value)
|
|
value = math.max(0, math.min(100, value))
|
|
return string.format("%02X", (255 - (value * 2.55)))
|
|
end
|
|
|
|
-- colors and opaicty
|
|
local icon_color = convert_color(options.icon_color)
|
|
local icon_border_color = convert_color(options.icon_border_color)
|
|
local icon_opacity = convert_opacity(options.icon_opacity)
|
|
local icon_font = "fluent-system-icons"
|
|
|
|
-- pause icon
|
|
local function draw_rectangles()
|
|
if options.fluent_icons then
|
|
local pause_icon = "\238\163\140"
|
|
return string.format([[{\\rDefault\\an5\\alpha&H%s\\bord%s\\1c&H%s&\\3c&H%s&\\fs%s\\fn%s}%s]],
|
|
icon_opacity, options.icon_border_width, icon_color, icon_border_color, options.fluent_icon_size, icon_font, pause_icon)
|
|
else
|
|
return string.format([[{\\rDefault\\p1\\an5\\alpha&H%s\\bord%s\\1c&H%s&\\3c&H%s&}m 0 0 l %d 0 l %d %d l 0 %d m %d 0 l %d 0 l %d %d l %d %d{\\p0}]],
|
|
icon_opacity, options.icon_border_width, icon_color, icon_border_color, options.rectangles_width, options.rectangles_width,
|
|
options.rectangles_height, options.rectangles_height, options.rectangles_width + options.rectangles_spacing,
|
|
options.rectangles_width * 2 + options.rectangles_spacing, options.rectangles_width * 2 + options.rectangles_spacing,
|
|
options.rectangles_height, options.rectangles_width + options.rectangles_spacing, options.rectangles_height)
|
|
end
|
|
end
|
|
|
|
-- play icon
|
|
local function draw_triangle()
|
|
if options.fluent_icons then
|
|
local play_icon = "\238\166\143"
|
|
return string.format([[{\\rDefault\\an5\\alpha&H%s\\bord%s\\1c&H%s&\\3c&H%s&\\fs%s\\fn%s}%s]],
|
|
icon_opacity, options.icon_border_width, icon_color, icon_border_color, options.fluent_icon_size, icon_font, play_icon)
|
|
else
|
|
return string.format([[{\\rDefault\\p1\\an5\\alpha&H%s\\bord%s\\1c&H%s&\\3c&H%s&}m 0 0 l %d %d l 0 %d{\\p0}]],
|
|
icon_opacity, options.icon_border_width, icon_color, icon_border_color, options.triangle_width, options.triangle_height / 2, options.triangle_height)
|
|
end
|
|
end
|
|
|
|
-- mute icon
|
|
local function draw_mute()
|
|
if not options.fluent_icons then return end
|
|
|
|
local mute_icon = "\238\173\138"
|
|
local mute_pos_list = {
|
|
["top_left"] = 7,
|
|
["top_center"] = 8,
|
|
["top_right"] = 9,
|
|
["middle_left"] = 4,
|
|
["middle_center"] = 5,
|
|
["middle_right"] = 6,
|
|
["bottom_left"] = 1,
|
|
["bottom_center"] = 2,
|
|
["bottom_right"] = 3,
|
|
}
|
|
local mute_pos = mute_pos_list[options.mute_indicator_pos:lower()] or 6
|
|
return string.format([[{\\rDefault\\an%s\\alpha&H%s\\bord%s\\1c&H%s&\\3c&H%s&\\fs%s\\fn%s}%s]],
|
|
mute_pos, icon_opacity, options.icon_border_width, icon_color, icon_border_color, options.fluent_icon_size, icon_font, mute_icon)
|
|
end
|
|
|
|
-- initiate overlay
|
|
local indicator = mp.create_osd_overlay("ass-events")
|
|
local flash = mp.create_osd_overlay("ass-events")
|
|
local mute = mp.create_osd_overlay("ass-events")
|
|
|
|
-- keep track of pause toggle and end of file
|
|
local toggled, eof
|
|
|
|
-- draw and update indicator
|
|
local function update_indicator()
|
|
local _, _, display_aspect = mp.get_osd_size()
|
|
if display_aspect == 0 or (indicator.visible and not toggled) then return end
|
|
|
|
indicator.data = options.indicator_icon == "play" and draw_triangle() or draw_rectangles()
|
|
indicator:update()
|
|
|
|
if not options.indicator_stay then
|
|
mp.add_timeout(options.indicator_timeout, function() indicator:remove() end)
|
|
end
|
|
end
|
|
|
|
-- flash play icon
|
|
local function flash_icon()
|
|
if not options.flash_play_icon then return flash:remove() end
|
|
flash.data = draw_triangle()
|
|
flash:update()
|
|
mp.add_timeout(options.flash_icon_timeout, function() flash:remove() end)
|
|
end
|
|
|
|
-- draw mute icon
|
|
local function mute_icon()
|
|
mute.data = draw_mute()
|
|
mute:update()
|
|
end
|
|
|
|
-- check if file is video
|
|
local function is_video()
|
|
local t = mp.get_property_native("current-tracks/video")
|
|
return t and not (t.image or t.albumart) and true or false
|
|
end
|
|
|
|
-- remove overlays
|
|
local function shutdown()
|
|
if flash then flash:remove() end
|
|
if indicator then indicator:remove() end
|
|
mp.unobserve_property("pause")
|
|
end
|
|
|
|
-- end of file keybind check
|
|
if options.keybind_eof_disable then
|
|
mp.observe_property("eof-reached", "bool", function(_, val)
|
|
eof = val
|
|
end)
|
|
end
|
|
|
|
-- observe when pause state changes
|
|
mp.observe_property("pause", "bool", function(_, paused)
|
|
if not is_video() then return shutdown() end
|
|
if paused then
|
|
update_indicator()
|
|
toggled = true
|
|
if options.flash_play_icon then flash:remove() end
|
|
else
|
|
indicator:remove()
|
|
if toggled then
|
|
flash_icon()
|
|
toggled = false
|
|
end
|
|
end
|
|
|
|
-- keybind setup (if options allow it)
|
|
if options.keybind_allow == true then
|
|
mp.set_key_bindings({
|
|
{options.keybind_set, function() mp.commandv("cycle", "pause") end}
|
|
}, "pause-indicator", "force")
|
|
|
|
if options.keybind_mode == "always" or (options.keybind_mode == "onpause" and paused) then
|
|
if not eof then mp.enable_key_bindings("pause-indicator") end
|
|
else
|
|
mp.disable_key_bindings("pause-indicator")
|
|
end
|
|
end
|
|
end)
|
|
|
|
-- update pause indicator position if window size changes
|
|
mp.observe_property("osd-dimensions", "native", function()
|
|
if indicator and indicator.visible then
|
|
update_indicator()
|
|
end
|
|
end)
|
|
|
|
if options.mute_indicator and options.fluent_icons then
|
|
mp.observe_property("mute", "bool", function(_, val)
|
|
if val and not mute.visible then mute_icon() else mute:remove() end
|
|
end)
|
|
else
|
|
mute:remove()
|
|
end
|