[pitivi] medialibrary: Automatically generate missing thumbnails
- From: Jean-François Fortin Tam <jfft src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] medialibrary: Automatically generate missing thumbnails
- Date: Sat, 4 Jan 2014 17:11:09 +0000 (UTC)
commit bf95c041c774eacc877b94fb2e6a3d18c2436868
Author: Jean-François Fortin Tam <nekohayo gmail com>
Date: Mon Dec 16 20:53:24 2013 -0500
medialibrary: Automatically generate missing thumbnails
Completes the solution for bug #432661
pitivi/check.py | 4 ++-
pitivi/medialibrary.py | 85 ++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 85 insertions(+), 4 deletions(-)
---
diff --git a/pitivi/check.py b/pitivi/check.py
index 54afc21..6d15bac 100644
--- a/pitivi/check.py
+++ b/pitivi/check.py
@@ -38,9 +38,11 @@ from gettext import gettext as _
# Unless otherwise noted, modules are accessed through gobject introspection
HARD_DEPS = {
"cairo": "1.10.0", # using static python bindings
- "GES": "1.0.0.0", # packagers: in reality 1.1.90, but that GES version erronously reports itself as
1.0.0.0
"Clutter": "1.12.0",
+ "GES": "1.0.0.0", # packagers: in reality 1.1.90, but that GES version erronously reports itself as
1.0.0.0
+ "Gio": None,
"gnonlin": "1.1.90",
+ "GnomeDesktop": None,
"Gst": "1.2.0",
"Gtk": "3.8.0",
"numpy": None, # using static python bindings
diff --git a/pitivi/medialibrary.py b/pitivi/medialibrary.py
index d927ebf..c08ef25 100644
--- a/pitivi/medialibrary.py
+++ b/pitivi/medialibrary.py
@@ -24,7 +24,9 @@
from gi.repository import Gst
from gi.repository import GES
+from gi.repository import Gio
from gi.repository import GLib
+from gi.repository import GnomeDesktop
from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import Gdk
@@ -46,7 +48,7 @@ from pitivi.mediafilespreviewer import PreviewWidget
from pitivi.dialogs.filelisterrordialog import FileListErrorDialog
from pitivi.dialogs.clipmediaprops import clipmediapropsDialog
from pitivi.utils.ui import beautify_length
-from pitivi.utils.misc import PathWalker, quote_uri
+from pitivi.utils.misc import PathWalker, quote_uri, path_from_uri
from pitivi.utils.signal import SignalGroup
from pitivi.utils.loggable import Loggable
import pitivi.utils.ui as dnd
@@ -132,6 +134,7 @@ class MediaLibraryWidget(Gtk.VBox, Loggable):
self.app = instance
self._errors = []
+ self._missing_thumbs = []
self._project = None
self._draggedPaths = None
self.dragged = False
@@ -534,6 +537,72 @@ class MediaLibraryWidget(Gtk.VBox, Loggable):
except GLib.GError:
return None, None
+ def _gen_missing_thumbs(self, thumbnailer):
+ # Some benchmarks to ensure that naïvely looping the model isn't too bad
+ start_time = time.time()
+ time_spent_generating_thumbs = 0.0
+ time_spent_searching_model = 0.0
+ time_spent_updating_model = 0.0
+ amount_of_thumbs_total = len(self._missing_thumbs)
+ amount_of_thumbs_processed = 0
+
+ for uri in self._missing_thumbs:
+ # This way of getting the mimetype feels awfully convoluted but
+ # seems to be the proper/reliable way in a GNOME context
+ _file = Gio.file_new_for_uri(uri)
+ _info = _file.query_info(attributes="standard::*",
+ flags=Gio.FileQueryInfoFlags.NONE,
+ cancellable=None)
+ mime = Gio.content_type_get_mime_type(_info.get_content_type())
+
+ mtime = os.path.getmtime(path_from_uri(uri))
+
+ _lap_start = time.time() # for benchmarking
+ if thumbnailer.can_thumbnail(uri, mime, mtime):
+ pixbuf_128 = thumbnailer.generate_thumbnail(uri, mime)
+ if pixbuf_128:
+ thumbnailer.save_thumbnail(pixbuf_128, uri, mtime)
+ # We also want the "64 pixels" version, can't use
+ # desktop_thumbnail_scale_down_pixbuf 'cause it doesn't
+ # keep aspect ratio. Screw that, 64² will appear on restart.
+ time_spent_generating_thumbs += (time.time() - _lap_start)
+
+ # Now search through the model
+ _lap2_start = time.time()
+ _found = False
+ for row in self.storemodel:
+ if uri == row[COL_URI]:
+ _found = True
+ time_spent_searching_model += (time.time() - _lap2_start)
+ # Finally, show the new pixbuf in the UI
+ _lap3_start = time.time()
+ row[COL_ICON_128] = pixbuf_128
+ time_spent_updating_model += (time.time() - _lap3_start)
+ amount_of_thumbs_processed += 1
+ break
+
+ if not _found:
+ # Should not ever happen, but who knows...
+ self.error("%s needed a thumbnail, but vanished from storemodel", uri)
+ time_spent_searching_model += (time.time() - _lap2_start)
+
+ else:
+ self.debug("Failed creating a thumbnail for %s", uri)
+ else:
+ self.debug("Thumbnailer says it can't thumbnail %s", uri)
+
+ # Don't iteratively remove items of the list you're looping onto, fool:
+ self._missing_thumbs = []
+
+ # Report the results of the benchmarks
+ self.info("%d/%d thumbs created (%.3fs to generate, "
+ "%.4fs to search the model, %.4fs to insert)",
+ amount_of_thumbs_processed,
+ amount_of_thumbs_total,
+ time_spent_generating_thumbs,
+ time_spent_searching_model,
+ time_spent_updating_model)
+
def _addAsset(self, asset):
# 128 is the normal size for thumbnails, but for *icons* it looks insane
LARGE_SIZE = 96
@@ -549,7 +618,8 @@ class MediaLibraryWidget(Gtk.VBox, Loggable):
# $XDG_CACHE_HOME/thumbnails will be used, otherwise
# $HOME/.cache/thumbnails will be used."
# Older version of the spec also mentioned $HOME/.thumbnails
- thumbnail_hash = md5(quote_uri(info.get_uri())).hexdigest()
+ quoted_uri = quote_uri(info.get_uri())
+ thumbnail_hash = md5(quoted_uri).hexdigest()
try:
thumb_dir = os.environ['XDG_CACHE_HOME']
thumb_64, thumb_128 = self._getThumbnailInDir(thumb_dir, thumbnail_hash)
@@ -562,13 +632,15 @@ class MediaLibraryWidget(Gtk.VBox, Loggable):
thumb_dir = os.path.expanduser("~/.thumbnails/")
thumb_64, thumb_128 = self._getThumbnailInDir(thumb_dir, thumbnail_hash)
if thumb_64 is None:
- # TODO gst discoverer should create missing thumbnails.
if asset.is_image():
thumb_64 = self._getIcon("image-x-generic")
thumb_128 = self._getIcon("image-x-generic", None, LARGE_SIZE)
else:
thumb_64 = self._getIcon("video-x-generic")
thumb_128 = self._getIcon("video-x-generic", None, LARGE_SIZE)
+ # TODO ideally gst discoverer should create missing thumbnails.
+ self.log("Missing a thumbnail for %s, queuing", path_from_uri(quoted_uri))
+ self._missing_thumbs.append(quoted_uri)
else:
thumb_64 = self._getIcon("audio-x-generic")
thumb_128 = self._getIcon("audio-x-generic", None, LARGE_SIZE)
@@ -649,6 +721,13 @@ class MediaLibraryWidget(Gtk.VBox, Loggable):
self._warning_label.set_text(text)
self._import_warning_infobar.show_all()
+ if self._missing_thumbs:
+ self.info("%d thumbnails are missing, we will generate them", len(self._missing_thumbs))
+ # We need to instanciate the thumbnail factory on the main thread...
+ _size_normal = GnomeDesktop.DesktopThumbnailSize.NORMAL
+ thumbnailer = GnomeDesktop.DesktopThumbnailFactory.new(_size_normal)
+ self._gen_missing_thumbs(thumbnailer)
+
## Error Dialog Box callbacks
def _errorDialogBoxCloseCb(self, dialog):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]