Unverified Commit 3a486c59 authored by Erik Reider's avatar Erik Reider Committed by GitHub

MPRIS: Support base64 album art (#658)

parent d9e3c7c3
...@@ -31,8 +31,6 @@ namespace SwayNotificationCenter.Widgets.Mpris { ...@@ -31,8 +31,6 @@ namespace SwayNotificationCenter.Widgets.Mpris {
} }
} }
private const int FADE_WIDTH = 20;
const string MPRIS_PREFIX = "org.mpris.MediaPlayer2."; const string MPRIS_PREFIX = "org.mpris.MediaPlayer2.";
HashTable<string, MprisPlayer> players = new HashTable<string, MprisPlayer> (str_hash, HashTable<string, MprisPlayer> players = new HashTable<string, MprisPlayer> (str_hash,
str_equal); str_equal);
......
...@@ -34,7 +34,7 @@ namespace SwayNotificationCenter.Widgets.Mpris { ...@@ -34,7 +34,7 @@ namespace SwayNotificationCenter.Widgets.Mpris {
public const string ICON_PAUSE = "media-playback-pause-symbolic"; public const string ICON_PAUSE = "media-playback-pause-symbolic";
private Cancellable album_art_cancellable = new Cancellable (); private Cancellable album_art_cancellable = new Cancellable ();
private string prev_art_url; private string prev_art_data;
private DesktopAppInfo ?desktop_entry = null; private DesktopAppInfo ?desktop_entry = null;
private unowned Config mpris_config; private unowned Config mpris_config;
...@@ -252,11 +252,11 @@ namespace SwayNotificationCenter.Widgets.Mpris { ...@@ -252,11 +252,11 @@ namespace SwayNotificationCenter.Widgets.Mpris {
private async void update_album_art (HashTable<string, Variant> metadata) { private async void update_album_art (HashTable<string, Variant> metadata) {
if ("mpris:artUrl" in metadata) { if ("mpris:artUrl" in metadata) {
string url = metadata["mpris:artUrl"].get_string (); string art_data = metadata["mpris:artUrl"].get_string ();
if (url == prev_art_url) { if (art_data == prev_art_data) {
return; return;
} }
prev_art_url = url; prev_art_data = art_data;
// Cancel previous download, reset the state and download again // Cancel previous download, reset the state and download again
album_art_cancellable.cancel (); album_art_cancellable.cancel ();
...@@ -264,15 +264,50 @@ namespace SwayNotificationCenter.Widgets.Mpris { ...@@ -264,15 +264,50 @@ namespace SwayNotificationCenter.Widgets.Mpris {
Gdk.Texture ?album_art_texture = null; Gdk.Texture ?album_art_texture = null;
try { try {
File file = File.new_for_uri (url); Uri uri = Uri.parse (art_data, UriFlags.NONE);
InputStream stream = yield file.read_async (Priority.DEFAULT, if (uri.get_scheme () == "data") {
album_art_cancellable); // Load base64 images
art_data = uri.get_path ();
Gdk.Pixbuf pixbuf = yield new Gdk.Pixbuf.from_stream_async ( int comma_index = art_data.index_of_char (',');
stream, album_art_cancellable); if (comma_index < 0) {
album_art_texture = Gdk.Texture.for_pixbuf (pixbuf); throw new UriError.FAILED ("Could not parse \"data\" uri");
}
string meta_data = art_data.substring (0, comma_index);
if (!meta_data.contains (";base64")) {
throw new UriError.FAILED ("\"data\" uri doesn't contain base64 data");
}
string data_part = art_data.substring (comma_index + 1);
uchar[] data = Base64.decode (data_part);
// Try to parse the mime-type if it exists
Gdk.PixbufLoader loader;
string uri_hints[2] = meta_data.split (";");
unowned string mime_type = uri_hints[0];
if (mime_type.length > 0 && mime_type in pixbuf_mime_types) {
loader = new Gdk.PixbufLoader.with_mime_type (mime_type);
} else {
loader = new Gdk.PixbufLoader ();
}
loader.write (data);
loader.close ();
unowned Gdk.Pixbuf ?pixbuf = loader.get_pixbuf ();
if (pixbuf != null) {
album_art_texture = Gdk.Texture.for_pixbuf (pixbuf);
}
} else {
// Load as a regular file/URL
File file = File.new_for_uri (art_data);
InputStream stream = yield file.read_async (Priority.DEFAULT,
album_art_cancellable);
Gdk.Pixbuf pixbuf = yield new Gdk.Pixbuf.from_stream_async (
stream, album_art_cancellable);
album_art_texture = Gdk.Texture.for_pixbuf (pixbuf);
}
} catch (Error e) { } catch (Error e) {
critical ("Could not download album art for %s. Using fallback... (%s)", critical ("MPRIS (%s) album art error: %s. Using fallback...",
source.media_player.identity, e.message); source.media_player.identity, e.message);
} }
if (album_art_texture != null) { if (album_art_texture != null) {
......
...@@ -4,6 +4,8 @@ namespace SwayNotificationCenter { ...@@ -4,6 +4,8 @@ namespace SwayNotificationCenter {
static Swaync app; static Swaync app;
static Settings self_settings; static Settings self_settings;
static HashTable<string, unowned Gdk.PixbufFormat> pixbuf_mime_types;
// Args // Args
static string ?style_path; static string ?style_path;
static string ?config_path; static string ?config_path;
...@@ -40,6 +42,15 @@ namespace SwayNotificationCenter { ...@@ -40,6 +42,15 @@ namespace SwayNotificationCenter {
activated = true; activated = true;
Functions.load_css (style_path); Functions.load_css (style_path);
pixbuf_mime_types =
new HashTable<string, unowned Gdk.PixbufFormat> (str_hash, str_equal);
SList<weak Gdk.PixbufFormat> formats = Gdk.Pixbuf.get_formats ();
foreach (weak Gdk.PixbufFormat format in formats) {
foreach (string mime_type in format.get_mime_types ()) {
pixbuf_mime_types.set (mime_type, format);
}
}
hold (); hold ();
unowned Gdk.Display ?display = Gdk.Display.get_default (); unowned Gdk.Display ?display = Gdk.Display.get_default ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment