Skip to content
This repository has been archived by the owner on Dec 18, 2024. It is now read-only.

Playerctl: Added metadata_v2 #207

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 109 additions & 36 deletions signal/playerctl/playerctl_lib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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

Expand All @@ -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
Expand All @@ -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()
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down