Last active
December 8, 2023 05:11
-
-
Save ferdiebergado/191f0c9c22865f5486a77a94f1293c8f to your computer and use it in GitHub Desktop.
mpv script for sending notifications on track change
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 mp = require("mp") | |
local utils = require("mp.utils") | |
local msg = require("mp.msg") | |
local home = os.getenv("HOME") | |
-- local mpv_cache = home .. "/.cache/mpv" | |
local mpv_cache = "/tmp" | |
local title = "" | |
local origin = "" | |
local thumbnail = home .. "/Pictures/icons/Guyman-Helmet-Music-512.png" | |
table.unpack = table.unpack or unpack -- 5.1 compatibility | |
local function shell_escape(inputString) | |
if inputString == nil then | |
return "Station ID" | |
end | |
-- Characters to escape: $ ` " | |
local escapedString = string.gsub(inputString, '([$`"])', "\\%1") | |
-- Preserve newline characters | |
escapedString = string.gsub(escapedString, "\\n", "\n") | |
return escapedString | |
end | |
local function notify(summary, body, options) | |
local option_args = {} | |
for key, value in pairs(options or {}) do | |
-- local info = key .. " = " .. value | |
-- msg.log("info", "DEBUG: " .. info) | |
table.insert(option_args, string.format("--%s=%s", key, value)) | |
end | |
msg.log("info", "summary:", summary) | |
msg.log("info", "body:", body) | |
return pcall(mp.command_native, { | |
"run", | |
"notify-send", | |
table.unpack(option_args), | |
shell_escape(summary), | |
shell_escape(body), | |
}) | |
end | |
local function notify_media() | |
return notify(title, origin, { | |
-- For some inscrutable reason, GNOME 3.24.2 | |
-- nondeterministically fails to pick up the notification icon | |
-- if either of these two parameters are present. | |
-- | |
-- urgency = "low", | |
-- ["app-name"] = "mpv", | |
-- ...and this one makes notifications nondeterministically | |
-- fail to appear altogether. | |
-- | |
-- hint = "string:desktop-entry:mpv", | |
icon = thumbnail, | |
--["replaces-process"] = "mpv-notification", | |
--["replace-file"] = mpv_cache .. "/mpv_notification", | |
}) | |
end | |
local function set_data(metadata) | |
local function tag(name) | |
return metadata[string.upper(name)] or metadata[name] | |
end | |
local function parse_data(data) | |
local t = {} | |
-- TODO: Address multiple hyphen | |
for s in string.gmatch(data, "[^-]+") do | |
table.insert(t, s) | |
end | |
if t[2] ~= nil then | |
t[2] = t[2]:gsub("^%s+", "") | |
end | |
return t | |
end | |
local function update_origin(meta) | |
return string.format("%s\\n%s", origin, meta) | |
end | |
local ice = tag("icy-title") | |
if ice then | |
local data = parse_data(ice) | |
origin = data[1] | |
title = data[2] | |
local icy_name = tag("icy-name") | |
origin = update_origin(icy_name) | |
else | |
title = tag("title") or title | |
origin = tag("artist_credit") or tag("artist") or origin | |
local album = tag("album") | |
if album then | |
origin = update_origin(album) | |
end | |
local year = tag("original_year") or tag("year") | |
if year then | |
origin = update_origin(year) | |
else | |
local date = tag("date") | |
if date then | |
origin = update_origin(date) | |
end | |
end | |
end | |
return title, origin | |
end | |
local function initialize_data_from_filename() | |
local path = mp.get_property_native("path") | |
local dir, file = utils.split_path(path) | |
-- TODO: handle embedded covers and videos? | |
-- potential options: mpv's take_screenshot, ffprobe/ffmpeg, ... | |
-- hooking off existing desktop thumbnails would be good too | |
-- local thumbnail = find_cover(dir) | |
title = file | |
origin = dir | |
end | |
local function dump_cover() | |
if mp.get_property("track-list/1/albumart") == "yes" then | |
msg.log("info", "Cover art found. Dumping cover art...") | |
local path = mp.get_property_native("path") | |
local cover = mpv_cache .. "/mpv.jpg" | |
mp.command_native({ | |
"run", | |
"ffmpeg", | |
"-loglevel", | |
"quiet", | |
"-y", | |
"-i", | |
path, | |
"-map", | |
"0:v", | |
"-map", | |
"-0:V", | |
"-c", | |
"copy", | |
cover, | |
}) | |
msg.log("info", "Command finished. Cover art dumped to " .. cover) | |
thumbnail = cover | |
end | |
end | |
local function update_data() | |
initialize_data_from_filename() | |
dump_cover() | |
end | |
local function notify_metadata_updated(_, metadata) | |
if metadata then | |
-- for name,val in pairs(metadata) do | |
-- msg.log("info", name, ": ", val) | |
-- end | |
title, origin = set_data(metadata) | |
end | |
if title ~= "" then | |
msg.log("info", "Sending notification...") | |
-- return notify_media(title, origin, thumbnail) | |
return notify_media() | |
end | |
end | |
mp.add_hook("on_preloaded", 50, update_data) | |
mp.observe_property("metadata", "native", notify_metadata_updated) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment