126 lines
5.1 KiB
Lua
126 lines
5.1 KiB
Lua
-- original by Wanakachi
|
|
-- suitable for Windows operating systems
|
|
|
|
-- picture-in-picture (PiP) mode for mpv
|
|
|
|
local options = require "mp.options"
|
|
|
|
local o = {
|
|
autofit = "25%x25%",
|
|
autofit_restore_larger = "100%x100%",
|
|
autofit_restore_smaller = "40%x30%",
|
|
geometry = "100%:100%", -- pip position, bottom-right: 100%:100%
|
|
geometry_restore = "50%:50%", -- restore position, center: 50%:50%
|
|
geometry_delay = 0.05 -- delay to avoid geometry race on state change
|
|
}
|
|
|
|
options.read_options(o, _, function() end)
|
|
|
|
local pip_enabled = false
|
|
local geometry_timer = nil
|
|
local original_options = {}
|
|
|
|
-- save original window properties
|
|
local function save_original_options()
|
|
original_options.fullscreen = mp.get_property_bool("fullscreen")
|
|
original_options.window_maximized = mp.get_property_bool("window-maximized")
|
|
original_options.force_window_position = mp.get_property_bool("force-window-position")
|
|
original_options.keepaspect_window = mp.get_property_bool("keepaspect-window")
|
|
original_options.border = mp.get_property_bool("border")
|
|
original_options.ontop = mp.get_property_bool("ontop")
|
|
original_options.window_scale = mp.get_property("window_scale")
|
|
original_options.autofit = mp.get_property("autofit")
|
|
original_options.autofit_larger = mp.get_property("autofit-larger") ~= "" and mp.get_property("autofit-larger") or o.autofit_restore_larger
|
|
original_options.autofit_smaller = mp.get_property("autofit-smaller") ~= "" and mp.get_property("autofit-smaller") or o.autofit_restore_smaller
|
|
original_options.geometry = mp.get_property("geometry") ~= "" and mp.get_property("geometry") or o.geometry_restore
|
|
end
|
|
|
|
-- restore original window properties
|
|
local function restore_original_options()
|
|
if original_options.fullscreen ~= nil then mp.set_property_bool("fullscreen", original_options.fullscreen) end
|
|
if original_options.window_maximized ~= nil then mp.set_property_bool("window-maximized", original_options.window_maximized) end
|
|
if original_options.force_window_position ~= nil then mp.set_property_bool("force-window-position", original_options.force_window_position) end
|
|
if original_options.border ~= nil then mp.set_property_bool("border", original_options.border) end
|
|
if original_options.ontop ~= nil then mp.set_property_bool("ontop", original_options.ontop) end
|
|
if original_options.keepaspect_window ~= nil then mp.set_property_bool("keepaspect-window", original_options.keepaspect_window) end
|
|
if original_options.window_scale ~= nil then mp.set_property("window_scale", original_options.window_scale) end
|
|
if original_options.autofit ~= nil then mp.set_property("autofit", original_options.autofit) end
|
|
if original_options.autofit_larger ~= nil then mp.set_property("autofit-larger", original_options.autofit_larger) end
|
|
if original_options.autofit_smaller ~= nil then mp.set_property("autofit-smaller", original_options.autofit_smaller) end
|
|
if original_options.geometry ~= nil then mp.set_property("geometry", original_options.geometry) end
|
|
end
|
|
|
|
local function cancel_geometry_timer()
|
|
if geometry_timer then
|
|
geometry_timer:kill()
|
|
geometry_timer = nil
|
|
end
|
|
end
|
|
|
|
local function set_geometry_delay(value)
|
|
cancel_geometry_timer()
|
|
geometry_timer = mp.add_timeout(o.geometry_delay, function()
|
|
geometry_timer = nil
|
|
mp.set_property("geometry", value)
|
|
end)
|
|
end
|
|
|
|
-- enter PiP mode
|
|
local function enable_pip()
|
|
if pip_enabled then return end
|
|
|
|
save_original_options()
|
|
|
|
mp.set_property_bool("fullscreen", false) -- exit fullscreen if necessary
|
|
mp.set_property_bool("window-minimized", false)
|
|
mp.set_property_bool("force-window-position", false)
|
|
mp.set_property_bool("border", false) -- remove decorations
|
|
mp.set_property_bool("ontop", true) -- keep above other windows
|
|
mp.set_property_bool("keepaspect-window", true)
|
|
mp.set_property("autofit", o.autofit)
|
|
mp.set_property("autofit-larger", "")
|
|
mp.set_property("autofit-smaller", "")
|
|
mp.set_property("window_scale", "")
|
|
set_geometry_delay(o.geometry)
|
|
|
|
pip_enabled = true
|
|
mp.osd_message("PiP enabled")
|
|
end
|
|
|
|
-- leave PiP mode
|
|
local function disable_pip()
|
|
if not pip_enabled then return end
|
|
|
|
cancel_geometry_timer()
|
|
restore_original_options()
|
|
pip_enabled = false
|
|
mp.osd_message("PiP disabled")
|
|
end
|
|
|
|
-- toggle PiP on/off
|
|
local function toggle_pip()
|
|
if pip_enabled then
|
|
disable_pip()
|
|
else
|
|
enable_pip()
|
|
end
|
|
end
|
|
|
|
-- monitor fullscreen state changes and exit PiP first
|
|
mp.observe_property("fullscreen", "bool", function(_, value)
|
|
if value and pip_enabled then
|
|
disable_pip()
|
|
mp.set_property_bool("fullscreen", true)
|
|
end
|
|
end)
|
|
|
|
-- monitor window-maximized state changes (on some systems maximize and fullscreen are separate)
|
|
mp.observe_property("window-maximized", "bool", function(_, value)
|
|
if value and pip_enabled then
|
|
disable_pip()
|
|
mp.set_property_bool("window-maximized", true)
|
|
end
|
|
end)
|
|
|
|
-- binding
|
|
mp.add_key_binding(nil, "toggle-pip", toggle_pip) |