[rygel] core: Add Thumbnailer



commit 3643750e7db7064eda422272e47f0a4fa995d392
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Tue Sep 8 16:07:51 2009 +0300

    core: Add Thumbnailer
    
    At the moment, it doesn't generate any thumbnails but serves existing
    thumbnails provided by either GNOME apps or hildon-thumbnailer. While
    former is good for desktop-integration the later is not only good for
    maemo-integration but is also DLNA-compliant since DLNA requires
    thumbnails to be provided at least in JPEG format.

 src/rygel/Makefile.am            |    1 +
 src/rygel/rygel-http-server.vala |   38 +++++++++++++++
 src/rygel/rygel-thumbnailer.vala |   94 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 133 insertions(+), 0 deletions(-)
---
diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am
index 85d42a3..47834ba 100644
--- a/src/rygel/Makefile.am
+++ b/src/rygel/Makefile.am
@@ -67,6 +67,7 @@ VAPI_SOURCE_FILES = rygel-configuration.vala \
 		    rygel-simple-async-result.vala \
 		    rygel-media-item.vala \
 		    rygel-thumbnail.vala \
+		    rygel-thumbnailer.vala \
 		    rygel-browse.vala \
 		    rygel-didl-lite-writer.vala \
 		    rygel-transcoder.vala \
diff --git a/src/rygel/rygel-http-server.vala b/src/rygel/rygel-http-server.vala
index 0a2bc07..6e470a2 100644
--- a/src/rygel/rygel-http-server.vala
+++ b/src/rygel/rygel-http-server.vala
@@ -33,6 +33,7 @@ internal class Rygel.HTTPServer : Rygel.TranscodeManager, Rygel.StateMachine {
     public MediaContainer root_container;
     public GUPnP.Context context;
     private ArrayList<HTTPRequest> requests;
+    private Thumbnailer thumbnailer;
 
     private Cancellable cancellable;
 
@@ -45,6 +46,14 @@ internal class Rygel.HTTPServer : Rygel.TranscodeManager, Rygel.StateMachine {
         this.requests = new ArrayList<HTTPRequest> ();
 
         this.path_root = SERVER_PATH_PREFIX + "/" + name;
+
+        try {
+            this.thumbnailer = new Thumbnailer ();
+            this.context.host_path (thumbnailer.directory,
+                                    this.path_root + "/thumbnails");
+        } catch (ThumbnailerError err) {
+            warning ("No thumbnailer available: %s", err.message);
+        }
     }
 
     public void run (Cancellable? cancellable) {
@@ -74,6 +83,35 @@ internal class Rygel.HTTPServer : Rygel.TranscodeManager, Rygel.StateMachine {
         base.add_resources (didl_item, item);
 
         // Thumbnails comes in the end
+        if (item.upnp_class.has_prefix (MediaItem.IMAGE_CLASS) ||
+            item.upnp_class.has_prefix (MediaItem.VIDEO_CLASS) &&
+            item.thumbnails.size == 0) {
+            // Lets see if we can provide the thumbnails
+            if (this.thumbnailer != null) {
+                foreach (var uri in item.uris) {
+                    Thumbnail thumbnail = null;
+
+                    try {
+                        thumbnail = this.thumbnailer.get_thumbnail (uri);
+                        thumbnail.add_resource (didl_item, "internal");
+
+                        // Now create the HTTP URI
+                        var basename = Path.get_basename (thumbnail.path);
+                        thumbnail.uri = this.create_uri_for_path (
+                                                    "/thumbnails/" + basename);
+                        thumbnail.add_resource (didl_item,
+                                                this.get_protocol ());
+                    } catch (ThumbnailerError err) {}
+
+                    // No error means we found the thumbnail
+                    break;
+                }
+            }
+
+            return; // We won't be here if there were thumbnails provided by
+                    // the item itself
+        }
+
         foreach (var thumbnail in item.thumbnails) {
             if (!is_http_uri (thumbnail.uri)) {
                 var uri = thumbnail.uri; // Save the original URI
diff --git a/src/rygel/rygel-thumbnailer.vala b/src/rygel/rygel-thumbnailer.vala
new file mode 100644
index 0000000..40ae3dc
--- /dev/null
+++ b/src/rygel/rygel-thumbnailer.vala
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008 Zeeshan Ali <zeenix gmail com>.
+ *
+ * Author: Zeeshan Ali <zeenix gmail com>
+ *
+ * This file is part of Rygel.
+ *
+ * Rygel is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Rygel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+using Gst;
+
+internal errordomain ThumbnailerError {
+    NO_DIR,
+    NO_THUMBNAIL
+}
+
+/**
+ * Provides thumbnails for images and vidoes.
+ */
+internal class Rygel.Thumbnailer : GLib.Object {
+    public string directory;
+
+    private Thumbnail template;
+    private string extension;
+
+    public Thumbnailer () throws ThumbnailerError {
+        var dir = Path.build_filename (Environment.get_home_dir (),
+                                       ".thumbnails",
+                                       "cropped");
+        var file = File.new_for_path (dir);
+        this.template = new Thumbnail ();
+
+        if (!file.query_exists (null)) {
+            dir = Path.build_filename (Environment.get_home_dir (),
+                                       ".thumbnails",
+                                       "normal");
+            file = File.new_for_path (dir);
+
+            if (!file.query_exists (null)) {
+                throw new ThumbnailerError.NO_DIR (
+                                        "Failed to find thumbnails directory");
+            } else {
+                this.template.mime_type = "image/png";
+                this.template.dlna_profile = "PNG_TN";
+                this.template.width = 128;
+                this.template.height = 128;
+                this.template.depth = 32;
+                this.extension = ".png";
+            }
+        } else {
+            this.template.width = 124;
+            this.template.height = 124;
+            this.template.depth = 24;
+            this.extension = ".jpg";
+        }
+
+        this.directory = dir;
+    }
+
+    public Thumbnail get_thumbnail (string uri) throws ThumbnailerError {
+        Thumbnail thumbnail = null;
+
+        var path = Checksum.compute_for_string (ChecksumType.MD5, uri) +
+                   this.extension;
+        var full_path = Path.build_filename (this.directory, path);
+        var file = File.new_for_path (full_path);
+
+        if (!file.query_exists (null)) {
+            throw new ThumbnailerError.NO_THUMBNAIL ("No thumbnail available");
+        }
+
+        thumbnail = new Thumbnail ();
+        thumbnail.width = this.template.width;
+        thumbnail.height = this.template.height;
+        thumbnail.depth = this.template.depth;
+        thumbnail.path = path;
+        thumbnail.uri = Filename.to_uri (full_path, null);
+
+        return thumbnail;
+    }
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]