[rygel] media-export: Expose DVD images as playlists
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel] media-export: Expose DVD images as playlists
- Date: Sun, 3 Jan 2016 14:43:24 +0000 (UTC)
commit 81b3f5e0d4e5c2dc4493d5b46f45e6000180ef7a
Author: Jens Georg <mail jensge org>
Date: Wed Sep 9 15:38:49 2015 +0200
media-export: Expose DVD images as playlists
All titles are shown as items in the playlist contianer.
src/media-engines/gstreamer/rygel-gst-utils.vala | 2 +-
src/plugins/media-export/Makefile.am | 3 +-
.../rygel-media-export-dvd-container.vala | 178 ++++++++++++++++++++
.../rygel-media-export-dvd-parser.vala | 22 +--
.../media-export/rygel-media-export-extract.vala | 3 +-
.../rygel-media-export-info-serializer.vala | 2 +-
.../rygel-media-export-item-factory.vala | 13 +-
.../rygel-media-export-object-factory.vala | 13 +-
.../rygel-media-export-root-container.vala | 12 ++-
9 files changed, 221 insertions(+), 27 deletions(-)
---
diff --git a/src/media-engines/gstreamer/rygel-gst-utils.vala
b/src/media-engines/gstreamer/rygel-gst-utils.vala
index 20b7302..9934195 100644
--- a/src/media-engines/gstreamer/rygel-gst-utils.vala
+++ b/src/media-engines/gstreamer/rygel-gst-utils.vala
@@ -70,7 +70,7 @@ internal abstract class Rygel.GstUtils {
}
if (src.get_class ().find_property ("tcp-timeout") != null) {
- // For rtspsrc since some RTSP sources takes a while to start
+ // For rtspsrc since some RTSP sources takes a while to start
// transmitting
src.tcp_timeout = (int64) 60000000;
}
diff --git a/src/plugins/media-export/Makefile.am b/src/plugins/media-export/Makefile.am
index 37c720e..101e4cc 100644
--- a/src/plugins/media-export/Makefile.am
+++ b/src/plugins/media-export/Makefile.am
@@ -59,7 +59,8 @@ librygel_media_export_la_SOURCES = \
rygel-media-export-photo-item.vala \
rygel-media-export-playlist-item.vala \
rygel-media-export-trackable-db-container.vala \
- rygel-media-export-updatable-object.vala
+ rygel-media-export-updatable-object.vala \
+ rygel-media-export-dvd-container.vala
librygel_media_export_la_VALAFLAGS = \
--enable-experimental \
diff --git a/src/plugins/media-export/rygel-media-export-dvd-container.vala
b/src/plugins/media-export/rygel-media-export-dvd-container.vala
new file mode 100644
index 0000000..6e2de58
--- /dev/null
+++ b/src/plugins/media-export/rygel-media-export-dvd-container.vala
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+using Rygel;
+using Gee;
+
+internal class Rygel.MediaExport.DVDContainer : MediaContainer, UpdatableObject {
+ public new const string UPNP_CLASS = MediaContainer.PLAYLIST + ".DVD";
+ public const string PREFIX = "dvd";
+ public const string TRACK_PREFIX = "dvd-track";
+
+ public string path { get; construct set; }
+
+ private GUPnP.XMLDoc doc;
+
+ public DVDContainer (string id,
+ MediaContainer? parent,
+ string title,
+ string path) {
+ Object (id : id,
+ upnp_class : DVDContainer.UPNP_CLASS,
+ title : title,
+ parent : parent,
+ child_count : 0,
+ path : path);
+ }
+
+ public override void constructed () {
+ base.constructed ();
+
+ var cache_path = this.get_cache_path (this.path);
+ var doc = Xml.Parser.read_file (cache_path,
+ null,
+ Xml.ParserOption.NOERROR |
+ Xml.ParserOption.NOWARNING);
+ this.doc = new GUPnP.XMLDoc (doc);
+ var it = doc->get_root_element ()->children;
+ var child_count = 0;
+
+ while (it != null) {
+ if (it->name == "title") {
+ this.title = it->children->content;
+ } else if (it->name == "track") {
+ child_count++;
+ }
+
+ it = it->next;
+ }
+
+ this.child_count = child_count;
+ }
+
+ public override async MediaObjects? get_children (
+ uint offset,
+ uint max_count,
+ string sort_criteria,
+ Cancellable? cancellable)
+ throws Error {
+ var children = new MediaObjects ();
+
+ var context = new Xml.XPath.Context (this.doc.doc);
+ var xpo = context.eval ("/lsdvd/track");
+ if (xpo->type != Xml.XPath.ObjectType.NODESET) {
+ delete xpo;
+ warning ("No tracks found in DVD");
+
+ return children;
+ }
+
+ for (int i = 0; i < xpo->nodesetval->length (); i++) {
+ var node = xpo->nodesetval->item (i);
+ var item = this.get_item_for_xml (i, node);
+ children.add (item);
+ }
+
+ delete xpo;
+
+ return children;
+ }
+
+ public override async MediaObject? find_object (string id,
+ Cancellable? cancellable)
+ throws Error {
+ if (!id.has_prefix (DVDContainer.TRACK_PREFIX)) {
+ return null;
+ }
+
+ var parts = id.split (":");
+ var track = int.parse (parts[2]);
+ var context = new Xml.XPath.Context (this.doc.doc);
+ var xpo = context.eval ("/lsdvd/track");
+ if (!(xpo->type == Xml.XPath.ObjectType.NODESET &&
+ xpo->nodesetval->length () >= track)) {
+ delete xpo;
+
+ warning ("No track %s in DVD", parts[2]);
+
+ return null;
+ }
+
+ var object = this.get_item_for_xml (int.parse (parts[2]),
+ xpo->nodesetval->item (track));
+ delete xpo;
+
+ return object;
+ }
+
+ private string get_cache_path (string image_path) {
+ unowned string user_cache = Environment.get_user_cache_dir ();
+ var id = Checksum.compute_for_string (ChecksumType.MD5, image_path);
+ var cache_folder = Path.build_filename (user_cache,
+ "rygel",
+ "dvd-content");
+ DirUtils.create_with_parents (cache_folder, 0700);
+ return Path.build_filename (cache_folder, id);
+ }
+
+ public async void commit () throws Error {
+ yield this.commit_custom (true);
+ }
+
+ public async void commit_custom (bool override_guarded) throws Error {
+ MediaCache.get_default ().save_container (this);
+ }
+
+ private string get_track_id (int track) {
+ var parts = this.id.split (":");
+
+ parts[0] = "dvd-track";
+ parts += track.to_string ();
+
+ return string.joinv (":", parts);
+ }
+
+ private MediaFileItem get_item_for_xml (int track, Xml.Node *node) {
+ var item = new VideoItem (this.get_track_id (track),
+ this,
+ "Track %d".printf (track + 1));
+ item.parent_ref = this;
+
+ var uri = new Soup.URI (this.get_uris ()[0]);
+ uri.set_scheme ("dvd");
+ uri.set_query ("title=%d".printf (track + 1));
+ item.add_uri (uri.to_string (false));
+ var media_engine = MediaEngine.get_default ( );
+ media_engine.get_resources_for_item.begin ( item,
+ (obj, res) => {
+ var added_resources = media_engine
+ .get_resources_for_item.end (res);
+ debug ("Adding %d resources to item source %s",
+ added_resources.size, item.get_primary_uri ());
+ foreach (var resrc in added_resources) {
+ debug ("Media-export item media resource %s",
+ resrc.get_name ());
+ }
+ item.get_resource_list ().add_all (added_resources);
+ });
+
+ return item;
+ }
+}
diff --git a/src/plugins/media-export/rygel-media-export-dvd-parser.vala
b/src/plugins/media-export/rygel-media-export-dvd-parser.vala
index 522c9cd..087ef4a 100644
--- a/src/plugins/media-export/rygel-media-export-dvd-parser.vala
+++ b/src/plugins/media-export/rygel-media-export-dvd-parser.vala
@@ -29,29 +29,28 @@ internal class Rygel.DVDParser : GLib.Object {
public File file { public get; construct; }
private File cache_file;
- private string id;
public DVDParser (File file) {
Object (file : file);
}
- public override void constructed () {
+ public static string get_cache_path (string image_path) {
unowned string user_cache = Environment.get_user_cache_dir ();
- this.id = this.get_id (this.file);
+ var id = Checksum.compute_for_string (ChecksumType.MD5, image_path);
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);
+ return Path.build_filename (cache_folder, id);
+ }
- this.cache_file = File.new_for_path (cache_path);
+ public override void constructed () {
+ var path = DVDParser.get_cache_path (this.file.get_path ());
+ this.cache_file = File.new_for_path (path);
}
public async void run () throws Error {
- var doc = yield this.get_information ();
- if (doc != null) {
- doc->children;
- }
+ yield this.get_information ();
}
public async Xml.Doc* get_information () throws Error {
@@ -81,9 +80,4 @@ internal class Rygel.DVDParser : GLib.Object {
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 0410bac..5964d99 100644
--- a/src/plugins/media-export/rygel-media-export-extract.vala
+++ b/src/plugins/media-export/rygel-media-export-extract.vala
@@ -33,7 +33,8 @@ 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 UPNP_CLASS_PLAYLIST_CONTAINER_DVD =
+ "object.container.playlistContainer.DVD";
const string STATUS_LINE_TEMPLATE = "RESULT|%s|%" + size_t.FORMAT + "|%s\n";
const string ERROR_LINE_TEMPLATE = "ERROR|%s|%d|%s\n";
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 b24a556..c8cb786 100644
--- a/src/plugins/media-export/rygel-media-export-info-serializer.vala
+++ b/src/plugins/media-export/rygel-media-export-info-serializer.vala
@@ -88,7 +88,7 @@ internal class Rygel.InfoSerializer : GLib.Object {
} 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;
+ upnp_class = UPNP_CLASS_PLAYLIST_CONTAINER_DVD;
} else {
debug ("Unsupported content-type %s, skipping %s…",
mime,
diff --git a/src/plugins/media-export/rygel-media-export-item-factory.vala
b/src/plugins/media-export/rygel-media-export-item-factory.vala
index 0939787..a2207c0 100644
--- a/src/plugins/media-export/rygel-media-export-item-factory.vala
+++ b/src/plugins/media-export/rygel-media-export-item-factory.vala
@@ -100,10 +100,10 @@ namespace Rygel.MediaExport.ItemFactory {
}
}
- static MediaFileItem? create_from_variant (MediaContainer parent,
- File file,
- Variant v)
- throws Error {
+ static MediaObject? create_from_variant (MediaContainer parent,
+ File file,
+ Variant v)
+ throws Error {
ItemFactory.check_variant_type (v,"(smvmvmvmvmvmv)");
Variant? upnp_class,
@@ -151,6 +151,7 @@ namespace Rygel.MediaExport.ItemFactory {
}
MediaFileItem item = null;
+ MediaObject object = null;
switch (upnp_class.get_string ()) {
case Rygel.PhotoItem.UPNP_CLASS:
item = new PhotoItem (id, parent, "");
@@ -164,6 +165,10 @@ namespace Rygel.MediaExport.ItemFactory {
case Rygel.PlaylistItem.UPNP_CLASS:
item = ItemFactory.create_playlist_item (file, parent, "");
break;
+ case DVDContainer.UPNP_CLASS:
+ object = new DVDContainer ("dvd:" + id, parent, "", file.get_path ());
+ object.add_uri (file.get_uri ());
+ return object;
default:
return null;
}
diff --git a/src/plugins/media-export/rygel-media-export-object-factory.vala
b/src/plugins/media-export/rygel-media-export-object-factory.vala
index 4a60fcd..8b55abe 100644
--- a/src/plugins/media-export/rygel-media-export-object-factory.vala
+++ b/src/plugins/media-export/rygel-media-export-object-factory.vala
@@ -33,10 +33,10 @@ internal class Rygel.MediaExport.ObjectFactory : Object {
* @param title title of the container
* @param child_count number of children in the container
*/
- public virtual DBContainer get_container (string id,
- string title,
- uint child_count,
- string? uri) {
+ public virtual MediaContainer get_container (string id,
+ string title,
+ uint child_count,
+ string? uri) {
if (id == "0") {
return RootContainer.get_instance ();
} else if (id == RootContainer.FILESYSTEM_FOLDER_ID) {
@@ -65,6 +65,11 @@ internal class Rygel.MediaExport.ObjectFactory : Object {
return new TrackableDbContainer (id, title);
}
+ if (id.has_prefix ("dvd:")) {
+ var file = File.new_for_uri (uri);
+ return new DVDContainer (id, null, title, file.get_path ());
+ }
+
if (id.has_prefix ("playlist:")) {
return new PlaylistContainer (id, title);
}
diff --git a/src/plugins/media-export/rygel-media-export-root-container.vala
b/src/plugins/media-export/rygel-media-export-root-container.vala
index a9ed65c..9bfbd80 100644
--- a/src/plugins/media-export/rygel-media-export-root-container.vala
+++ b/src/plugins/media-export/rygel-media-export-root-container.vala
@@ -94,7 +94,17 @@ public class Rygel.MediaExport.RootContainer : TrackableDbContainer {
return object;
}
- if (id.has_prefix (QueryContainer.PREFIX)) {
+ if (id.has_prefix (DVDContainer.TRACK_PREFIX)) {
+ var parts = id.split (":");
+ var parent_id = DVDContainer.PREFIX + ":" + parts[1];
+ object = yield base.find_object (parent_id, cancellable);
+ var container = object as MediaContainer;
+ if (container != null) {
+ return yield container.find_object (id, cancellable);
+ }
+
+ return null;
+ } else if (id.has_prefix (QueryContainer.PREFIX)) {
var factory = QueryContainerFactory.get_default ();
var container = factory.create_from_hashed_id (id);
if (container != null) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]