[rygel] media-export: Query DVD structure information



commit 3fac7ac8ce0dc9b63e4c4a4d2b09b93c480e10f9
Author: Jens Georg <jensg openismus com>
Date:   Sun Jul 14 14:55:12 2013 +0200

    media-export: Query DVD structure information
    
    Use lsdvd binary and its XML output for this to avoid effective GPL
    relicensing by using libdvdread explicitly.
    
    The output is cached so we only have to do this once ideally.

 configure.ac                                       |    1 +
 src/plugins/media-export/Makefile.am               |    3 +-
 .../rygel-media-export-dvd-parser.vala             |   89 ++++++++++++++++++++
 .../media-export/rygel-media-export-extract.vala   |   17 +++-
 .../media-export/rygel-media-export-harvester.vala |    4 +-
 .../rygel-media-export-info-serializer.vala        |    2 +
 6 files changed, 108 insertions(+), 8 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index c71a701..89557c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -260,6 +260,7 @@ AS_IF([test "x$with_media_engine" = "xgstreamer"],
                                gstreamer-pbutils-1.0 >= $GSTPBU_REQUIRED
                                libsoup-2.4 >= $LIBSOUP_REQUIRED
                                sqlite3 >= $LIBSQLITE3_REQUIRED
+                               libxml-2.0 >= $LIBXML_REQUIRED
                                libmediaart-2.0 >= $MEDIAART_REQUIRED])
             RYGEL_PLUGIN_MEDIA_EXPORT_DEPS_VALAFLAGS="$RYGEL_COMMON_MODULES_VALAFLAGS --pkg gupnp-dlna-2.0 
--pkg gupnp-dlna-gst-2.0 --pkg gstreamer-tag-1.0 --pkg gstreamer-app-1.0 --pkg gstreamer-pbutils-1.0 --pkg 
sqlite3 --pkg libmediaart-2.0"
             AC_SUBST([RYGEL_PLUGIN_MEDIA_EXPORT_DEPS_VALAFLAGS])
diff --git a/src/plugins/media-export/Makefile.am b/src/plugins/media-export/Makefile.am
index f77fa8a..37c720e 100644
--- a/src/plugins/media-export/Makefile.am
+++ b/src/plugins/media-export/Makefile.am
@@ -10,7 +10,8 @@ include $(top_srcdir)/common.am
 pkglibexec_PROGRAMS = mx-extract
 mx_extract_SOURCES = \
        rygel-media-export-extract.vala \
-       rygel-media-export-info-serializer.vala
+       rygel-media-export-info-serializer.vala \
+       rygel-media-export-dvd-parser.vala
 
 mx_extract_VALAFLAGS = \
        --enable-experimental \
diff --git a/src/plugins/media-export/rygel-media-export-dvd-parser.vala 
b/src/plugins/media-export/rygel-media-export-dvd-parser.vala
new file mode 100644
index 0000000..522c9cd
--- /dev/null
+++ b/src/plugins/media-export/rygel-media-export-dvd-parser.vala
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2013,2015 Jens Georg <mail jensge org>.
+ *
+ * Author: Jens Georg <mail jensge org>
+ *
+ * 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.
+ */
+
+internal errordomain DVDParserError {
+    GENERAL;
+}
+
+internal class Rygel.DVDParser : GLib.Object {
+    /// URI to the image / toplevel directory
+    public File file { public get; construct; }
+
+    private File cache_file;
+    private string id;
+
+    public DVDParser (File file) {
+        Object (file : file);
+    }
+
+    public override void constructed () {
+        unowned string user_cache = Environment.get_user_cache_dir ();
+        this.id = this.get_id (this.file);
+        var cache_folder = Path.build_filename (user_cache,
+                                                "rygel",
+                                                "dvd-content");
+        DirUtils.create_with_parents (cache_folder, 0700);
+        var cache_path = Path.build_filename (cache_folder, this.id);
+
+        this.cache_file = File.new_for_path (cache_path);
+    }
+
+    public async void run () throws Error {
+        var doc = yield this.get_information ();
+        if (doc != null) {
+            doc->children;
+        }
+    }
+
+    public async Xml.Doc* get_information () throws Error {
+        if (!this.cache_file.query_exists ()) {
+            var launcher = new SubprocessLauncher (SubprocessFlags.STDERR_SILENCE);
+            launcher.set_stdout_file_path (this.cache_file.get_path ());
+            string[] args = {
+                "/usr/bin/lsdvd",
+                "-Ox",
+                "-x",
+                "-q",
+                this.file.get_path (),
+                null
+            };
+
+            var process = launcher.spawnv (args);
+            yield process.wait_async ();
+
+            if (!(process.get_if_exited () &&
+                process.get_exit_status () == 0)) {
+                throw new DVDParserError.GENERAL ("lsdvd did die or file is not a DVD");
+            }
+        }
+
+        return Xml.Parser.read_file (this.cache_file.get_path (),
+                                     null,
+                                     Xml.ParserOption.NOERROR |
+                                     Xml.ParserOption.NOWARNING);
+    }
+
+    private string get_id (File file) {
+        return Checksum.compute_for_string (ChecksumType.MD5,
+                                            file.get_uri ());
+    }
+}
diff --git a/src/plugins/media-export/rygel-media-export-extract.vala 
b/src/plugins/media-export/rygel-media-export-extract.vala
index 2022a34..0410bac 100644
--- a/src/plugins/media-export/rygel-media-export-extract.vala
+++ b/src/plugins/media-export/rygel-media-export-extract.vala
@@ -33,6 +33,7 @@ const string UPNP_CLASS_PHOTO = "object.item.imageItem.photo";
 const string UPNP_CLASS_MUSIC = "object.item.audioItem.musicTrack";
 const string UPNP_CLASS_VIDEO = "object.item.videoItem";
 const string UPNP_CLASS_PLAYLIST = "object.item.playlistItem";
+const string UPNP_CLASS_PLAYLIST_CONTAINER = "object.container.playlistContainer";
 
 const string STATUS_LINE_TEMPLATE = "RESULT|%s|%" + size_t.FORMAT + "|%s\n";
 const string ERROR_LINE_TEMPLATE = "ERROR|%s|%d|%s\n";
@@ -101,12 +102,18 @@ async void run () {
                     GLib.Memory.copy (last_uri.data,
                                       (void *) parts[0],
                                       parts[0].length);
-                    var is_text = parts[1].has_prefix ("text/") ||
-                                  parts[1].has_suffix ("xml");
-                    if (metadata && !is_text) {
-                        info = discoverer.discover_uri (parts[0]);
-
-                        debug ("Finished discover on URI %s", parts[0]);
+                    if (metadata) {
+                        var is_text = parts[1].has_prefix ("text/") ||
+                                      parts[1].has_suffix ("xml");
+                        if (parts[1] == "application/x-cd-image") {
+                            var file = File.new_for_uri (parts[0]);
+                            var parser = new Rygel.DVDParser (file);
+                            yield parser.run ();
+                        } else if (!is_text) {
+                            info = discoverer.discover_uri (parts[0]);
+
+                            debug ("Finished discover on URI %s", parts[0]);
+                        }
                     }
                     yield process_meta_data (parts[0], info);
                 } catch (Error error) {
diff --git a/src/plugins/media-export/rygel-media-export-harvester.vala 
b/src/plugins/media-export/rygel-media-export-harvester.vala
index f7107f0..a4f20d4 100644
--- a/src/plugins/media-export/rygel-media-export-harvester.vala
+++ b/src/plugins/media-export/rygel-media-export-harvester.vala
@@ -74,8 +74,8 @@ internal class Rygel.MediaExport.Harvester : GLib.Object {
             info.get_content_type () == "application/ogg" ||
             info.get_content_type () == "application/xml" ||
             info.get_content_type () == "text/xml" ||
-            info.get_content_type () == "text/plain";
-
+            info.get_content_type () == "text/plain" ||
+            info.get_content_type () == "application/x-cd-image";
         var cache = MediaCache.get_default ();
         var is_blacklisted = cache.is_blacklisted (file);
 
diff --git a/src/plugins/media-export/rygel-media-export-info-serializer.vala 
b/src/plugins/media-export/rygel-media-export-info-serializer.vala
index 796086f..b24a556 100644
--- a/src/plugins/media-export/rygel-media-export-info-serializer.vala
+++ b/src/plugins/media-export/rygel-media-export-info-serializer.vala
@@ -87,6 +87,8 @@ internal class Rygel.InfoSerializer : GLib.Object {
                 upnp_class = UPNP_CLASS_MUSIC;
             } else if (mime.has_suffix ("/xml")) { // application/xml or text/xml
                 upnp_class = UPNP_CLASS_PLAYLIST;
+            } else if (mime == "application/x-cd-image") {
+                upnp_class = UPNP_CLASS_PLAYLIST_CONTAINER;
             } else {
                 debug ("Unsupported content-type %s, skipping %s…",
                        mime,


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