diff --git a/CLAUDE.md b/CLAUDE.md index 20b2a61..0d8038b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,7 +13,7 @@ just check # fmt-check + lint (pre-commit gate) ## Architecture -This repository holds standalone Lua scripts for mpv (0.36+, bundled Lua 5.2). Each script in `scripts/` is self-contained with no external Lua dependencies. +This repository holds Lua scripts for mpv (0.36+, bundled Lua 5.2). Script structure convention: 1. Header comment block explaining features, requirements, and configuration @@ -21,6 +21,17 @@ Script structure convention: 3. Note indicating no edits are needed below the config block 4. Implementation code +### Shared Library + +`scripts/lib/utils.lua` contains common utilities (trim, clamp, ASS color helpers). Scripts load it via: + +```lua +package.path = mp.command_native({ "expand-path", "~~/scripts/lib/?.lua;" }) .. package.path +local lib = require("utils") +``` + +When adding new shared functions, prefer adding to this module over duplicating code. + ## Code Style - 2-space indentation, 100-column width, double quotes preferred (enforced by stylua) diff --git a/README.md b/README.md index 40aa02f..f655b33 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,226 @@ # mpv-scripts -Small collection of personal mpv Lua scripts. Drop any file from `scripts/` into your `~/.config/mpv/scripts/` to enable it. +Personal collection of Lua scripts for mpv (0.36+). -- `ac-power.lua` — polls Home Assistant for a power sensor and shows wattage in the OSD with debounce/backoff. -- `kb-blackout.lua` — dims or turns off the keyboard backlight while mpv is playing, restores it on pause/idle/unfocus. -- `touch-gestures.lua` — tablet-friendly vertical edge swipes: right edge changes system volume (PipeWire/Pulse), left edge changes screen brightness (brightnessctl), with OSD feedback and bottom exclusion to avoid the OSC. +## Installation + +Copy desired scripts from `scripts/` into `~/.config/mpv/scripts/`. Also copy `scripts/lib/` for the shared utilities required by all scripts. + +```bash +cp scripts/lib ~/.config/mpv/scripts/ -r +cp scripts/ac-power.lua ~/.config/mpv/scripts/ +``` + +Configuration is done by editing the `config` table at the top of each script. + +--- + +## ac-power.lua + +Displays Home Assistant AC power sensor readings with a color-coded gauge, delta indicator, and persistent min/max tracking. + +**Display format:** `[████░░░░] 450W +50` + +**Features:** +- Polls Home Assistant API for power sensor data +- Visual gauge colored by power level (green → yellow → red) +- Delta indicator showing power change (+/-) colored by trend +- Persistent min/max tracking across sessions (stored in `~/.cache/mpv/`) +- Debounces updates to avoid OSD spam +- Exponential backoff on network failures + +**Requirements:** +- Home Assistant instance with a power sensor +- Long-lived access token from HA +- `curl` in PATH + +**Configuration:** + +```lua +local config = { + -- Home Assistant connection (required) + sensor_id = "sensor.ac_power", + ha_base_url = "http://homeassistant.local:8123", + ha_token = "YOUR_LONG_LIVED_TOKEN", + + -- Polling behavior + poll_interval = 3, -- seconds between polls + min_delta_watts = 5, -- minimum change to trigger display + force_refresh_interval = 30, -- force display even if delta small + + -- Gauge + show_gauge = true, + gauge_width = 8, -- number of bar segments + gauge_max_watts = 1000, -- scale reference (or uses tracked max) + + -- Delta indicator + show_delta = true, + delta_stable_range = 5, -- watts within which shows as stable (white) + + -- Min/Max tracking + track_minmax = true, + show_minmax = false, -- show [min-max] inline + persist_minmax = true, -- save to disk across sessions + + -- Color thresholds (watts) + color_low_threshold = 200, -- below = green + color_mid_threshold = 500, -- below = yellow + color_high_threshold = 800, -- above = red +} +``` + +**Script messages:** +- `script-message ac-power-refresh` — force immediate poll +- `script-message ac-power-reset-minmax` — clear min/max history + +--- + +## kb-blackout.lua + +Dims or disables the keyboard backlight while mpv is playing, restoring it on pause or when mpv loses focus. + +**Features:** +- Captures starting brightness and restores exact value +- Auto-discovers keyboard LED device via `brightnessctl --list` +- Debounces rapid state changes +- Optional restore on window unfocus + +**Requirements:** +- Linux +- `brightnessctl` with permission to control LED device + +**Configuration:** + +```lua +local config = { + timeout_ms = 3000, -- delay before dimming after playback starts + minimum_brightness = 0, -- target brightness (0 = off) + restore_on_pause = true, -- restore when paused + restore_on_unfocus = true, -- restore when mpv loses window focus + debounce_ms = 250, -- ignore rapid state flips + led_path = "", -- auto-detect, or set explicitly e.g. "asus::kbd_backlight" + brightnessctl_path = "brightnessctl", +} +``` + +**Example — keep minimal glow instead of full off:** + +```lua +minimum_brightness = 10, -- 10% brightness while playing +``` + +--- + +## playback-health.lua + +Monitors playback health and shows OSD warnings only when problems occur (buffering, frame drops, low cache). + +**Features:** +- Silent during normal playback +- Detects network streams automatically (cache warnings only for streams) +- Frame drop monitoring for all sources +- Buffer prediction (estimates time to stall/resume) +- Bandwidth monitoring (warns when download can't keep up) +- Color-coded warnings with cooldown to prevent spam + +**Configuration:** + +```lua +local config = { + -- Thresholds + cache_warning_seconds = 5, -- warn when cache falls below (streams) + cache_critical_seconds = 2, -- critical threshold (red) + drop_rate_threshold = 1.0, -- drops per second to trigger warning + drop_window_seconds = 5, -- time window for measuring drops + + -- Display + osd_duration = 3, + show_buffering_percent = true, + show_buffer_prediction = true, -- "stall in 5s" / "resume in 3s" + show_recovery = true, -- "✓ Recovered" message + cooldown_seconds = 10, -- minimum time between same warning type + + -- What to monitor + monitor_cache = true, + monitor_drops = true, + monitor_bandwidth = true, + bandwidth_ratio_warn = 0.9, -- warn when download/playback < 90% +} +``` + +**Example — more sensitive drop detection:** + +```lua +drop_rate_threshold = 0.5, -- warn at 0.5 drops/sec instead of 1.0 +drop_window_seconds = 3, -- shorter measurement window +``` + +--- + +## touch-gestures.lua + +Tablet-friendly swipe controls: horizontal swipes seek, vertical edge swipes adjust volume (right) or brightness (left). + +**Features:** +- Horizontal swipes anywhere: seek forward/backward +- Right edge vertical swipes: system volume (PipeWire/PulseAudio) +- Left edge vertical swipes: screen brightness (brightnessctl) +- Axis locking prevents accidental cross-axis actions +- Fine-grained steps at low values +- OSD feedback after each adjustment + +**Requirements:** +- mpv 0.39+ recommended +- On Wayland: run mpv with `--native-touch=yes` +- `brightnessctl` for brightness control +- `wpctl` (PipeWire) or `pactl` (PulseAudio) for volume + +**Configuration:** + +```lua +local config = { + -- Sensitivity + steps_per_screen = 40, -- steps across full screen height + deadzone_px = 4, -- ignore tiny movements + + -- Step sizes + volume_step = 5, -- percent per step + volume_step_fine = 1, -- step when below fine_threshold + brightness_step = 5, + brightness_step_fine = 1, + fine_threshold = 10, -- use fine steps below this % + seek_step = 5, -- seconds per horizontal step + + -- Limits + max_volume = 130, + min_brightness = 1, -- prevent turning off screen + + -- Zones (fraction of screen width) + left_zone_ratio = 0.35, -- brightness zone + right_zone_ratio = 0.35, -- volume zone + bottom_exclude_ratio = 0.15, -- ignore bottom (OSC area) + + -- Direction + invert_vertical = false, + invert_horizontal = false, +} +``` + +**Example — larger edge zones for easier targeting:** + +```lua +left_zone_ratio = 0.4, +right_zone_ratio = 0.4, +``` + +**Example — add to mpv.conf for Wayland touch support:** + +``` +native-touch=yes +``` + +--- + +## License + +These scripts are provided as-is for personal use.