Created
June 29, 2023 11:06
-
-
Save DBX12/8fb430c988bfad6872ae064e158bd5fe to your computer and use it in GitHub Desktop.
VLC player command runner extension, see https://dbx-12.de/?linux/vlc-command-runner for instructions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# comma-separated list of commands to run when playback is started | |
on_play_commands= | |
# comma-separated list of commands to run when playback is paused | |
on_pause_commands= | |
# comma-separated list of commands to run when playback is stopped | |
on_stop_commands= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local cfgPath = "" | |
local options = { | |
on_play_commands = {}, | |
on_pause_commands = {}, | |
on_stop_commands = {}, | |
} | |
local last_called = { | |
playing = 0, | |
paused = 0, | |
stopped = 0 | |
} | |
--region methods called by vlc | |
---descriptor Describes the extension for VLC | |
function descriptor() | |
return { | |
title = "Command runner", | |
version = "1.0", | |
author = "dbx12", | |
url = "http://dbx-12.de/?linux/vlc-command-runner", | |
shortdesc = "Command runner", | |
description = "This extension triggers commands on your machine when playback is started, paused or stopped.", | |
capabilities = { | |
"playing-listener", | |
"menu" | |
} | |
} | |
end | |
---activate called when the extension is activated | |
function activate() | |
cfgPath = vlc.config.configdir() .. "/command-runner.conf" | |
if file_exists(cfgPath) == false then | |
write_config_file(cfgPath) | |
log_info("Config file is missing, empty config file generated at "..cfgPath) | |
log_info("After editing this file, you should reload the extension config with View > Command Runner > Reload config") | |
else | |
load_config(cfgPath) | |
end | |
end | |
---deactivate called when the extension is deactivated | |
function deactivate() | |
end | |
---meta_changed called when meta information changes | |
function meta_changed() | |
end | |
---playing_changed called when the playback status changes | |
function playing_changed() | |
local status = vlc.playlist.status() | |
if debounce(status) then | |
return | |
end | |
if status == "playing" then | |
run_commands(options.on_play_commands) | |
elseif status == "paused" then | |
run_commands(options.on_pause_commands) | |
elseif status == "stopped" then | |
run_commands(options.on_stop_commands) | |
end | |
end | |
---menu contains the entries in the menu | |
function menu() | |
return {"Reload config"} | |
end | |
---trigger_menu is called when a menu entry is clicked | |
---@param action_id number 1-based id of the entry that was clicked | |
function trigger_menu(action_id) | |
if action_id == 1 then | |
load_config() | |
end | |
end | |
--endregion | |
---debounce prevents calling the commands too fast in case VLC calls `playing_changed()` more than once per state change | |
---@param action string | |
function debounce(action) | |
local now = os.time() | |
if last_called[action] == now then | |
log_dbg(action.." was called too fast after the last call. Ignoring this one.") | |
return true | |
end | |
last_called[action] = now | |
return false | |
end | |
---run_commands runs specified commands with os.execute | |
---@param commands table list of commands to execute | |
function run_commands(commands) | |
for _, command in pairs(commands) do | |
log_dbg("Running command: "..command) | |
os.execute(command) | |
end | |
end | |
--region log functions | |
function log_dbg(message) | |
vlc.msg.dbg("[command runner] "..message) | |
end | |
function log_info(message) | |
vlc.msg.info("[command runner] "..message) | |
end | |
--endregion | |
--region Config file handling | |
function load_config() | |
log_dbg("Loading config from: " .. cfgPath) | |
local lines = lines_from(cfgPath) | |
for _, line in pairs(lines) do | |
-- only process line if it does not start with a # | |
if string.match(line, "^%s*#") == nil then | |
parsed = parse_line(line) | |
if string.match(parsed.key, "_commands") then | |
options[parsed.key] = parse_list(parsed.value) | |
else | |
options[parsed.key] = parsed.value | |
end | |
end | |
end | |
end | |
function parse_line(line) | |
local key, value | |
for k, v in string.gmatch(line, "([a-z_]+)=(.*)") do | |
key = k | |
value = v | |
end | |
return { key = key, value = value } | |
end | |
function parse_list(value) | |
local values = {} | |
for v in string.gmatch(value, "([^,]+)") do | |
table.insert(values, v) | |
end | |
return values | |
end | |
-- source: https://github.com/michaelbull/vlc-credit-skipper/blob/84211bc6e08596d2626be6f58bf8a3beec6db728/credit-skipper.lua#L206 | |
function lines_from(cfgFile) | |
local lines = {} | |
for line in io.lines(cfgFile) do | |
lines[#lines + 1] = line | |
end | |
return lines | |
end | |
-- source: https://github.com/michaelbull/vlc-credit-skipper/blob/84211bc6e08596d2626be6f58bf8a3beec6db728/credit-skipper.lua#L200 | |
function file_exists(file) | |
local f = io.open(file, "rb") | |
if f then | |
f:close() | |
end | |
return f ~= nil | |
end | |
---write_config_file writes the default config (no commands at all) to `cfgPath` | |
function write_config_file() | |
content=[=[ | |
# comma-separated list of commands to run when playback is started | |
on_play_commands= | |
# comma-separated list of commands to run when playback is paused | |
on_pause_commands= | |
# comma-separated list of commands to run when playback is stopped | |
on_stop_commands= | |
]=] | |
local fd = io.open(cfgPath, "wb") | |
fd:write(content) | |
fd:close() | |
end | |
--endregion |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment