diff --git a/signal/playerctl/playerctl_lib.lua b/signal/playerctl/playerctl_lib.lua index ca196333..23d8c53c 100644 --- a/signal/playerctl/playerctl_lib.lua +++ b/signal/playerctl/playerctl_lib.lua @@ -66,9 +66,27 @@ function playerctl:disable() self._private.last_position = -1 self._private.last_length = -1 self._private.last_player = nil - self._private.last_title = "" - self._private.last_artist = "" - self._private.last_artUrl = "" + self._private.last_metadata_table = { + album = "", + albumArtist = "", + artist = "", + asText = "", + audioBPM = "", + autoRating = "", + comment = "", + composer = "", + contentCreated = "", + discNumber = "", + firstUsed = "", + genre = "", + lastUsed = "", + lyricist = "", + title = "", + trackNumber = "", + url = "", + useCount = "", + userRating = "", + } end function playerctl:pause(player) @@ -179,25 +197,46 @@ function playerctl:get_player_of_name(name) return nil end -local function emit_metadata_signal(self, title, artist, artUrl, album, new, player_name) - title = gstring.xml_escape(title) - artist = gstring.xml_escape(artist) - album = gstring.xml_escape(album) +local function join_table_of_strings(t) + if type(t) == "nil" then return "" end + local out = t[1] + for i = 2, #t do + out = out .. ", " .. t[i] + end + return out +end + +local function emit_metadata_signal(self, metadata, new, player_name) + for i, v in pairs(metadata) do + if i ~= "artUrl" and type(v) ~= "number" then + metadata[i] = gstring.xml_escape(v) + end + end -- Spotify client doesn't report its art URL's correctly... if player_name == "spotify" then - artUrl = artUrl:gsub("open.spotify.com", "i.scdn.co") + metadata.artUrl = metadata.artUrl:gsub("open.spotify.com", "i.scdn.co") end - if artUrl ~= "" then + if metadata.artUrl ~= "" then local art_path = os.tmpname() - helpers.filesystem.save_image_async_curl(artUrl, art_path, function() - self:emit_signal("metadata", title, artist, art_path, album, new, player_name) - capi.awesome.emit_signal("bling::playerctl::title_artist_album", title, artist, art_path, player_name) + helpers.filesystem.save_image_async_curl(metadata.artUrl, art_path, function() + if self.metadata_v2 then + self:emit_signal("metadata", metadata, art_path, new, player_name) + capi.awesome.emit_signal("bling::playerctl::title_artist_album", metadata, art_path, player_name) + elseif not self.metadata_v2 then + self:emit_signal("metadata", metadata.title, metadata.artist, art_path, metadata.album, new, player_name) + capi.awesome.emit_signal("bling::playerctl::title_artist_album", metadata.title, metadata.artist, art_path, player_name) + end end) else - capi.awesome.emit_signal("bling::playerctl::title_artist_album", title, artist, "", player_name) - self:emit_signal("metadata", title, artist, "", album, new, player_name) + if self.metadata_v2 then + self:emit_signal("metadata", metadata, "", new, player_name) + capi.awesome.emit_signal("bling::playerctl::title_artist_album", metadata, "", player_name) + elseif not self.metadata_v2 then + self:emit_signal("metadata", metadata.title, metadata.artist, "", metadata.album, new, player_name) + capi.awesome.emit_signal("bling::playerctl::title_artist_album", metadata.title, metadata.artist, "", player_name) + end end end @@ -208,13 +247,30 @@ local function metadata_cb(self, player, metadata) local data = metadata.value - local title = data["xesam:title"] or "" - local artist = data["xesam:artist"][1] or "" - for i = 2, #data["xesam:artist"] do - artist = artist .. ", " .. data["xesam:artist"][i] - end - local artUrl = data["mpris:artUrl"] or "" - local album = data["xesam:album"] or "" + local metadata_table = { + album = data["xesam:album"] or "", + artUrl = data["mpris:artUrl"] or "", + asText = data["xesam:asText"] or "", + audioBPM = data["xesam:audioBPM"] or "", + autoRating = data["xesam:autoRating"] or "", + contentCreated = data["xesam:contentCreated"] or "", + discNumber = data["xesam:discNumber"] or "", + firstUsed = data["xesam:firstUsed"] or "", + lastUsed = data["xesam:lastUsed"] or "", + title = data["xesam:title"] or "", + trackNumber = data["xesam:trackNumber"] or "", + url = data["xesam:url"] or "", + useCount = data["xesam:useCount"] or "", + userRating = data["xesam:userRating"] or "", + } + + metadata_table.albumArtist = join_table_of_strings(data["xesam:albumArtist"]) + metadata_table.artist = join_table_of_strings(data["xesam:artist"]) + metadata_table.comment = join_table_of_strings(data["xesam:comment"]) + metadata_table.composer = join_table_of_strings(data["xesam:composer"]) + metadata_table.genre = join_table_of_strings(data["xesam:genre"]) + metadata_table.lyricist = join_table_of_strings(data["xesam:lyricist"]) + if player == self._private.manager.players[1] then self._private.active_player = player @@ -223,11 +279,9 @@ local function metadata_cb(self, player, metadata) -- changed, so check to see if they have if player ~= self._private.last_player - or title ~= self._private.last_title - or artist ~= self._private.last_artist - or artUrl ~= self._private.last_artUrl + or metadata_table ~= self._private.last_metadata_table then - if (title == "" and artist == "" and artUrl == "") then return end + if (metadata_table.title == "" and metadata_table.artist == "" and metadata_table.artUrl == "") then return end if self._private.metadata_timer ~= nil and self._private.metadata_timer.started then self._private.metadata_timer:stop() @@ -238,16 +292,14 @@ local function metadata_cb(self, player, metadata) autostart = true, single_shot = true, callback = function() - emit_metadata_signal(self, title, artist, artUrl, album, true, player.player_name) + emit_metadata_signal(self, metadata_table, true, player.player_name) end } -- Re-sync with position timer when track changes self._private.position_timer:again() self._private.last_player = player - self._private.last_title = title - self._private.last_artist = artist - self._private.last_artUrl = artUrl + self._private.last_metadata_table = metadata_table end end end @@ -430,12 +482,10 @@ local function player_compare(self, a, b) end local function get_current_player_info(self, player) - local title = player:get_title() or "" - local artist = player:get_artist() or "" + local metadata = player.metadata local artUrl = player:print_metadata_prop("mpris:artUrl") or "" - local album = player:get_album() or "" - emit_metadata_signal(self, title, artist, artUrl, album, false, player.player_name) + metadata_cb(self, metadata, artUrl, false, player.player_name) playback_status_cb(self, player, player.playback_status) volume_cb(self, player, player.volume) loop_status_cb(self, player, player.loop_status) @@ -526,6 +576,11 @@ local function new(args) else ret.update_on_activity = beautiful.playerctl_update_on_activity ~= false end + if args.metadata_v2 ~= nil then + ret.metadata_v2 = args.metadata_v2 + else + ret.metadata_v2 = false -- Default to the old way of passing metadata for backwards compatibility + end ret.interval = args.interval or beautiful.playerctl_position_update_interval or 1 ret.debounce_delay = args.debounce_delay or beautiful.playerctl_debounce_delay or 0.35 parse_args(ret, args) @@ -534,9 +589,27 @@ local function new(args) -- Metadata callback for title, artist, and album art ret._private.last_player = nil - ret._private.last_title = "" - ret._private.last_artist = "" - ret._private.last_artUrl = "" + ret._private.last_metadata_table = { + album = "", + albumArtist = "", + artist = "", + asText = "", + audioBPM = "", + autoRating = "", + comment = "", + composer = "", + contentCreated = "", + discNumber = "", + firstUsed = "", + genre = "", + lastUsed = "", + lyricist = "", + title = "", + trackNumber = "", + url = "", + useCount = "", + userRating = "", + } -- Track position callback ret._private.last_position = -1