[gnome-music] Make loading of cover art asynchronous
- From: Vadim Rutkovsky <vrutkovsky src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music] Make loading of cover art asynchronous
- Date: Tue, 4 Jun 2013 10:42:26 +0000 (UTC)
commit e579c2344ab194d7d0b4db1a6b945d8d4845c22f
Author: Arnel A. Borja <kyoushuu yahoo com>
Date: Sat Jun 1 14:10:39 2013 +0800
Make loading of cover art asynchronous
https://bugzilla.gnome.org/show_bug.cgi?id=700443
src/albumArtCache.js | 71 ++++++++++++++++++++++++++++++++++---------------
src/player.js | 11 +++++--
src/view.js | 56 +++++++++++++++++++++------------------
src/widgets.js | 68 ++++++++++++++++++++++++++---------------------
4 files changed, 125 insertions(+), 81 deletions(-)
---
diff --git a/src/albumArtCache.js b/src/albumArtCache.js
index 5390d61..91e906f 100644
--- a/src/albumArtCache.js
+++ b/src/albumArtCache.js
@@ -52,9 +52,55 @@ const AlbumArtCache = new Lang.Class({
}
},
- lookup: function(size, artist, album) {
- var key, path;
+ _tryLoad: function(size, artist, album, i, callback) {
+ var key, path, file;
+ if (i >= this._keybuilder_funcs.length) {
+ callback(null);
+ return;
+ }
+
+ key = this._keybuilder_funcs[i].call(this, artist, album);
+ path = GLib.build_filenamev([this.cacheDir, key + ".jpeg"]);
+ file = Gio.File.new_for_path(path);
+
+ file.read_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this,
+ function(object, res) {
+ try {
+ let stream = object.read_finish(res);
+ GdkPixbuf.Pixbuf.new_from_stream_async(stream, null, Lang.bind(this,
+ function(source, res) {
+ try {
+ let pixbuf = GdkPixbuf.Pixbuf.new_from_stream_finish(res),
+ width = pixbuf.get_width(),
+ height = pixbuf.get_height();
+ if (width >= size || height >= size) {
+ let scale = Math.max(width, height)/size;
+ callback(pixbuf.scale_simple(width/scale, height/scale, 2));
+
+ return;
+ }
+ }
+ catch (error) {
+ if (this.logLookupErrors)
+ print ("ERROR:", error);
+ }
+
+ this._tryLoad(size, artist, album, ++i, callback);
+ }));
+
+ return;
+ }
+ catch (error) {
+ if (this.logLookupErrors)
+ print ("ERROR:", error);
+ }
+
+ this._tryLoad(size, artist, album, ++i, callback);
+ }));
+ },
+
+ lookup: function(size, artist, album, callback) {
if (artist == null) {
artist = " ";
}
@@ -63,26 +109,7 @@ const AlbumArtCache = new Lang.Class({
album = " ";
}
- for (var i = 0; i < this._keybuilder_funcs.length; i++)
- {
- try {
- key = this._keybuilder_funcs[i].call (this, artist, album);
- path = GLib.build_filenamev([this.cacheDir, key + ".jpeg"]);
- let pixbuf = GdkPixbuf.Pixbuf.new_from_file(path),
- width = pixbuf.get_width(),
- height = pixbuf.get_height();
- if (width >= size || height >= size) {
- let scale = Math.max(width, height)/size;
- return pixbuf.scale_simple(width/scale, height/scale, 2);
- }
- }
- catch (error) {
- if (this.logLookupErrors)
- print ("ERROR:", error);
- }
- }
-
- return null;
+ this._tryLoad(size, artist, album, 0, callback);
},
normalizeAndHash: function(input, utf8Only, utf8) {
diff --git a/src/player.js b/src/player.js
index f6ce1dd..18c4b05 100644
--- a/src/player.js
+++ b/src/player.js
@@ -56,6 +56,7 @@ const Player = new Lang.Class({
this._lastState = Gst.State.PAUSED;
this.repeat = RepeatType.NONE;
this.cache = AlbumArtCache.AlbumArtCache.getDefault();
+ this._symbolicIcon = this.cache.makeDefaultIcon(ART_SIZE, ART_SIZE);
Gst.init(null, 0);
this.discoverer = new GstPbutils.Discoverer();
@@ -132,7 +133,6 @@ const Player = new Lang.Class({
},
load: function(media) {
- var pixbuf;
this._setDuration(media.get_duration());
this.songTotalTimeLabel.set_label(this.secondsToString (media.get_duration()));
this.progressScale.sensitive = true;
@@ -149,8 +149,13 @@ const Player = new Lang.Class({
this.prevBtn.set_sensitive(true);
else
this.prevBtn.set_sensitive(false);
- pixbuf = this.cache.lookup (ART_SIZE, media.get_artist (), media.get_string(Grl.METADATA_KEY_ALBUM));
- this.coverImg.set_from_pixbuf (pixbuf);
+ this.coverImg.set_from_pixbuf(this._symbolicIcon);
+ this.cache.lookup(ART_SIZE, media.get_artist(), media.get_string(Grl.METADATA_KEY_ALBUM),
Lang.bind(this,
+ function(pixbuf) {
+ if (pixbuf != null) {
+ this.coverImg.set_from_pixbuf(pixbuf);
+ }
+ }));
if (media.get_title() != null) {
this.titleLabel.set_label(media.get_title());
diff --git a/src/view.js b/src/view.js
index 5a62618..3f4aff9 100644
--- a/src/view.js
+++ b/src/view.js
@@ -216,33 +216,37 @@ const ViewContainer = new Lang.Class({
artist = item.get_author();
if (item.get_string(Grl.METADATA_KEY_ARTIST) != null)
artist = item.get_string(Grl.METADATA_KEY_ARTIST)
- var icon = albumArtCache.lookup(this._iconHeight, artist, item.get_string(Grl.METADATA_KEY_ALBUM));
- if (icon != null) {
- icon = albumArtCache.makeIconFrame(icon)
- this._model.set_value(iter, 4, icon);
- return false;
- }
- var options = Grl.OperationOptions.new(null);
- options.set_flags (Grl.ResolutionFlags.FULL | Grl.ResolutionFlags.IDLE_RELAY);
- grilo.tracker.resolve(
- item,
- [Grl.METADATA_KEY_THUMBNAIL],
- options,
- Lang.bind(this,
- function(source, param, item) {
- var uri = item.get_thumbnail();
- albumArtCache.getFromUri(uri,
- artist,
- item.get_string(Grl.METADATA_KEY_ALBUM),
- this._iconWidth,
- this._iconHeight,
- Lang.bind(this,
- function (icon) {
- icon = albumArtCache.makeIconFrame(icon);
- this._model.set_value(iter, 4, icon);
- }))
+ albumArtCache.lookup(this._iconHeight, artist, item.get_string(Grl.METADATA_KEY_ALBUM),
Lang.bind(this,
+ function(icon) {
+ if (icon != null) {
+ icon = albumArtCache.makeIconFrame(icon)
+ this._model.set_value(iter, 4, icon);
+ this.emit("album-art-updated");
+ }
+ else {
+ var options = Grl.OperationOptions.new(null);
+ options.set_flags(Grl.ResolutionFlags.FULL | Grl.ResolutionFlags.IDLE_RELAY);
+ grilo.tracker.resolve(
+ item,
+ [Grl.METADATA_KEY_THUMBNAIL],
+ options,
+ Lang.bind(this,
+ function(source, param, item) {
+ var uri = item.get_thumbnail();
+ albumArtCache.getFromUri(uri,
+ artist,
+ item.get_string(Grl.METADATA_KEY_ALBUM),
+ this._iconWidth,
+ this._iconHeight,
+ Lang.bind(this,
+ function(icon) {
+ icon = albumArtCache.makeIconFrame(icon);
+ this._model.set_value(iter, 4, icon);
+ this.emit("album-art-updated");
+ }))
+ }));
+ }
}));
- this.emit("album-art-updated");
return false;
},
diff --git a/src/widgets.js b/src/widgets.js
index ce92498..2b1e724 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -100,6 +100,7 @@ const AlbumWidget = new Lang.Class({
this.player = player;
this.hbox = new Gtk.HBox ();
this.iterToClean = null;
+ this._symbolicIcon = albumArtCache.makeDefaultIcon(256, 256);
this.ui = new Gtk.Builder();
this.ui.add_from_resource('/org/gnome/music/AlbumWidget.ui');
@@ -207,10 +208,6 @@ const AlbumWidget = new Lang.Class({
}
let duration = 0;
this.album = album;
- let pixbuf = albumArtCache.lookup (256, artist, item.get_string(Grl.METADATA_KEY_ALBUM));
- if (pixbuf == null)
- pixbuf = albumArtCache.makeDefaultIcon(256, 256);
- this.ui.get_object("cover").set_from_pixbuf (pixbuf);
// if the active queue has been set by this album,
// use it as model, otherwise build the liststore
@@ -236,19 +233,28 @@ const AlbumWidget = new Lang.Class({
duration = duration + track.get_duration();
let iter = this.model.append();
let escapedTitle = GLib.markup_escape_text(track.get_title(), track.get_title().length);
+ this.ui.get_object("cover").set_from_pixbuf(this._symbolicIcon);
try{
this.player.discoverer.discover_uri(track.get_url());
this.model.set(iter,
[0, 1, 2, 3, 4, 5, 6, 7],
- [ escapedTitle, "", "", "", pixbuf, track, false, nowPlayingIconName ]);
+ [ escapedTitle, "", "", "", this._symbolicIcon, track, false, nowPlayingIconName
]);
} catch(err) {
log(err.message);
log("failed to discover url " + track.get_url());
this.model.set(iter,
[0, 1, 2, 3, 4, 5, 6, 7],
- [ escapedTitle, "", "", "", pixbuf, track, true, errorIconName ]);
+ [ escapedTitle, "", "", "", this._symbolicIcon, track, true, errorIconName ]);
}
+ albumArtCache.lookup(256, artist, item.get_string(Grl.METADATA_KEY_ALBUM),
Lang.bind(this,
+ function(pixbuf) {
+ if (pixbuf != null) {
+ this.ui.get_object("cover").set_from_pixbuf(pixbuf);
+ this.model.set(iter, [4], [pixbuf]);
+ }
+ }));
+
this.ui.get_object("running_length_label_info").set_text(
(parseInt(duration/60) + 1) + " min");
@@ -576,31 +582,33 @@ const ArtistAlbumWidget = new Lang.Class({
},
_updateAlbumArt: function() {
- let pixbuf = albumArtCache.lookup (128, this.artist, this.album.get_title());
- if (pixbuf != null)
- this.ui.get_object("cover").set_from_pixbuf(pixbuf);
- else {
- var options = Grl.OperationOptions.new(null);
- options.set_flags (Grl.ResolutionFlags.FULL | Grl.ResolutionFlags.IDLE_RELAY);
- grilo.tracker.resolve(
- this.album,
- [Grl.METADATA_KEY_THUMBNAIL],
- options,
- Lang.bind(this,
- function(source, param, item) {
- var uri = this.album.get_thumbnail();
- albumArtCache.getFromUri(uri,
- this.artist,
- this.album.get_title(),
- 128,
- 128,
+ albumArtCache.lookup(128, this.artist, this.album.get_title(), Lang.bind(this,
+ function(pixbuf) {
+ if (pixbuf != null)
+ this.ui.get_object("cover").set_from_pixbuf(pixbuf);
+ else {
+ var options = Grl.OperationOptions.new(null);
+ options.set_flags(Grl.ResolutionFlags.FULL | Grl.ResolutionFlags.IDLE_RELAY);
+ grilo.tracker.resolve(
+ this.album,
+ [Grl.METADATA_KEY_THUMBNAIL],
+ options,
Lang.bind(this,
- function (pixbuf) {
- pixbuf = albumArtCache.makeIconFrame(pixbuf);
- this.ui.get_object("cover").set_from_pixbuf(pixbuf);
- }))
- }));
- }
+ function(source, param, item) {
+ var uri = this.album.get_thumbnail();
+ albumArtCache.getFromUri(uri,
+ this.artist,
+ this.album.get_title(),
+ 128,
+ 128,
+ Lang.bind(this,
+ function(pixbuf) {
+ pixbuf = albumArtCache.makeIconFrame(pixbuf);
+ this.ui.get_object("cover").set_from_pixbuf(pixbuf);
+ }))
+ }));
+ }
+ }));
},
trackSelected: function(widget, iter) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]