├── fastforward.lua ├── gallery-dl_hook.lua ├── resume_helper.lua ├── reverse.lua ├── rubberband_helper.lua ├── tts-subs.lua └── unpauser.lua /fastforward.lua: -------------------------------------------------------------------------------- 1 | -- fastforward.lua 2 | -- 3 | -- Skipping forward by five seconds can be jarring. 4 | -- 5 | -- This script allows you to tap or hold the RIGHT key to speed up video, 6 | -- the faster you tap RIGHT the faster the video will play. After 2.5 7 | -- seconds the playback speed will begin to decay back to 1x speed. 8 | local decay_delay = .05 -- rate of time by which playback speed is decreased 9 | local speed_increments = .2 -- amount by which playback speed is increased each time 10 | local speed_decrements = .4 -- amount by which playback speed is decreased each time 11 | local max_rate = 5 -- will not exceed this rate 12 | local inertial_decay = false -- changes the behavior of speed decay 13 | 14 | 15 | ----------------------- 16 | local mp = require 'mp' 17 | local auto_dec_timer = nil 18 | local osd_duration = math.max(decay_delay, mp.get_property_number("osd-duration")/1000) 19 | 20 | local function inc_speed() 21 | if auto_dec_timer ~= nil then 22 | auto_dec_timer:kill() 23 | end 24 | 25 | local new_speed = mp.get_property("speed") + speed_increments 26 | 27 | if new_speed > max_rate - speed_increments then 28 | new_speed = max_rate 29 | end 30 | 31 | mp.set_property("speed", new_speed) 32 | mp.osd_message(("▶▶ x%.1f"):format(new_speed), osd_duration) 33 | end 34 | 35 | local function auto_dec_speed() 36 | auto_dec_timer = mp.add_periodic_timer(decay_delay, dec_speed) 37 | end 38 | 39 | function dec_speed() 40 | local new_speed = mp.get_property("speed") - speed_decrements 41 | if new_speed < 1 + speed_decrements then 42 | new_speed = 1 43 | if auto_dec_timer ~= nil then auto_dec_timer:kill() end 44 | end 45 | mp.set_property("speed", new_speed) 46 | mp.osd_message(("▶▶ x%.1f"):format(new_speed), osd_duration) 47 | end 48 | 49 | local function fastforward_handle(table) 50 | if table == nil or table["event"] == "down" or table["event"] == "repeat" then 51 | inc_speed() 52 | if inertial_decay then 53 | mp.add_timeout(decay_delay, dec_speed) 54 | end 55 | elseif table["event"] == "up" then 56 | if not inertial_decay then 57 | auto_dec_speed() 58 | end 59 | end 60 | end 61 | 62 | mp.add_forced_key_binding("RIGHT", "fastforward", fastforward_handle, {complex=not inertial_decay, repeatable=inertial_decay}) 63 | -------------------------------------------------------------------------------- /gallery-dl_hook.lua: -------------------------------------------------------------------------------- 1 | -- gallery-dl_hook.lua 2 | -- 3 | -- load online image galleries as playlists using gallery-dl 4 | -- https://github.com/mikf/gallery-dl 5 | -- 6 | -- to use, prepend the gallery url with: gallery-dl:// 7 | -- e.g. 8 | -- `mpv gallery-dl://https://imgur.com/....` 9 | 10 | local utils = require 'mp.utils' 11 | local msg = require 'mp.msg' 12 | 13 | local function exec(args) 14 | local ret = utils.subprocess({args = args}) 15 | return ret.status, ret.stdout, ret 16 | end 17 | 18 | mp.add_hook("on_load", 15, function() 19 | local url = mp.get_property("stream-open-filename", "") 20 | if (url:find("gallery%-dl://") ~= 1) then 21 | msg.debug("not a gallery-dl:// url: " .. url) 22 | return 23 | end 24 | local url = string.gsub(url,"gallery%-dl://","") 25 | 26 | local es, urls, result = exec({"gallery-dl", "-g", url}) 27 | if (es < 0) or (urls == nil) or (urls == "") then 28 | msg.error("failed to get album list.") 29 | end 30 | 31 | mp.commandv("loadlist", "memory://" .. urls) 32 | end) 33 | -------------------------------------------------------------------------------- /resume_helper.lua: -------------------------------------------------------------------------------- 1 | -- resume_helper.lua 2 | -- 3 | -- watch-later saving at the very end of the file be annoying when you want to 4 | -- play that file again. This script always starts a file back at the 5 | -- beginning if it was previously >95% complete. 6 | local mp = require 'mp' 7 | 8 | mp.register_event("file-loaded", function() 9 | if mp.get_property_native("percent-pos") > 95 then 10 | mp.commandv("seek", 0.0, "absolute") 11 | end 12 | end) 13 | -------------------------------------------------------------------------------- /reverse.lua: -------------------------------------------------------------------------------- 1 | -- reverse.lua 2 | -- 3 | -- Reverses the current playlist, preserving playlist titles. 4 | -- Bound to Meta+r 5 | 6 | local function reverse_playlist() 7 | local current_file = mp.get_property("playlist/" .. mp.get_property_number("playlist-pos-1") .. "/filename") 8 | local current_time = mp.get_property_number("time-pos") 9 | local new_pos = nil 10 | 11 | playlist={"#EXTM3U"} 12 | for _, f in ipairs(mp.get_property_native("playlist")) do 13 | table.insert(playlist, 2, f.filename) 14 | if f.title then table.insert(playlist, 2, "#EXTINF:0,"..f.title) end 15 | 16 | if f.filename == current_file then new_pos = 1 17 | elseif new_pos then new_pos = new_pos + 1 18 | end 19 | end 20 | mp.commandv("loadlist", "memory://"..table.concat(playlist,"\n"), "replace") 21 | mp.set_property_number("playlist-pos-1", new_pos) 22 | 23 | local function seeker() 24 | mp.commandv("seek", current_time, "absolute") 25 | mp.unregister_event(seeker) 26 | end 27 | mp.register_event("file-loaded", seeker) 28 | end 29 | 30 | mp.add_key_binding("Meta+r", "reverse-playlist", reverse_playlist) 31 | -------------------------------------------------------------------------------- /rubberband_helper.lua: -------------------------------------------------------------------------------- 1 | -- rubberband_helper.lua 2 | -- 3 | -- rubberband is great for keeping voices intelligible when the video playback 4 | -- is speed up, but it consumes a fair amount of CPU. 5 | -- 6 | -- This script allows you to degrade the audio filter back to scaletempo when 7 | -- playback speeds are high enough to make rubberband pointless. Hopefully 8 | -- this reduces pesky A/V desync that can occur when rubberband is pushed 9 | -- too fast. 10 | -- 11 | -- (default threshold is 3x, based on my personal preference) 12 | local mp = require 'mp' 13 | 14 | local threshold = 3 15 | local scaletempo_af = {{name='scaletempo', enabled=true, params={speed="tempo"}}} 16 | local rubberband_af = {{name='rubberband', enabled=true, params={channels="together"}}} 17 | 18 | local last_set = nil 19 | local function changed_speed(name, value) 20 | if last_set ~= scaletempo_af and (value == 1.0 or value > threshold) then 21 | mp.set_property_native('af', scaletempo_af) 22 | last_set = scaletempo_af 23 | elseif last_set ~= rubberband_af and (value ~= 1.0 and value <= threshold) then 24 | mp.set_property_native('af', rubberband_af) 25 | last_set = rubberband_af 26 | end 27 | end 28 | 29 | mp.observe_property("speed", "number", changed_speed) 30 | 31 | --re-implement the [ and ] keys. 32 | --this nonsense is needed because observe_property("speed"...) isn't working 33 | --properly for some reason in mpv 0.29.0 34 | mp.add_forced_key_binding("[", "slowdown", function() 35 | mp.set_property("speed", mp.get_property("speed") - 0.1) 36 | mp.osd_message(string.format("x%.1f", mp.get_property("speed")), 1) 37 | end ,{repeatable=true}) 38 | 39 | mp.add_forced_key_binding("]", "speedup", function() 40 | mp.set_property("speed", mp.get_property("speed") + 0.1) 41 | mp.osd_message(string.format("x%.1f", mp.get_property("speed")), 1) 42 | end ,{repeatable=true} ) 43 | -------------------------------------------------------------------------------- /tts-subs.lua: -------------------------------------------------------------------------------- 1 | local utils = require 'mp.utils' 2 | 3 | 4 | local function exec(args) 5 | local ret = utils.subprocess({args = args}) 6 | return ret.status, ret.stdout, ret 7 | end 8 | 9 | local last_text = "" 10 | local enabled = false 11 | mp.observe_property("sub-text","string", function(prop,txt) 12 | if enabled and txt ~= nil and txt ~= last_text then 13 | last_text = txt 14 | exec({"say", " "..txt}) -- prepend a space, incase the subtitle line begins with a - character. 15 | end 16 | end) 17 | 18 | mp.add_key_binding("Ctrl+x","toggle-tts-subs", function() 19 | enabled = not enabled 20 | mp.osd_message("Subtitle TTS mode: ".. utils.to_string(enabled) ) 21 | end) 22 | 23 | -------------------------------------------------------------------------------- /unpauser.lua: -------------------------------------------------------------------------------- 1 | -- unpauser.lua 2 | -- 3 | -- Always unpause mpv when a new file is loaded. 4 | 5 | mp.add_hook("on_load", 5, function () 6 | if(mp.get_property_bool("pause") == true) then 7 | mp.set_property_bool("pause", false) 8 | end 9 | end) 10 | --------------------------------------------------------------------------------