Skip to content

Instantly share code, notes, and snippets.

@byblo
Forked from TheDrHax/autosave.lua
Last active September 22, 2025 14:27
Show Gist options
  • Select an option

  • Save byblo/8cf5d24dcd932016c655be58e07c8b2c to your computer and use it in GitHub Desktop.

Select an option

Save byblo/8cf5d24dcd932016c655be58e07c8b2c to your computer and use it in GitHub Desktop.
MPV script that periodically saves "watch later" data during playback
-- autosave.lua
--
-- Periodically saves "watch later" data during playback, rather than only saving on quit.
-- This lets you easily recover your position in the case of an ungraceful shutdown of mpv (crash, power failure, etc.).
--
-- You can configure the save period by creating a "lua-settings" directory inside your mpv configuration directory.
-- Inside the "lua-settings" directory, create a file named "autosave.conf".
-- The save period can be set like so:
--
-- save_period=60
--
-- This will set the save period to once every 60 seconds of playback, time while paused is not counted towards the save period timer.
-- The default save period is 30 seconds.
--
--
-- min_duration=120
--
-- This will set the minimum duration in seconds before starting to automatically save. This option has 2 advantages:
-- 1. To prevent autosave on small medias, which are under 2 minutes by default.
-- 2. To prevent autosave if user is just browsing a medias under 2 minutes before leaving
--
-- Note that if a watch later file does exists already, this setting will not apply anymore.
--
--
-- osd_msg_on_save=2
--
-- This will show on OSD when the script is saving.
-- 0 = no osd msg, 1 = osd each time, 2 = show only once. Default value is 2
--
--
--
-- IMPORTANT! : You must edit your input.conf and add those keys shortcuts to allow mpv to save using this script only:
--
-- ESC script-binding autosave/save_then_quit
-- q script-binding autosave/save_then_quit
-- shift+q script-binding autosave/save
local options = require 'mp.options'
local o = {
save_period = 30, -- def 30
min_duration = 120, -- def 120
osd_msg_on_save = 2 -- def 2
}
options.read_options(o)
local mp = require 'mp'
local function save()
-- skip save if duration is smaller than X seconds or no custom settings like deinterlace ect...
-- this will also allow to keep the watch_later file deleted by default by mpv when necessary
if ( mp.get_property_number("time-pos") >= o.min_duration or mp.get_property_bool("deinterlace") ) then
mp.command("write-watch-later-config")
o.min_duration = 0--since position is now saved no matter what, better save anytime since now even if user seeks under the previous minimum duration value
if o.osd_msg_on_save > 0 then
--mp.osd_message(string.format("\nAUTOSAVE.LUA: start=%s deinterlace=%s", mp.get_property_number("time-pos"), mp.get_property("deinterlace")))
mp.osd_message(string.format("\nAUTOSAVE.LUA"))
if o.osd_msg_on_save == 2 then --only once
o.osd_msg_on_save = 0
end
end
end
end
local function save_then_quit()
save()
mp.command("quit")
end
local function init()
if not mp.get_property_bool("seekable", true) then
return
end
--since mpv deletes the watch-later file at loading the media, restore it under certain conditions (see save() function)
mp.add_timeout(0.02, save) --restore file after a safety timeout of ~1/50s, in case mpv player crashing at restoring a watch-later file as seen on some problematic medias
local save_period_timer = mp.add_periodic_timer(o.save_period, save)
local function pause(name, paused)
if paused then
save_period_timer:stop()
else
save_period_timer:resume()
end
end
mp.observe_property("pause", "bool", pause)
end
mp.register_event("file-loaded", init)
--Note about ESC binding: If using ESC, requires to add into input.conf: ESC script-binding autosave/save_then_quit
mp.add_key_binding("nil", "save_then_quit", save_then_quit)--save then exit
mp.add_key_binding("nil", "save", save)--save via key
--mp.add_forced_key_binding("esc", "save_then_quit", save_then_quit)--does not work with ESC. Requires into input.conf: ESC script-binding autosave/save_then_quit to work
--mp.add_forced_key_binding("q", "save_then_quit", save_then_quit)--works but no need to make things more complicated.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment