[gnome-music] view: don't discover URIs synchronously
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music] view: don't discover URIs synchronously
- Date: Sun, 1 Sep 2013 10:08:27 +0000 (UTC)
commit 5fdc33208d700f4e7e3e3d2b3046a51d723e23f8
Author: Giovanni Campagna <gcampagna src gnome org>
Date: Sun Aug 18 17:57:47 2013 +0200
view: don't discover URIs synchronously
Doing IO in the main loop is always a bad idea. But we don't need
to, because GStreamer can be made to do all the processing in a
background thread and only report the final result.
https://bugzilla.gnome.org/show_bug.cgi?id=706019
gnomemusic/player.py | 32 +++++++++++++++++++
gnomemusic/view.py | 54 +++++++++++++-------------------
gnomemusic/widgets.py | 82 +++++++++++++++++++++++-------------------------
3 files changed, 93 insertions(+), 75 deletions(-)
---
diff --git a/gnomemusic/player.py b/gnomemusic/player.py
index 52b7256..c8834d6 100644
--- a/gnomemusic/player.py
+++ b/gnomemusic/player.py
@@ -81,7 +81,12 @@ class Player(GObject.GObject):
self._symbolicIcon = self.cache.make_default_icon(ART_SIZE, ART_SIZE)
Gst.init(None)
+
self.discoverer = GstPbutils.Discoverer()
+ self.discoverer.connect('discovered', self._on_discovered)
+ self.discoverer.start()
+ self._discovering_urls = {}
+
self.player = Gst.ElementFactory.make('playbin', 'player')
self.bus = self.player.get_bus()
self.bus.add_signal_watch()
@@ -95,6 +100,33 @@ class Player(GObject.GObject):
self.bus.connect('message::eos', self._on_bus_eos)
self._setup_view()
+ def discover_item(self, item, callback, data=None):
+ url = item.get_url()
+ if not url:
+ return
+
+ obj = (callback, data)
+
+ if url in self._discovering_urls:
+ self._discovering_urls[url] += [obj]
+ else:
+ self._discovering_urls[url] = [obj]
+ self.discoverer.discover_uri_async(url)
+
+ def _on_discovered(self, discoverer, info, error):
+ try:
+ cbs = self._discovering_urls[info.get_uri()]
+ del(self._discovering_urls[info.get_uri()])
+
+ for callback, data in cbs:
+ if data is not None:
+ callback(info, error, data)
+ else:
+ callback(info, error)
+ except KeyError:
+ # Not something we're interested in
+ return
+
def _on_settings_changed(self, settings, value):
self.repeat = settings.get_enum('repeat')
self._sync_prev_next()
diff --git a/gnomemusic/view.py b/gnomemusic/view.py
index 3fb5978..a7104ed 100644
--- a/gnomemusic/view.py
+++ b/gnomemusic/view.py
@@ -135,6 +135,8 @@ class ViewContainer(Stack):
self.view.connect('view-selection-changed',
self._on_view_selection_changed)
+ self._discovering_urls = {};
+
def _get_remaining_item_count(self):
if self._cached_count < 0:
self._cached_count = Widgets.get_count(self.countQuery)
@@ -209,6 +211,10 @@ class ViewContainer(Stack):
def populate(self):
print('populate')
+ def _on_discovered(self, info, error, _iter):
+ if error:
+ self._model.set(_iter, [8, 10], [self.errorIconName, True])
+
def _add_item(self, source, param, item):
if not item:
return
@@ -219,23 +225,15 @@ class ViewContainer(Stack):
title = albumArtCache.get_media_title(item)
item.set_title(title)
- def add_new_item():
- _iter = self._model.append()
- icon_name = self.nowPlayingIconName
- if item.get_url():
- try:
- self.player.discoverer.discover_uri(item.get_url())
- except:
- print('failed to discover url ' + item.get_url())
- icon_name = self.errorIconName
- self._model.set(_iter,
- [0, 1, 2, 3, 4, 5, 7, 8, 9, 10],
- [str(item.get_id()), '', title,
- artist, self._symbolicIcon, item,
- -1, icon_name, False, icon_name == self.errorIconName])
- GLib.idle_add(self._update_album_art, item, _iter)
-
- GLib.idle_add(add_new_item)
+ _iter = self._model.append()
+ icon_name = self.nowPlayingIconName
+ self.player.discover_item(item, self._on_discovered, _iter)
+ self._model.set(_iter,
+ [0, 1, 2, 3, 4, 5, 7, 8, 9, 10],
+ [str(item.get_id()), '', title,
+ artist, self._symbolicIcon, item,
+ -1, icon_name, False, False])
+ GLib.idle_add(self._update_album_art, item, _iter)
def _insert_album_art(self, item, cb_item, itr, x=False):
if item and cb_item and not item.get_thumbnail():
@@ -289,6 +287,7 @@ class Albums(ViewContainer):
self.view.set_view_type(Gd.MainViewType.ICON)
self.countQuery = Query.ALBUMS_COUNT
self._albumWidget = Widgets.AlbumWidget(player)
+ self.player = player
self.add(self._albumWidget)
def _back_button_clicked(self, widget, data=None):
@@ -354,21 +353,12 @@ class Songs(ViewContainer):
self._offset += 1
_iter = self._model.append()
item.set_title(albumArtCache.get_media_title(item))
- try:
- if item.get_url():
- self.player.discoverer.discover_uri(item.get_url())
- self._model.set(_iter,
- [2, 3, 5, 8, 9, 10],
- [albumArtCache.get_media_title(item),
- item.get_string(Grl.METADATA_KEY_ARTIST),
- item, self.nowPlayingIconName, False, False])
- except:
- print('failed to discover url ' + item.get_url())
- self._model.set(_iter,
- [2, 3, 5, 8, 9, 10],
- [albumArtCache.get_media_title(item),
- item.get_string(Grl.METADATA_KEY_ARTIST),
- item, self.errorIconName, False, True])
+ self.player.discover_item(item, self._on_discovered, _iter)
+ self._model.set(_iter,
+ [2, 3, 5, 8, 9, 10],
+ [albumArtCache.get_media_title(item),
+ item.get_string(Grl.METADATA_KEY_ARTIST),
+ item, self.nowPlayingIconName, False, False])
def _add_list_renderers(self):
list_widget = self.view.get_generic_view()
diff --git a/gnomemusic/widgets.py b/gnomemusic/widgets.py
index 8668ec2..6c10e16 100644
--- a/gnomemusic/widgets.py
+++ b/gnomemusic/widgets.py
@@ -273,28 +273,24 @@ class AlbumWidget(Gtk.EventBox):
if(self.player.get_playback_status() != 2):
self.player.eventBox.set_visible(True)
+ def _on_discovered(self, info, error, _iter):
+ if error:
+ self.model.set(_iter, [7, 9], [ERROR_ICON_NAME, True])
+
def _on_populate_album_songs(self, source, prefs, track):
if track:
self.tracks.append(track)
self.duration = self.duration + track.get_duration()
_iter = self.model.append()
escapedTitle = AlbumArtCache.get_media_title(track, True)
- try:
- self.player.discoverer.discover_uri(track.get_url())
- self.model.set(_iter,
- [0, 1, 2, 3, 4, 5, 7, 9],
- [escapedTitle,
- self.player.seconds_to_string(
- track.get_duration()),
- '', '', None, track, NOW_PLAYING_ICON_NAME,
- False])
- except Exception as err:
- logging.debug(err.message)
- logging.debug('failed to discover url ' + track.get_url())
- self.model.set(_iter,
- [0, 1, 2, 3, 4, 5, 7, 9],
- [escapedTitle, '', '', '', None,
- track, ERROR_ICON_NAME, True])
+ self.player.discover_item(track, self._on_discovered, _iter)
+ self.model.set(_iter,
+ [0, 1, 2, 3, 4, 5, 7, 9],
+ [escapedTitle,
+ self.player.seconds_to_string(
+ track.get_duration()),
+ '', '', None, track, NOW_PLAYING_ICON_NAME,
+ False])
self.ui.get_object('running_length_label_info').set_text(
'%d min' % (int(self.duration / 60) + 1))
@@ -521,6 +517,15 @@ class ArtistAlbumWidget(Gtk.HBox):
self.pack_start(self.ui.get_object('ArtistAlbumWidget'), True, True, 0)
self.show_all()
+ def _on_discovered(self, info, error, song_widget):
+ if error:
+ self.model.set(song_widget._iter, [4], [ERROR_ICON_NAME])
+ song_widget.now_playing_sign.set_from_icon_name(
+ ERROR_ICON_NAME,
+ Gtk.IconSize.SMALL_TOOLBAR)
+ song_widget.now_playing_sign.show()
+ song_widget.can_be_played = False
+
def get_songs(self, source, prefs, track):
if track:
self.tracks.append(track)
@@ -547,33 +552,21 @@ class ArtistAlbumWidget(Gtk.HBox):
song_widget.model = self.model
song_widget.title = ui.get_object('title')
- try:
- self.player.discoverer.discover_uri(str(track.get_url()))
- self.model.set(itr,
- [0, 1, 2, 3, 4, 5],
- [title, '', '', False,
- NOW_PLAYING_ICON_NAME, track])
- song_widget.now_playing_sign = ui.get_object('image1')
- song_widget.now_playing_sign.set_from_icon_name(
- NOW_PLAYING_ICON_NAME,
- Gtk.IconSize.SMALL_TOOLBAR)
- song_widget.now_playing_sign.set_no_show_all('True')
- song_widget.now_playing_sign.set_alignment(1, 0.6)
- song_widget.can_be_played = True
- song_widget.connect('button-release-event',
- self.track_selected)
-
- except:
- print('failed to discover url ' + str(track.get_url()))
- self.model.set(itr, [0, 1, 2, 3, 4, 5],
- [title, '', '', True,
- ERROR_ICON_NAME, track])
- song_widget.now_playing_sign = ui.get_object('image1')
- song_widget.now_playing_sign.set_from_icon_name(
- ERROR_ICON_NAME,
- Gtk.IconSize.SMALL_TOOLBAR)
- song_widget.now_playing_sign.set_alignment(1, 0.6)
- song_widget.can_be_played = False
+ self.player.discover_item(track, self._on_discovered, song_widget)
+ self.model.set(itr,
+ [0, 1, 2, 3, 4, 5],
+ [title, '', '', False,
+ NOW_PLAYING_ICON_NAME, track])
+ song_widget.now_playing_sign = ui.get_object('image1')
+ song_widget.now_playing_sign.set_from_icon_name(
+ NOW_PLAYING_ICON_NAME,
+ Gtk.IconSize.SMALL_TOOLBAR)
+ song_widget.now_playing_sign.set_no_show_all('True')
+ song_widget.now_playing_sign.set_alignment(1, 0.6)
+ song_widget.can_be_played = True
+ song_widget.connect('button-release-event',
+ self.track_selected)
+
self.ui.get_object('grid1').show_all()
def _update_album_art(self):
@@ -584,6 +577,9 @@ class ArtistAlbumWidget(Gtk.HBox):
self.ui.get_object('cover').set_from_pixbuf(pixbuf)
def track_selected(self, widget, _iter):
+ if not widget.can_be_played:
+ return
+
self.player.stop()
self.player.set_playlist('Artist', self.album,
widget.model, widget._iter, 5)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]