summaryrefslogtreecommitdiff
path: root/mac/.config/mpv/scripts/blur-edges.lua
diff options
context:
space:
mode:
Diffstat (limited to 'mac/.config/mpv/scripts/blur-edges.lua')
-rw-r--r--mac/.config/mpv/scripts/blur-edges.lua174
1 files changed, 174 insertions, 0 deletions
diff --git a/mac/.config/mpv/scripts/blur-edges.lua b/mac/.config/mpv/scripts/blur-edges.lua
new file mode 100644
index 0000000..6c3a111
--- /dev/null
+++ b/mac/.config/mpv/scripts/blur-edges.lua
@@ -0,0 +1,174 @@
+local options = require("mp.options")
+
+local opts = {
+ blur_radius = 10,
+ blur_power = 10,
+ minimum_black_bar_size = 3,
+ mode = "all",
+ active = true,
+ reapply_delay = 0.5,
+ watch_later_fix = false,
+ only_fullscreen = true,
+}
+options.read_options(opts)
+
+local active = opts.active
+local applied = false
+
+function set_lavfi_complex(filter)
+ if not filter and mp.get_property("lavfi-complex") == "" then
+ return
+ end
+ local force_window = mp.get_property("force-window")
+ local sub = mp.get_property("sub")
+ mp.set_property("force-window", "yes")
+ if not filter then
+ mp.set_property("lavfi-complex", "")
+ mp.set_property("vid", "1")
+ else
+ if not opts.watch_later_fix then
+ mp.set_property("vid", "no")
+ end
+ mp.set_property("lavfi-complex", filter)
+ end
+ mp.set_property("sub", "no")
+ mp.set_property("force-window", force_window)
+ mp.set_property("sub", sub)
+end
+
+function set_blur()
+ if applied then
+ return
+ end
+ if not mp.get_property("video-out-params") then
+ return
+ end
+ if opts.only_fullscreen and not mp.get_property_bool("fullscreen") then
+ return
+ end
+ local video_aspect = mp.get_property_number("video-aspect-override")
+ local ww, wh = mp.get_osd_size()
+
+ if math.abs(ww / wh - video_aspect) < 0.05 then
+ return
+ end
+ if opts.mode == "horizontal" and ww / wh < video_aspect then
+ return
+ end
+ if opts.mode == "vertical" and ww / wh > video_aspect then
+ return
+ end
+
+ local par = mp.get_property_number("video-params/par")
+ local height = mp.get_property_number("video-params/h")
+ local width = mp.get_property_number("video-params/w")
+
+ local split = "[vid1] split=3 [a] [v] [b]"
+ local crop_format = "crop=%s:%s:%s:%s"
+ local scale_format = "scale=width=%s:height=%s:flags=neighbor"
+
+ local stack_direction, cropped_scaled_1, cropped_scaled_2, blur_size
+
+ if ww / wh > video_aspect then
+ blur_size = math.floor((ww / wh) * height / par - width)
+ local nudge = blur_size % 2
+ blur_size = blur_size / 2
+
+ local height_with_maximized_width = height / width * ww
+ local visible_height = math.floor(height * par * wh / height_with_maximized_width)
+ local visible_width = math.floor(blur_size * wh / height_with_maximized_width)
+
+ local cropped_1 = string.format(crop_format, visible_width, visible_height, "0", (height - visible_height) / 2)
+ local scaled_1 = string.format(scale_format, blur_size + nudge, height)
+ cropped_scaled_1 = cropped_1 .. "," .. scaled_1
+
+ local cropped_2 = string.format(
+ crop_format,
+ visible_width,
+ visible_height,
+ width - visible_width,
+ (height - visible_height) / 2
+ )
+ local scaled_2 = string.format(scale_format, blur_size, height)
+ cropped_scaled_2 = cropped_2 .. "," .. scaled_2
+ stack_direction = "h"
+ else
+ blur_size = math.floor((wh / ww) * width * par - height)
+ local nudge = blur_size % 2
+ blur_size = blur_size / 2
+
+ local width_with_maximized_height = width / height * wh
+ local visible_width = math.floor(width * ww / width_with_maximized_height)
+ local visible_height = math.floor(blur_size * ww / width_with_maximized_height)
+
+ local cropped_1 = string.format(crop_format, visible_width, visible_height, (width - visible_width) / 2, "0")
+ local scaled_1 = string.format(scale_format, width, blur_size + nudge)
+ cropped_scaled_1 = cropped_1 .. "," .. scaled_1
+
+ local cropped_2 = string.format(
+ crop_format,
+ visible_width,
+ visible_height,
+ (width - visible_width) / 2,
+ height - visible_height
+ )
+ local scaled_2 = string.format(scale_format, width, blur_size)
+ cropped_scaled_2 = cropped_2 .. "," .. scaled_2
+ stack_direction = "v"
+ end
+
+ if blur_size < math.max(1, opts.minimum_black_bar_size) then
+ return
+ end
+ local lr = math.min(opts.blur_radius, math.floor(blur_size / 2) - 1)
+ local cr = math.min(opts.blur_radius, math.floor(blur_size / 4) - 1)
+ local blur = string.format("boxblur=lr=%i:lp=%i:cr=%i:cp=%i", lr, opts.blur_power, cr, opts.blur_power)
+
+ zone_1 = string.format("[a] %s,%s [a_fin]", cropped_scaled_1, blur)
+ zone_2 = string.format("[b] %s,%s [b_fin]", cropped_scaled_2, blur)
+
+ local par_fix = "setsar=ratio=" .. tostring(par) .. ":max=10000"
+
+ stack = string.format("[a_fin] [v] [b_fin] %sstack=3,%s [vo]", stack_direction, par_fix)
+ filter = string.format("%s;%s;%s;%s", split, zone_1, zone_2, stack)
+ set_lavfi_complex(filter)
+ applied = true
+end
+
+function unset_blur()
+ set_lavfi_complex()
+ applied = false
+end
+
+local reapplication_timer = mp.add_timeout(opts.reapply_delay, set_blur)
+reapplication_timer:kill()
+
+function reset_blur(k, v)
+ unset_blur()
+ reapplication_timer:kill()
+ reapplication_timer:resume()
+end
+
+function toggle()
+ if active then
+ active = false
+ unset_blur()
+ mp.unobserve_property(reset_blur)
+ else
+ active = true
+ set_blur()
+ local properties = { "osd-width", "osd-height", "path", "fullscreen" }
+ for _, p in ipairs(properties) do
+ mp.observe_property(p, "native", reset_blur)
+ end
+ end
+end
+
+if active then
+ active = false
+ toggle()
+end
+
+mp.add_key_binding(nil, "toggle-blur", toggle)
+mp.add_key_binding(nil, "set-blur", set_blur)
+mp.add_key_binding(nil, "unset-blur", unset_blur)