├── .github └── README.md ├── LICENSE.md └── persist-properties.lua /.github/README.md: -------------------------------------------------------------------------------- 1 | # persist-properties 2 | 3 | Lua script for [mpv](https://mpv.io/) to keep selected values like volume between player sessions. 4 | 5 | An example configuration _(script-opts/persist_properties.conf)_ : 6 | ``` 7 | properties=volume,sub-scale 8 | ``` -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 d87 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /persist-properties.lua: -------------------------------------------------------------------------------- 1 | -- Script home: https://github.com/d87/mpv-persist-properties 2 | local utils = require "mp.utils" 3 | local msg = require "mp.msg" 4 | 5 | local opts = { 6 | properties = "volume,sub-scale", 7 | } 8 | (require 'mp.options').read_options(opts, "persist_properties") 9 | 10 | local CONFIG_ROOT = (os.getenv('APPDATA') or os.getenv('HOME')..'/.config')..'/mpv/' 11 | if not utils.file_info(CONFIG_ROOT) then 12 | -- On Windows if using portable_config dir, APPDATA mpv folder isn't auto-created 13 | -- In more recent mpv versions there's a mp.get_script_directory function, but i'm not using it for compatiblity 14 | local mpv_conf_path = mp.find_config_file("scripts") -- finds where the scripts folder is located 15 | local mpv_conf_dir = utils.split_path(mpv_conf_path) 16 | CONFIG_ROOT = mpv_conf_dir 17 | end 18 | local PCONFIG = CONFIG_ROOT..'persistent_config.json'; 19 | 20 | local function split(input) 21 | local ret = {} 22 | for str in string.gmatch(input, "([^,]+)") do 23 | table.insert(ret, str) 24 | end 25 | return ret 26 | end 27 | local persisted_properties = split(opts.properties) 28 | 29 | local print = function(...) 30 | -- return msg.log("info", ...) 31 | end 32 | 33 | -- print("Config Root is "..CONFIG_ROOT) 34 | 35 | local isInitialized = false 36 | 37 | local properties 38 | 39 | local function load_config(file) 40 | local f = io.open(file, "r") 41 | if f then 42 | local jsonString = f:read() 43 | f:close() 44 | 45 | if jsonString == nil then 46 | return {} 47 | end 48 | 49 | local props = utils.parse_json(jsonString) 50 | if props then 51 | return props 52 | end 53 | end 54 | return {} 55 | end 56 | 57 | local function save_config(file, properties) 58 | local serialized_props = utils.format_json(properties) 59 | 60 | local f = io.open(file, 'w+') 61 | if f then 62 | f:write(serialized_props) 63 | f:close() 64 | else 65 | msg.log("error", string.format("Couldn't open file: %s", file)) 66 | end 67 | end 68 | 69 | local save_timer = nil 70 | local got_unsaved_changed = false 71 | 72 | local function onInitialLoad() 73 | properties = load_config(PCONFIG) 74 | 75 | for i, property in ipairs(persisted_properties) do 76 | local name = property 77 | local value = properties[name] 78 | if value ~= nil then 79 | mp.set_property_native(name, value) 80 | end 81 | end 82 | 83 | for i, property in ipairs(persisted_properties) do 84 | local property_type = nil 85 | mp.observe_property(property, property_type, function(name) 86 | if isInitialized then 87 | local value = mp.get_property_native(name) 88 | -- print(string.format("%s changed to %s at %s", name, value, os.time())) 89 | 90 | properties[name] = value 91 | 92 | if save_timer then 93 | save_timer:kill() 94 | save_timer:resume() 95 | got_unsaved_changed = true 96 | else 97 | save_timer = mp.add_timeout(5, function() 98 | save_config(PCONFIG, properties) 99 | got_unsaved_changed = false 100 | end) 101 | end 102 | end 103 | end) 104 | end 105 | 106 | isInitialized = true 107 | end 108 | 109 | onInitialLoad() 110 | mp.register_event("shutdown", function() 111 | if got_unsaved_changed then 112 | save_config(PCONFIG, properties) 113 | end 114 | end) 115 | --------------------------------------------------------------------------------