[rygel] core,plugins: Proper, rich item hierarchy
- From: Zeeshan Ali Khattak <zeeshanak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel] core,plugins: Proper, rich item hierarchy
- Date: Wed, 25 Aug 2010 14:45:35 +0000 (UTC)
commit aaf25fb2c2e79dac1d3ec43bad2b5dd58f541e0d
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date: Wed Aug 25 15:06:41 2010 +0300
core,plugins: Proper, rich item hierarchy
* We have the following item hierarchy now:
* VisualItem (interface, requires MediaItem)
* MediaItem (abstract class)
|
|--> AudioItem
| |
| |--> MusicItem
| |--> VideoItem (implements VisualItem)
|
|--> ImageItem (implements VisualItem)
|
|--> PhotoItem
* Serialization of MediaItem is completely handled by MediaItem itself.
po/POTFILES.in | 8 +-
po/POTFILES.skip | 6 +
.../external/rygel-external-item-factory.vala | 106 +++++--
src/plugins/gst-launch/Makefile.am | 4 +-
.../rygel-gst-launch-audio-item.vala} | 33 +-
src/plugins/gst-launch/rygel-gst-launch-item.vala | 30 +--
.../rygel-gst-launch-root-container.vala | 18 +-
.../rygel-gst-launch-video-item.vala} | 33 +-
.../rygel-media-export-harvesting-task.vala | 4 +-
.../media-export/rygel-media-export-item.vala | 337 ++++++++++----------
.../rygel-media-export-media-cache.vala | 102 +++++--
.../rygel-media-export-object-factory.vala | 11 +-
.../mediathek/rygel-mediathek-video-item.vala | 9 +-
src/plugins/test/Makefile.am | 1 -
src/plugins/test/rygel-test-audio-item.vala | 10 +-
src/plugins/test/rygel-test-video-item.vala | 10 +-
.../tracker/rygel-tracker-item-factory.vala | 18 +-
.../tracker/rygel-tracker-music-item-factory.vala | 33 ++-
.../rygel-tracker-picture-item-factory.vala | 27 ++-
.../tracker/rygel-tracker-video-item-factory.vala | 25 +-
src/rygel/Makefile.am | 6 +
src/rygel/rygel-audio-item.vala | 67 ++++
src/rygel/rygel-didl-lite-writer.vala | 59 +----
src/rygel/rygel-http-get-handler.vala | 4 +-
src/rygel/rygel-http-get.vala | 23 ++-
src/rygel/rygel-http-server.vala | 53 +---
src/rygel/rygel-http-time-seek.vala | 5 +-
src/rygel/rygel-image-item.vala | 99 ++++++
src/rygel/rygel-item-creator.vala | 46 ++-
src/rygel/rygel-l16-transcoder.vala | 17 +-
src/rygel/rygel-media-art-store.vala | 22 +-
src/rygel/rygel-media-container.vala | 8 +-
src/rygel/rygel-media-item.vala | 212 +++++--------
src/rygel/rygel-mp2ts-transcoder.vala | 29 +-
src/rygel/rygel-mp3-transcoder.vala | 9 +-
src/rygel/rygel-music-item.vala | 129 ++++++++
src/rygel/rygel-photo-item.vala | 67 ++++
src/rygel/rygel-relational-expression.vala | 6 +-
src/rygel/rygel-transcode-manager.vala | 5 +-
src/rygel/rygel-transcoder.vala | 2 +-
src/rygel/rygel-video-item.vala | 153 +++++++++
src/rygel/rygel-visual-item.vala | 90 ++++++
src/rygel/rygel-wma-transcoder.vala | 9 +-
src/rygel/rygel-wmv-transcoder.vala | 15 +-
44 files changed, 1304 insertions(+), 656 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0c7bc32..4e9f587 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -37,7 +37,7 @@ src/plugins/media-export/rygel-media-export-query-container.vala
src/plugins/media-export/rygel-media-export-recursive-file-monitor.vala
src/plugins/media-export/rygel-media-export-root-container.vala
src/plugins/test/rygel-test-audio-item.vala
-src/plugins/test/rygel-test-item.vala
+src/plugins/test/rygel-test-video-item.vala
src/plugins/test/rygel-test-plugin.vala
src/plugins/test/rygel-test-root-container.vala
src/plugins/test/rygel-test-video-item.vala
@@ -100,6 +100,12 @@ src/rygel/rygel-logical-expression.vala
src/rygel/rygel-main.vala
src/rygel/rygel-media-container.vala
src/rygel/rygel-media-item.vala
+src/rygel/rygel-music-item.vala
+src/rygel/rygel-audio-item.vala
+src/rygel/rygel-image-item.vala
+src/rygel/rygel-photo-item.vala
+src/rygel/rygel-video-item.vala
+src/rygel/rygel-visual-item.vala
src/rygel/rygel-media-object.vala
src/rygel/rygel-media-receiver-registrar.vala
src/rygel/rygel-meta-config.vala
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index f6c4b45..c389cb3 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -59,6 +59,12 @@ src/rygel/rygel-log-handler.c
src/rygel/rygel-main.c
src/rygel/rygel-media-container.c
src/rygel/rygel-media-item.c
+src/rygel/rygel-music-item.c
+src/rygel/rygel-audio-item.c
+src/rygel/rygel-image-item.c
+src/rygel/rygel-photo-item.c
+src/rygel/rygel-video-item.c
+src/rygel/rygel-visual-item.c
src/rygel/rygel-meta-config.c
src/rygel/rygel-metadata-extractor.c
src/rygel/rygel-mp2ts-transcoder-bin.c
diff --git a/src/plugins/external/rygel-external-item-factory.vala b/src/plugins/external/rygel-external-item-factory.vala
index ce67df7..f83bca9 100644
--- a/src/plugins/external/rygel-external-item-factory.vala
+++ b/src/plugins/external/rygel-external-item-factory.vala
@@ -38,19 +38,38 @@ public class Rygel.External.ItemFactory {
string host_ip,
MediaContainer parent)
throws GLib.Error {
- string upnp_class;
+ MediaItem item;
if (type.has_prefix ("audio")) {
- upnp_class = MediaItem.AUDIO_CLASS;
+ item = new AudioItem (id, parent, title);
+
+ this.set_audio_metadata (item as AudioItem,
+ props,
+ service_name,
+ host_ip);
} else if (type.has_prefix ("music")) {
- upnp_class = MediaItem.MUSIC_CLASS;
+ item = new MusicItem (id, parent, title);
+
+ yield this.set_music_metadata (item as MusicItem,
+ props,
+ service_name,
+ host_ip);
} else if (type.has_prefix ("video")) {
- upnp_class = MediaItem.VIDEO_CLASS;
+ item = new VideoItem (id, parent, title);
+
+ yield this.set_video_metadata (item as VideoItem,
+ props,
+ service_name,
+ host_ip);
} else {
- upnp_class = MediaItem.IMAGE_CLASS;
+ item = new ImageItem (id, parent, title);
+
+ yield this.set_visual_metadata (item as VisualItem,
+ props,
+ service_name,
+ host_ip);
}
- var item = new MediaItem (id, parent, title, upnp_class);
if (parent is DummyContainer) {
item.parent_ref = parent;
}
@@ -75,45 +94,74 @@ public class Rygel.External.ItemFactory {
item.size = (int64) value;
}
- item.author = this.get_string (props, "Artist");
- item.album = this.get_string (props, "Album");
- item.genre = this.get_string (props, "Genre");
item.date = this.get_string (props, "Date");
- // Properties specific to video and audio/music
-
- item.duration = this.get_int (props, "Duration");
- item.bitrate = this.get_int (props, "Bitrate");
- item.sample_freq = this.get_int (props, "SampleRate");
- item.bits_per_sample = this.get_int (props, "BitsPerSample");
+ return item;
+ }
- value = props.lookup ("AlbumArt");
+ private async void set_music_metadata (
+ MusicItem music,
+ HashTable<string,Value?> props,
+ string service_name,
+ string host_ip)
+ throws GLib.Error {
+ music.artist = this.get_string (props, "Artist");
+ music.album = this.get_string (props, "Album");
+ music.genre = this.get_string (props, "Genre");
+
+ var value = props.lookup ("AlbumArt");
if (value != null) {
var cover_factory = new AlbumArtFactory ();
- var album_art = yield cover_factory.create ((string) value,
- service_name,
- host_ip);
- item.thumbnails.add (album_art);
+
+ music.album_art = yield cover_factory.create ((string) value,
+ service_name,
+ host_ip);
}
- // Properties specific to video and image
+ this.set_audio_metadata (music, props, service_name, host_ip);
+ }
- item.width = this.get_int (props, "Width");
- item.height = this.get_int (props, "Height");
- item.color_depth = this.get_int (props, "ColorDepth");
- item.pixel_width = this.get_int (props, "PixelWidth");
- item.pixel_height = this.get_int (props, "PixelHeight");
+ private void set_audio_metadata (AudioItem audio,
+ HashTable<string,Value?> props,
+ string service_name,
+ string host_ip)
+ throws GLib.Error {
+ audio.duration = this.get_int (props, "Duration");
+ audio.bitrate = this.get_int (props, "Bitrate");
+ audio.sample_freq = this.get_int (props, "SampleRate");
+ audio.bits_per_sample = this.get_int (props, "BitsPerSample");
+ }
- value = props.lookup ("Thumbnail");
+ private async void set_visual_metadata (
+ VisualItem visual,
+ HashTable<string,Value?> props,
+ string service_name,
+ string host_ip)
+ throws GLib.Error {
+ visual.width = this.get_int (props, "Width");
+ visual.height = this.get_int (props, "Height");
+ visual.color_depth = this.get_int (props, "ColorDepth");
+ visual.pixel_width = this.get_int (props, "PixelWidth");
+ visual.pixel_height = this.get_int (props, "PixelHeight");
+
+ var value = props.lookup ("Thumbnail");
if (value != null) {
var factory = new ThumbnailFactory ();
var thumbnail = yield factory.create ((string) value,
service_name,
host_ip);
- item.thumbnails.add (thumbnail);
+ visual.thumbnails.add (thumbnail);
}
+ }
- return item;
+ private async void set_video_metadata (
+ VideoItem video,
+ HashTable<string,Value?> props,
+ string service_name,
+ string host_ip)
+ throws GLib.Error {
+ yield this.set_visual_metadata (video, props, service_name, host_ip);
+ this.set_audio_metadata (video, props, service_name, host_ip);
}
private string? get_string (HashTable<string,Value?> props, string prop) {
diff --git a/src/plugins/gst-launch/Makefile.am b/src/plugins/gst-launch/Makefile.am
index 575d925..06312b5 100644
--- a/src/plugins/gst-launch/Makefile.am
+++ b/src/plugins/gst-launch/Makefile.am
@@ -14,7 +14,9 @@ AM_CFLAGS = $(LIBGUPNP_CFLAGS) \
librygel_gst_launch_la_SOURCES = rygel-gst-launch-plugin.vala \
rygel-gst-launch-root-container.vala \
- rygel-gst-launch-item.vala
+ rygel-gst-launch-item.vala \
+ rygel-gst-launch-audio-item.vala \
+ rygel-gst-launch-video-item.vala
librygel_gst_launch_la_VALAFLAGS = --vapidir=$(top_srcdir)/src/rygel \
--pkg rygel-1.0 --pkg gconf-2.0 \
diff --git a/src/plugins/test/rygel-test-item.vala b/src/plugins/gst-launch/rygel-gst-launch-audio-item.vala
similarity index 54%
copy from src/plugins/test/rygel-test-item.vala
copy to src/plugins/gst-launch/rygel-gst-launch-audio-item.vala
index f4bb394..d68fb6f 100644
--- a/src/plugins/test/rygel-test-item.vala
+++ b/src/plugins/gst-launch/rygel-gst-launch-audio-item.vala
@@ -1,7 +1,8 @@
/*
- * Copyright (C) 2008 Zeeshan Ali (Khattak) <zeeshanak gnome org>.
- * Copyright (C) 2008 Nokia Corporation.
+ * Copyright (C) 2009 Thijs Vermeir <thijsvermeir gmail com>
+ * Copyright (C) 2010 Nokia Corporation.
*
+ * Author: Thijs Vermeir <thijsvermeir gmail com>
* Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
* <zeeshan ali nokia com>
*
@@ -22,24 +23,26 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-using GUPnP;
using Gst;
/**
- * Represents Test item.
+ * Audio item that serves data from a gst-launch commandline.
*/
-public abstract class Rygel.Test.Item : Rygel.MediaItem {
- const string TEST_AUTHOR = "Zeeshan Ali (Khattak)";
+public class Rygel.GstLaunch.AudioItem : Rygel.AudioItem, Item {
+ public string launch_line { get; protected set; }
- public Item (string id,
- MediaContainer parent,
- string title,
- string mime,
- string upnp_class) {
- base (id, parent, title, upnp_class);
+ public AudioItem (string id,
+ MediaContainer parent,
+ string title,
+ string mime_type,
+ string launch_line) {
+ base (id, parent, title);
- this.mime_type = mime;
- this.author = TEST_AUTHOR;
+ this.mime_type = mime_type;
+ this.launch_line = launch_line;
}
-}
+ public override Element? create_stream_source () {
+ return this.create_source ();
+ }
+}
diff --git a/src/plugins/gst-launch/rygel-gst-launch-item.vala b/src/plugins/gst-launch/rygel-gst-launch-item.vala
index 29c4306..c00dd9f 100644
--- a/src/plugins/gst-launch/rygel-gst-launch-item.vala
+++ b/src/plugins/gst-launch/rygel-gst-launch-item.vala
@@ -1,7 +1,10 @@
/*
* Copyright (C) 2009 Thijs Vermeir <thijsvermeir gmail com>
+ * Copyright (C) 2010 Nokia Corporation.
*
* Author: Thijs Vermeir <thijsvermeir gmail com>
+ * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ * <zeeshan ali nokia com>
*
* This file is part of Rygel.
*
@@ -23,31 +26,12 @@
using Gst;
/**
- * Represents Test audio item.
+ * Item that serves data from a gst-launch commandline.
*/
-public class Rygel.GstLaunch.Item : Rygel.MediaItem {
- string launch_line;
+public interface Rygel.GstLaunch.Item : Rygel.MediaItem {
+ public abstract string launch_line { get; protected set; }
- public Item (string id,
- MediaContainer parent,
- string title,
- string mime_type,
- string launch_line) {
- string upnp_class;
-
- if (mime_type.has_prefix ("audio")) {
- upnp_class = MediaItem.AUDIO_CLASS;
- } else {
- upnp_class = MediaItem.VIDEO_CLASS;
- }
-
- base (id, parent, title, upnp_class);
-
- this.mime_type = mime_type;
- this.launch_line = launch_line;
- }
-
- public override Element? create_stream_source () {
+ protected Element? create_source () {
try {
return Gst.parse_bin_from_description (this.launch_line, true);
} catch (Error err) {
diff --git a/src/plugins/gst-launch/rygel-gst-launch-root-container.vala b/src/plugins/gst-launch/rygel-gst-launch-root-container.vala
index 59643a7..a433cf1 100644
--- a/src/plugins/gst-launch/rygel-gst-launch-root-container.vala
+++ b/src/plugins/gst-launch/rygel-gst-launch-root-container.vala
@@ -58,11 +58,19 @@ public class Rygel.GstLaunch.RootContainer : SimpleContainer {
var launch_line = config.get_string (CONFIG_GROUP,
"%s-launch".printf (name));
- this.add_child (new Item (name,
- this,
- title,
- mime_type,
- launch_line));
+ if (mime_type.has_prefix ("audio")) {
+ this.add_child (new AudioItem (name,
+ this,
+ title,
+ mime_type,
+ launch_line));
+ } else {
+ this.add_child (new VideoItem (name,
+ this,
+ title,
+ mime_type,
+ launch_line));
+ }
} catch (GLib.Error err) {
debug ("GstLaunch failed item '%s': %s", name, err.message);
}
diff --git a/src/plugins/test/rygel-test-item.vala b/src/plugins/gst-launch/rygel-gst-launch-video-item.vala
similarity index 54%
rename from src/plugins/test/rygel-test-item.vala
rename to src/plugins/gst-launch/rygel-gst-launch-video-item.vala
index f4bb394..3cfa0bc 100644
--- a/src/plugins/test/rygel-test-item.vala
+++ b/src/plugins/gst-launch/rygel-gst-launch-video-item.vala
@@ -1,7 +1,8 @@
/*
- * Copyright (C) 2008 Zeeshan Ali (Khattak) <zeeshanak gnome org>.
- * Copyright (C) 2008 Nokia Corporation.
+ * Copyright (C) 2009 Thijs Vermeir <thijsvermeir gmail com>
+ * Copyright (C) 2010 Nokia Corporation.
*
+ * Author: Thijs Vermeir <thijsvermeir gmail com>
* Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
* <zeeshan ali nokia com>
*
@@ -22,24 +23,26 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-using GUPnP;
using Gst;
/**
- * Represents Test item.
+ * Video item that serves data from a gst-launch commandline.
*/
-public abstract class Rygel.Test.Item : Rygel.MediaItem {
- const string TEST_AUTHOR = "Zeeshan Ali (Khattak)";
+public class Rygel.GstLaunch.VideoItem : Rygel.VideoItem, Item {
+ public string launch_line { get; protected set; }
- public Item (string id,
- MediaContainer parent,
- string title,
- string mime,
- string upnp_class) {
- base (id, parent, title, upnp_class);
+ public VideoItem (string id,
+ MediaContainer parent,
+ string title,
+ string mime_type,
+ string launch_line) {
+ base (id, parent, title);
- this.mime_type = mime;
- this.author = TEST_AUTHOR;
+ this.mime_type = mime_type;
+ this.launch_line = launch_line;
}
-}
+ public override Element? create_stream_source () {
+ return this.create_source ();
+ }
+}
diff --git a/src/plugins/media-export/rygel-media-export-harvesting-task.vala b/src/plugins/media-export/rygel-media-export-harvesting-task.vala
index f133c69..fa9bb33 100644
--- a/src/plugins/media-export/rygel-media-export-harvesting-task.vala
+++ b/src/plugins/media-export/rygel-media-export-harvesting-task.vala
@@ -287,13 +287,13 @@ public class Rygel.MediaExport.HarvestingTask : Rygel.StateMachine, GLib.Object
MediaItem item;
if (dlna == null) {
- item = new Item.simple (this.current_parent (),
+ item = ItemFactory.create_simple (this.current_parent (),
file,
mime,
size,
mtime);
} else {
- item = Item.create_from_info (this.current_parent (),
+ item = ItemFactory.create_from_info (this.current_parent (),
file,
dlna,
mime,
diff --git a/src/plugins/media-export/rygel-media-export-item.vala b/src/plugins/media-export/rygel-media-export-item.vala
index 5e1945f..63d1992 100644
--- a/src/plugins/media-export/rygel-media-export-item.vala
+++ b/src/plugins/media-export/rygel-media-export-item.vala
@@ -27,36 +27,38 @@ using Gst;
/**
* Represents MediaExport item.
*/
-public class Rygel.MediaExport.Item : Rygel.MediaItem {
- public Item.simple (MediaContainer parent,
- File file,
- string mime,
- uint64 size,
- uint64 mtime) {
+namespace Rygel.MediaExport.ItemFactory {
+ public static MediaItem create_simple (MediaContainer parent,
+ File file,
+ string mime,
+ uint64 size,
+ uint64 mtime) {
var title = file.get_basename ();
- string upnp_class;
+ MediaItem item;
if (mime.has_prefix ("video/")) {
- upnp_class = MediaItem.VIDEO_CLASS;
+ item = new VideoItem (MediaCache.get_id (file), parent, title);
} else if (mime.has_prefix ("image/")) {
- upnp_class = MediaItem.PHOTO_CLASS;
+ item = new PhotoItem (MediaCache.get_id (file), parent, title);
} else {
- upnp_class = MediaItem.AUDIO_CLASS;
+ item = new MusicItem (MediaCache.get_id (file), parent, title);
}
- base (MediaCache.get_id (file), parent, title, upnp_class);
- this.mime_type = mime;
- this.size = (int64) size;
- this.modified = mtime;
- this.add_uri (file.get_uri ());
+ item.mime_type = mime;
+ item.size = (int64) size;
+ item.modified = mtime;
+ item.add_uri (file.get_uri ());
+
+ return item;
}
- public static Item? create_from_info (MediaContainer parent,
- File file,
- GUPnP.DLNAInformation dlna_info,
- string mime,
- uint64 size,
- uint64 mtime) {
+ public static MediaItem? create_from_info (MediaContainer parent,
+ File file,
+ GUPnP.DLNAInformation dlna_info,
+ string mime,
+ uint64 size,
+ uint64 mtime) {
+ MediaItem item;
string id = MediaCache.get_id (file);
unowned StreamAudioInformation audio_info = null;
unowned StreamVideoInformation video_info = null;
@@ -76,154 +78,171 @@ public class Rygel.MediaExport.Item : Rygel.MediaItem {
if (video_info != null) {
if (audio_info == null &&
video_info.streamtype == Gst.StreamType.IMAGE) {
- return new Item.photo (parent,
- id,
- file,
- dlna_info,
- video_info,
- mime,
- size,
- mtime);
+ item = new PhotoItem (id, parent, "");
+ return fill_photo_item (item as PhotoItem,
+ file,
+ dlna_info,
+ video_info,
+ mime,
+ size,
+ mtime);
} else {
- return new Item.video (parent,
- id,
- file,
- dlna_info,
- video_info,
- audio_info,
- mime,
- size,
- mtime);
+ item = new VideoItem (id, parent, "");
+ return fill_video_item (item as VideoItem,
+ file,
+ dlna_info,
+ video_info,
+ audio_info,
+ mime,
+ size,
+ mtime);
}
} else if (audio_info != null) {
- return new Item.audio (parent,
- id,
- file,
- dlna_info,
- audio_info,
- mime,
- size,
- mtime);
+ item = new MusicItem (id, parent, "");
+ return fill_music_item (item as MusicItem,
+ file,
+ dlna_info,
+ audio_info,
+ mime,
+ size,
+ mtime);
} else {
return null;
}
}
- private Item.video (MediaContainer parent,
- string id,
- File file,
- GUPnP.DLNAInformation dlna_info,
- Gst.StreamVideoInformation video_info,
- Gst.StreamAudioInformation? audio_info,
- string mime,
- uint64 size,
- uint64 mtime) {
- this (parent,
- id,
- file,
- dlna_info,
- mime,
- size,
- mtime,
- MediaItem.VIDEO_CLASS);
-
- this.width = (int) video_info.width;
- this.height = (int) video_info.height;
- this.color_depth = (int) video_info.depth;
+ private static void fill_audio_item (AudioItem item,
+ DLNAInformation dlna_info,
+ StreamAudioInformation? audio_info) {
+ if (dlna_info.info.duration > 0) {
+ item.duration = dlna_info.info.duration / Gst.SECOND;
+ } else {
+ item.duration = -1;
+ }
+
+
+ if (audio_info != null) {
+ if (audio_info.tags != null) {
+ uint tmp;
+ audio_info.tags.get_uint (TAG_BITRATE, out tmp);
+ item.bitrate = (int) tmp / 8;
+ }
+ item.n_audio_channels = (int) audio_info.channels;
+ item.sample_freq = (int) audio_info.sample_rate;
+ }
+ }
+
+
+ private static MediaItem fill_video_item (VideoItem item,
+ File file,
+ DLNAInformation dlna_info,
+ StreamVideoInformation video_info,
+ StreamAudioInformation? audio_info,
+ string mime,
+ uint64 size,
+ uint64 mtime) {
+ fill_audio_item (item as AudioItem, dlna_info, audio_info);
+ fill_media_item (item, file, dlna_info, mime, size, mtime);
+
+ item.width = (int) video_info.width;
+ item.height = (int) video_info.height;
+ item.color_depth = (int) video_info.depth;
if (audio_info != null) {
- this.n_audio_channels = (int) audio_info.channels;
- this.sample_freq = (int) audio_info.sample_rate;
+ item.n_audio_channels = (int) audio_info.channels;
+ item.sample_freq = (int) audio_info.sample_rate;
if (audio_info.tags != null) {
uint tmp;
audio_info.tags.get_uint (TAG_BITRATE, out tmp);
- this.bitrate = (int) tmp / 8;
+ item.bitrate = (int) tmp / 8;
}
}
+
+ return item;
}
- private Item.photo (MediaContainer parent,
- string id,
- File file,
- GUPnP.DLNAInformation dlna_info,
- Gst.StreamVideoInformation video_info,
- string mime,
- uint64 size,
- uint64 mtime) {
- this (parent,
- id,
- file,
- dlna_info,
- mime,
- size,
- mtime,
- MediaItem.PHOTO_CLASS);
-
- this.width = (int) video_info.width;
- this.height = (int) video_info.height;
- this.color_depth = (int) video_info.depth;
+ private static MediaItem fill_photo_item (PhotoItem item,
+ File file,
+ DLNAInformation dlna_info,
+ StreamVideoInformation video_info,
+ string mime,
+ uint64 size,
+ uint64 mtime) {
+ fill_media_item (item,
+ file,
+ dlna_info,
+ mime,
+ size,
+ mtime);
+
+ item.width = (int) video_info.width;
+ item.height = (int) video_info.height;
+ item.color_depth = (int) video_info.depth;
+
+ return item;
}
- private Item.audio (MediaContainer parent,
- string id,
- File file,
- GUPnP.DLNAInformation dlna_info,
- Gst.StreamAudioInformation audio_info,
- string mime,
- uint64 size,
- uint64 mtime) {
- this (parent,
- id,
- file,
- dlna_info,
- mime,
- size,
- mtime,
- MediaItem.MUSIC_CLASS);
-
- if (audio_info.tags != null) {
- unowned Gst.Buffer buffer;
- audio_info.tags.get_buffer (TAG_IMAGE, out buffer);
- if (buffer != null) {
- var structure = buffer.caps.get_structure (0);
- int image_type;
- structure.get_enum ("image-type",
- typeof (Gst.TagImageType),
- out image_type);
- switch (image_type) {
- case TagImageType.UNDEFINED:
- case TagImageType.FRONT_COVER:
- var store = MediaArtStore.get_default ();
- var thumb = store.get_media_art_file ("album",
- this,
- true);
- try {
- var writer = new JPEGWriter ();
- writer.write (buffer, thumb);
- } catch (Error error) {}
- break;
- default:
- break;
+ private static MediaItem fill_music_item (MusicItem item,
+ File file,
+ DLNAInformation dlna_info,
+ StreamAudioInformation? audio_info,
+ string mime,
+ uint64 size,
+ uint64 mtime) {
+ fill_audio_item (item as AudioItem, dlna_info, audio_info);
+ fill_media_item (item,
+ file,
+ dlna_info,
+ mime,
+ size,
+ mtime);
+
+ if (audio_info != null) {
+ if (audio_info.tags != null) {
+ unowned Gst.Buffer buffer;
+ audio_info.tags.get_buffer (TAG_IMAGE, out buffer);
+ if (buffer != null) {
+ var structure = buffer.caps.get_structure (0);
+ int image_type;
+ structure.get_enum ("image-type",
+ typeof (Gst.TagImageType),
+ out image_type);
+ switch (image_type) {
+ case TagImageType.UNDEFINED:
+ case TagImageType.FRONT_COVER:
+ var store = MediaArtStore.get_default ();
+ var thumb = store.get_media_art_file ("album",
+ item,
+ true);
+ try {
+ var writer = new JPEGWriter ();
+ writer.write (buffer, thumb);
+ } catch (Error error) {}
+ break;
+ default:
+ break;
+ }
}
}
+ dlna_info.info.tags.get_string (TAG_ARTIST, out item.artist);
+ dlna_info.info.tags.get_string (TAG_ALBUM, out item.album);
+ dlna_info.info.tags.get_string (TAG_GENRE, out item.genre);
uint tmp;
- audio_info.tags.get_uint (TAG_BITRATE, out tmp);
- this.bitrate = (int) tmp / 8;
+ dlna_info.info.tags.get_uint (TAG_TRACK_NUMBER, out tmp);
+ item.track_number = (int) tmp;
}
- this.n_audio_channels = (int) audio_info.channels;
- this.sample_freq = (int) audio_info.sample_rate;
+
+ return item;
}
- private Item (MediaContainer parent,
- string id,
- File file,
- GUPnP.DLNAInformation dlna_info,
- string mime,
- uint64 size,
- uint64 mtime,
- string upnp_class) {
+ private static void fill_media_item (MediaItem item,
+ File file,
+ DLNAInformation dlna_info,
+ string mime,
+ uint64 size,
+ uint64 mtime) {
string title = null;
if (dlna_info.info.tags == null ||
@@ -231,48 +250,34 @@ public class Rygel.MediaExport.Item : Rygel.MediaItem {
title = file.get_basename ();
}
- base (id, parent, title, upnp_class);
-
- if (dlna_info.info.duration > 0) {
- this.duration = dlna_info.info.duration / Gst.SECOND;
- } else {
- this.duration = -1;
- }
+ item.title = title;
if (dlna_info.info.tags != null) {
- dlna_info.info.tags.get_string (TAG_ARTIST, out this.author);
- dlna_info.info.tags.get_string (TAG_ALBUM, out this.album);
- dlna_info.info.tags.get_string (TAG_GENRE, out this.genre);
-
- uint tmp;
- dlna_info.info.tags.get_uint (TAG_TRACK_NUMBER, out tmp);
- this.track_number = (int) tmp;
-
GLib.Date? date;
if (dlna_info.info.tags.get_date (TAG_DATE, out date)) {
char[] datestr = new char[30];
date.strftime (datestr, "%F");
- this.date = (string) datestr;
+ item.date = (string) datestr;
}
}
// use mtime if no time tag was available
- if (this.date == null) {
+ if (item.date == null) {
TimeVal tv = { (long) mtime, 0 };
- this.date = tv.to_iso8601 ();
+ item.date = tv.to_iso8601 ();
}
- this.size = (int64) size;
- this.modified = (int64) mtime;
+ item.size = (int64) size;
+ item.modified = (int64) mtime;
if (dlna_info.name != null) {
- this.dlna_profile = dlna_info.name;
- this.mime_type = dlna_info.mime;
+ item.dlna_profile = dlna_info.name;
+ item.mime_type = dlna_info.mime;
} else {
- this.mime_type = mime;
+ item.mime_type = mime;
}
- this.add_uri (file.get_uri ());
+ item.add_uri (file.get_uri ());
}
}
diff --git a/src/plugins/media-export/rygel-media-export-media-cache.vala b/src/plugins/media-export/rygel-media-export-media-cache.vala
index 701eced..0e38478 100644
--- a/src/plugins/media-export/rygel-media-export-media-cache.vala
+++ b/src/plugins/media-export/rygel-media-export-media-cache.vala
@@ -415,25 +415,57 @@ public class Rygel.MediaExport.MediaCache : Object {
}
}
+
+
private void save_metadata (Rygel.MediaItem item) throws Error {
+ // Fill common properties
GLib.Value[] values = { item.size,
item.mime_type,
- item.width,
- item.height,
+ 0,
+ 0,
item.upnp_class,
- item.author,
- item.album,
+ 0,
+ 0,
item.date,
- item.bitrate,
- item.sample_freq,
- item.bits_per_sample,
- item.n_audio_channels,
- item.track_number,
- item.color_depth,
- item.duration,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
item.id,
item.dlna_profile,
- item.genre};
+ 0};
+
+ if (item is AudioItem) {
+ var audio_item = item as AudioItem;
+ values[14] = audio_item.duration;
+ values[8] = audio_item.bitrate;
+ values[9] = audio_item.sample_freq;
+ values[10] = audio_item.bits_per_sample;
+ values[11] = audio_item.n_audio_channels;
+ if (item is MusicItem) {
+ var music_item = item as MusicItem;
+ values[5] = music_item.artist;
+ values[6] = music_item.album;
+ values[17] = music_item.genre;
+ values[12] = music_item.track_number;
+ music_item.lookup_album_art ();
+ }
+ }
+
+ if (item is VisualItem) {
+ var visual_item = item as VisualItem;
+ values[2] = visual_item.width;
+ values[3] = visual_item.height;
+ values[13] = visual_item.color_depth;
+ if (item is VideoItem) {
+ var video_item = item as VideoItem;
+ values[5] = video_item.author;
+ }
+ }
+
this.db.exec (this.sql.make (SQLString.SAVE_METADATA), values);
}
@@ -519,10 +551,6 @@ public class Rygel.MediaExport.MediaCache : Object {
upnp_class);
fill_item (statement, object as MediaItem);
- if (upnp_class.has_prefix (MediaItem.AUDIO_CLASS)) {
- (object as MediaItem).lookup_album_art ();
- }
-
var uri = statement.column_text (DetailColumn.URI);
if (uri != null) {
(object as MediaItem).add_uri (uri);
@@ -540,27 +568,41 @@ public class Rygel.MediaExport.MediaCache : Object {
}
private void fill_item (Statement statement, MediaItem item) {
- item.author = statement.column_text (DetailColumn.AUTHOR);
- item.album = statement.column_text (DetailColumn.ALBUM);
+ // Fill common properties
item.date = statement.column_text (DetailColumn.DATE);
item.mime_type = statement.column_text (DetailColumn.MIME_TYPE);
- item.duration = (long) statement.column_int64 (DetailColumn.DURATION);
-
+ item.dlna_profile = statement.column_text (DetailColumn.DLNA_PROFILE);
item.size = statement.column_int64 (DetailColumn.SIZE);
- item.bitrate = statement.column_int (DetailColumn.BITRATE);
- item.sample_freq = statement.column_int (DetailColumn.SAMPLE_FREQ);
- item.bits_per_sample = statement.column_int (
+ if (item is AudioItem) {
+ var audio_item = item as AudioItem;
+ audio_item.duration = (long) statement.column_int64 (DetailColumn.DURATION);
+ audio_item.bitrate = statement.column_int (DetailColumn.BITRATE);
+ audio_item.sample_freq = statement.column_int (DetailColumn.SAMPLE_FREQ);
+ audio_item.bits_per_sample = statement.column_int (
DetailColumn.BITS_PER_SAMPLE);
- item.n_audio_channels = statement.column_int (
+ audio_item.n_audio_channels = statement.column_int (
DetailColumn.CHANNELS);
- item.track_number = statement.column_int (DetailColumn.TRACK);
+ if (item is MusicItem) {
+ var music_item = item as MusicItem;
+ music_item.artist = statement.column_text (DetailColumn.AUTHOR);
+ music_item.album = statement.column_text (DetailColumn.ALBUM);
+ music_item.genre = statement.column_text (DetailColumn.GENRE);
+ music_item.track_number = statement.column_int (DetailColumn.TRACK);
+ music_item.lookup_album_art ();
+ }
+ }
- item.width = statement.column_int (DetailColumn.WIDTH);
- item.height = statement.column_int (DetailColumn.HEIGHT);
- item.color_depth = statement.column_int (DetailColumn.COLOR_DEPTH);
- item.dlna_profile = statement.column_text (DetailColumn.DLNA_PROFILE);
- item.genre = statement.column_text (DetailColumn.GENRE);
+ if (item is VisualItem) {
+ var visual_item = item as VisualItem;
+ visual_item.width = statement.column_int (DetailColumn.WIDTH);
+ visual_item.height = statement.column_int (DetailColumn.HEIGHT);
+ visual_item.color_depth = statement.column_int (DetailColumn.COLOR_DEPTH);
+ if (item is VideoItem) {
+ var video_item = item as VideoItem;
+ video_item.author = statement.column_text (DetailColumn.AUTHOR);
+ }
+ }
}
public ArrayList<string> get_child_ids (string container_id)
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 ea90b28..88fb43d 100644
--- a/src/plugins/media-export/rygel-media-export-object-factory.vala
+++ b/src/plugins/media-export/rygel-media-export-object-factory.vala
@@ -53,6 +53,15 @@ internal class Rygel.MediaExport.ObjectFactory : Object {
string id,
string title,
string upnp_class) {
- return new MediaItem (id, parent, title, upnp_class);
+ switch (upnp_class) {
+ case MusicItem.UPNP_CLASS:
+ return new MusicItem (id, parent, title);
+ case VideoItem.UPNP_CLASS:
+ return new VideoItem (id, parent, title);
+ case PhotoItem.UPNP_CLASS:
+ return new PhotoItem (id, parent, title);
+ default:
+ assert_not_reached ();
+ }
}
}
diff --git a/src/plugins/mediathek/rygel-mediathek-video-item.vala b/src/plugins/mediathek/rygel-mediathek-video-item.vala
index 473d480..4deb7bf 100644
--- a/src/plugins/mediathek/rygel-mediathek-video-item.vala
+++ b/src/plugins/mediathek/rygel-mediathek-video-item.vala
@@ -27,12 +27,11 @@ public errordomain Rygel.Mediathek.VideoItemError {
XML_PARSE_ERROR
}
-public class Rygel.Mediathek.VideoItem : Rygel.MediaItem {
+public class Rygel.Mediathek.VideoItem : Rygel.VideoItem {
private VideoItem (MediaContainer parent, string title) {
- base(Checksum.compute_for_string (ChecksumType.MD5, title),
- parent,
- title,
- MediaItem.VIDEO_CLASS);
+ base (Checksum.compute_for_string (ChecksumType.MD5, title),
+ parent,
+ title);
this.mime_type = "video/x-ms-wmv";
this.author = "ZDF - Second German TV Channel Streams";
diff --git a/src/plugins/test/Makefile.am b/src/plugins/test/Makefile.am
index 77e6fae..581d772 100644
--- a/src/plugins/test/Makefile.am
+++ b/src/plugins/test/Makefile.am
@@ -18,7 +18,6 @@ AM_CFLAGS = $(LIBGUPNP_CFLAGS) \
-include config.h
librygel_test_la_SOURCES = rygel-test-root-container.vala \
- rygel-test-item.vala \
rygel-test-audio-item.vala \
rygel-test-video-item.vala \
rygel-test-plugin.vala
diff --git a/src/plugins/test/rygel-test-audio-item.vala b/src/plugins/test/rygel-test-audio-item.vala
index 69bba43..36b1b39 100644
--- a/src/plugins/test/rygel-test-audio-item.vala
+++ b/src/plugins/test/rygel-test-audio-item.vala
@@ -27,16 +27,14 @@ using Gst;
/**
* Represents Test audio item.
*/
-public class Rygel.Test.AudioItem : Item {
+public class Rygel.Test.AudioItem : Rygel.AudioItem {
private const string TEST_MIMETYPE = "audio/x-wav";
private const string PIPELINE = "audiotestsrc is-live=1 ! wavenc";
public AudioItem (string id, MediaContainer parent, string title) {
- base (id,
- parent,
- title,
- TEST_MIMETYPE,
- MediaItem.AUDIO_CLASS);
+ base (id, parent, title);
+
+ this.mime_type = TEST_MIMETYPE;
}
public override Element? create_stream_source () {
diff --git a/src/plugins/test/rygel-test-video-item.vala b/src/plugins/test/rygel-test-video-item.vala
index c43498c..876d271 100644
--- a/src/plugins/test/rygel-test-video-item.vala
+++ b/src/plugins/test/rygel-test-video-item.vala
@@ -27,18 +27,16 @@ using Gst;
/**
* Represents Test video item.
*/
-public class Rygel.Test.VideoItem : Item {
+public class Rygel.Test.VideoItem : Rygel.VideoItem {
private const string TEST_MIMETYPE = "video/mpeg";
private const string PIPELINE = "videotestsrc is-live=1 ! " +
"ffenc_mpeg2video ! " +
"mpegtsmux";
public VideoItem (string id, MediaContainer parent, string title) {
- base (id,
- parent,
- title,
- TEST_MIMETYPE,
- MediaItem.VIDEO_CLASS);
+ base (id, parent, title);
+
+ this.mime_type = TEST_MIMETYPE;
}
public override Element? create_stream_source () {
diff --git a/src/plugins/tracker/rygel-tracker-item-factory.vala b/src/plugins/tracker/rygel-tracker-item-factory.vala
index cc01ae2..f9aa48e 100644
--- a/src/plugins/tracker/rygel-tracker-item-factory.vala
+++ b/src/plugins/tracker/rygel-tracker-item-factory.vala
@@ -68,13 +68,15 @@ public abstract class Rygel.Tracker.ItemFactory {
this.key_chains[Metadata.DATE].add ("nie:contentCreated");
}
- public virtual MediaItem create (string id,
- string uri,
- SearchContainer parent,
- string[] metadata)
- throws GLib.Error {
- var item = new MediaItem (id, parent, "", this.upnp_class);
-
+ public abstract MediaItem create (string id,
+ string uri,
+ SearchContainer parent,
+ string[] metadata)
+ throws GLib.Error;
+
+ protected virtual void set_metadata (MediaItem item,
+ string uri,
+ string[] metadata) throws GLib.Error {
if (metadata[Metadata.TITLE] != "")
item.title = metadata[Metadata.TITLE];
else
@@ -93,8 +95,6 @@ public abstract class Rygel.Tracker.ItemFactory {
item.mime_type = metadata[Metadata.MIME];
item.add_uri (uri);
-
- return item;
}
}
diff --git a/src/plugins/tracker/rygel-tracker-music-item-factory.vala b/src/plugins/tracker/rygel-tracker-music-item-factory.vala
index c8dee6c..899fcf0 100644
--- a/src/plugins/tracker/rygel-tracker-music-item-factory.vala
+++ b/src/plugins/tracker/rygel-tracker-music-item-factory.vala
@@ -41,7 +41,7 @@ public class Rygel.Tracker.MusicItemFactory : ItemFactory {
public MusicItemFactory () {
base (CATEGORY,
- MediaItem.MUSIC_CLASS,
+ MusicItem.UPNP_CLASS,
MUSIC_RESOURCES_CLASS_PATH,
Environment.get_user_special_dir (UserDirectory.MUSIC));
@@ -61,27 +61,38 @@ public class Rygel.Tracker.MusicItemFactory : ItemFactory {
public override MediaItem create (string id,
string uri,
SearchContainer parent,
- string[] metadata)
+ string[] metadata)
throws GLib.Error {
- var item = base.create (id, uri, parent, metadata);
+ var item = new MusicItem (id, parent, "");
+
+ this.set_metadata (item, uri, metadata);
+
+ return item;
+ }
+
+ protected override void set_metadata (MediaItem item,
+ string uri,
+ string[] metadata)
+ throws GLib.Error {
+ base.set_metadata (item, uri, metadata);
+
+ var music = item as MusicItem;
if (metadata[MusicMetadata.DURATION] != "" &&
metadata[MusicMetadata.DURATION] != "0") {
- item.duration = metadata[MusicMetadata.DURATION].to_int ();
+ music.duration = metadata[MusicMetadata.DURATION].to_int ();
}
if (metadata[MusicMetadata.AUDIO_TRACK_NUM] != "") {
var track_number = metadata[MusicMetadata.AUDIO_TRACK_NUM];
- item.track_number = track_number.to_int ();
+ music.track_number = track_number.to_int ();
}
- item.author = metadata[MusicMetadata.AUDIO_ARTIST];
- item.album = metadata[MusicMetadata.AUDIO_ALBUM];
- item.genre = metadata[MusicMetadata.AUDIO_GENRE];
+ music.artist = metadata[MusicMetadata.AUDIO_ARTIST];
+ music.album = metadata[MusicMetadata.AUDIO_ALBUM];
+ music.genre = metadata[MusicMetadata.AUDIO_GENRE];
- item.lookup_album_art ();
-
- return item;
+ music.lookup_album_art ();
}
}
diff --git a/src/plugins/tracker/rygel-tracker-picture-item-factory.vala b/src/plugins/tracker/rygel-tracker-picture-item-factory.vala
index c8b162f..d722ed3 100644
--- a/src/plugins/tracker/rygel-tracker-picture-item-factory.vala
+++ b/src/plugins/tracker/rygel-tracker-picture-item-factory.vala
@@ -38,7 +38,7 @@ public class Rygel.Tracker.PictureItemFactory : ItemFactory {
public PictureItemFactory () {
base (CATEGORY,
- MediaItem.PHOTO_CLASS,
+ PhotoItem.UPNP_CLASS,
PHOTO_RESOURCES_CLASS_PATH,
Environment.get_user_special_dir (UserDirectory.PICTURES));
@@ -55,15 +55,28 @@ public class Rygel.Tracker.PictureItemFactory : ItemFactory {
SearchContainer parent,
string[] metadata)
throws GLib.Error {
- var item = base.create (id, uri, parent, metadata);
+ var item = new PhotoItem (id, parent, "");
- if (metadata[PictureMetadata.WIDTH] != "")
- item.width = metadata[PictureMetadata.WIDTH].to_int ();
-
- if (metadata[PictureMetadata.HEIGHT] != "")
- item.height = metadata[PictureMetadata.HEIGHT].to_int ();
+ this.set_metadata (item, uri, metadata);
return item;
}
+
+ protected override void set_metadata (MediaItem item,
+ string uri,
+ string[] metadata)
+ throws GLib.Error {
+ base.set_metadata (item, uri, metadata);
+
+ var photo = item as PhotoItem;
+
+ if (metadata[PictureMetadata.WIDTH] != "") {
+ photo.width = metadata[PictureMetadata.WIDTH].to_int ();
+ }
+
+ if (metadata[PictureMetadata.HEIGHT] != "") {
+ photo.height = metadata[PictureMetadata.HEIGHT].to_int ();
+ }
+ }
}
diff --git a/src/plugins/tracker/rygel-tracker-video-item-factory.vala b/src/plugins/tracker/rygel-tracker-video-item-factory.vala
index 3e1d366..db66cdf 100644
--- a/src/plugins/tracker/rygel-tracker-video-item-factory.vala
+++ b/src/plugins/tracker/rygel-tracker-video-item-factory.vala
@@ -39,7 +39,7 @@ public class Rygel.Tracker.VideoItemFactory : ItemFactory {
public VideoItemFactory () {
base (CATEGORY,
- MediaItem.VIDEO_CLASS,
+ VideoItem.UPNP_CLASS,
VIDEO_RESOURCES_CLASS_PATH,
Environment.get_user_special_dir (UserDirectory.VIDEOS));
@@ -57,18 +57,29 @@ public class Rygel.Tracker.VideoItemFactory : ItemFactory {
SearchContainer parent,
string[] metadata)
throws GLib.Error {
- var item = base.create (id, uri, parent, metadata);
+ var item = new VideoItem (id, parent, "");
+
+ this.set_metadata (item, uri, metadata);
+
+ return item;
+ }
+
+ protected override void set_metadata (MediaItem item,
+ string uri,
+ string[] metadata)
+ throws GLib.Error {
+ base.set_metadata (item, uri, metadata);
+
+ var video = item as VideoItem;
if (metadata[VideoMetadata.WIDTH] != "")
- item.width = metadata[VideoMetadata.WIDTH].to_int ();
+ video.width = metadata[VideoMetadata.WIDTH].to_int ();
if (metadata[VideoMetadata.HEIGHT] != "")
- item.height = metadata[VideoMetadata.HEIGHT].to_int ();
+ video.height = metadata[VideoMetadata.HEIGHT].to_int ();
if (metadata[VideoMetadata.DURATION] != "")
- item.duration = metadata[VideoMetadata.DURATION].to_int ();
-
- return item;
+ video.duration = metadata[VideoMetadata.DURATION].to_int ();
}
}
diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am
index 6752c25..1c87ebc 100644
--- a/src/rygel/Makefile.am
+++ b/src/rygel/Makefile.am
@@ -82,6 +82,12 @@ VAPI_SOURCE_FILES = rygel-configuration.vala \
rygel-media-container.vala \
rygel-simple-container.vala \
rygel-media-item.vala \
+ rygel-audio-item.vala \
+ rygel-music-item.vala \
+ rygel-visual-item.vala \
+ rygel-video-item.vala \
+ rygel-image-item.vala \
+ rygel-photo-item.vala \
rygel-thumbnail.vala \
rygel-thumbnailer.vala \
rygel-album-art.vala \
diff --git a/src/rygel/rygel-audio-item.vala b/src/rygel/rygel-audio-item.vala
new file mode 100644
index 0000000..eb58f26
--- /dev/null
+++ b/src/rygel/rygel-audio-item.vala
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 Zeeshan Ali <zeenix gmail com>.
+ * Copyright (C) 2010 Nokia Corporation.
+ *
+ * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ * <zeeshan ali nokia 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 GUPnP;
+
+/**
+ * Represents an audio item.
+ */
+public class Rygel.AudioItem : MediaItem {
+ public new const string UPNP_CLASS = "object.item.audioItem";
+
+ public long duration = -1; // Duration in seconds
+ public int bitrate = -1; // Bytes/second
+
+ public int sample_freq = -1;
+ public int bits_per_sample = -1;
+ public int n_audio_channels = -1;
+
+ public AudioItem (string id,
+ MediaContainer parent,
+ string title,
+ string upnp_class = AudioItem.UPNP_CLASS) {
+ base (id, parent, title, upnp_class);
+ }
+
+ public override bool streamable () {
+ return true;
+ }
+
+ internal override DIDLLiteResource add_resource (
+ DIDLLiteItem didl_item,
+ string? uri,
+ string protocol,
+ string? import_uri = null)
+ throws Error {
+ var res = base.add_resource (didl_item, uri, protocol, import_uri);
+
+ res.duration = this.duration;
+ res.bitrate = this.bitrate;
+ res.sample_freq = this.sample_freq;
+ res.bits_per_sample = this.bits_per_sample;
+ res.audio_channels = this.n_audio_channels;
+
+ return res;
+ }
+}
diff --git a/src/rygel/rygel-didl-lite-writer.vala b/src/rygel/rygel-didl-lite-writer.vala
index 9f92da9..cc17574 100644
--- a/src/rygel/rygel-didl-lite-writer.vala
+++ b/src/rygel/rygel-didl-lite-writer.vala
@@ -40,7 +40,7 @@ internal class Rygel.DIDLLiteWriter : GUPnP.DIDLLiteWriter {
public void serialize (MediaObject media_object) throws Error {
if (media_object is MediaItem) {
- this.serialize_item ((MediaItem) media_object);
+ ((MediaItem) media_object).serialize (this);
} else if (media_object is MediaContainer) {
this.serialize_container ((MediaContainer) media_object);
} else {
@@ -49,63 +49,6 @@ internal class Rygel.DIDLLiteWriter : GUPnP.DIDLLiteWriter {
}
}
- private void serialize_item (MediaItem item) throws Error {
- var didl_item = this.add_item ();
-
- didl_item.id = item.id;
- if (item.parent != null) {
- didl_item.parent_id = item.parent.id;
- } else {
- didl_item.parent_id = "0";
- }
-
- didl_item.restricted = false;
-
- didl_item.title = item.title;
- didl_item.upnp_class = item.upnp_class;
- if (item.author != null && item.author != "") {
- var contributor = didl_item.add_creator ();
- contributor.name = item.author;
-
- if (item.upnp_class.has_prefix (MediaItem.VIDEO_CLASS)) {
- contributor = didl_item.add_author ();
- contributor.name = item.author;
- } else if (item.upnp_class.has_prefix (MediaItem.MUSIC_CLASS)) {
- contributor = didl_item.add_artist ();
- contributor.name = item.author;
- }
- }
-
- if (item.track_number >= 0) {
- didl_item.track_number = item.track_number;
- }
-
- if (item.album != null && item.album != "") {
- didl_item.album = item.album;
- }
-
- if (item.date != null && item.date != "") {
- didl_item.date = item.date;
- }
-
- if (item.genre != null && item.genre != "") {
- didl_item.genre = item.genre;
- }
-
- if (item.place_holder) {
- this.http_server.add_proxy_resource (didl_item, item);
- } else {
- // Add the transcoded/proxy URIs first
- this.http_server.add_resources (didl_item, item);
-
- // then original URIs
- bool internal_allowed;
- internal_allowed = this.http_server.context.interface == "lo" ||
- this.http_server.context.host_ip == "127.0.0.1";
- item.add_resources (didl_item, internal_allowed);
- }
- }
-
private void serialize_container (MediaContainer container) throws Error {
var didl_container = this.add_container ();
if (container.parent != null) {
diff --git a/src/rygel/rygel-http-get-handler.vala b/src/rygel/rygel-http-get-handler.vala
index 5d11cbd..1061e36 100644
--- a/src/rygel/rygel-http-get-handler.vala
+++ b/src/rygel/rygel-http-get-handler.vala
@@ -61,8 +61,8 @@ internal abstract class Rygel.HTTPGetHandler: GLib.Object {
}
// Handle Samsung DLNA TV proprietary subtitle headers
- if (request.msg.request_headers.get_one ("getCaptionInfo.sec") != null &&
- request.item.subtitles.size > 0) {
+ if (request.msg.request_headers.get_one ("getCaptionInfo.sec") != null
+ && (request.item as VideoItem).subtitles.size > 0) {
var caption_uri = request.http_server.create_uri_for_item (
request.item,
-1,
diff --git a/src/rygel/rygel-http-get.vala b/src/rygel/rygel-http-get.vala
index b783102..f5be2e0 100644
--- a/src/rygel/rygel-http-get.vala
+++ b/src/rygel/rygel-http-get.vala
@@ -79,10 +79,29 @@ internal class Rygel.HTTPGet : HTTPRequest {
yield base.find_item ();
if (this.uri.thumbnail_index >= 0) {
- this.thumbnail = this.item.thumbnails.get (
+ if (this.item is MusicItem) {
+ var music = this.item as MusicItem;
+
+ this.thumbnail = music.album_art;
+ } else if (this.item is VisualItem) {
+ var visual = this.item as VisualItem;
+
+ this.thumbnail = visual.thumbnails.get (
this.uri.thumbnail_index);
+ } else {
+ throw new HTTPRequestError.NOT_FOUND (
+ ("No Thumbnail available for item '%s"),
+ this.item.id);
+ }
} else if (this.uri.subtitle_index >= 0) {
- this.subtitle = this.item.subtitles.get (this.uri.subtitle_index);
+ if (!(this.item is VideoItem)) {
+ throw new HTTPRequestError.NOT_FOUND (
+ ("No subtitles available for item '%s"),
+ this.item.id);
+ }
+
+ this.subtitle = (this.item as VideoItem).subtitles.get (
+ this.uri.subtitle_index);
}
}
diff --git a/src/rygel/rygel-http-server.vala b/src/rygel/rygel-http-server.vala
index 419e195..460a220 100644
--- a/src/rygel/rygel-http-server.vala
+++ b/src/rygel/rygel-http-server.vala
@@ -58,58 +58,13 @@ internal class Rygel.HTTPServer : Rygel.TranscodeManager, Rygel.StateMachine {
}
}
- /* We prepend these resources into the original resource list instead of
- * appending them because some crappy MediaRenderer/ControlPoint
- * implemenation out there just choose the first one in the list instead of
- * the one they can handle.
- */
- internal override void add_resources (DIDLLiteItem didl_item,
- MediaItem item)
- throws Error {
- // Subtitles first
- foreach (var subtitle in item.subtitles) {
- if (this.need_proxy (subtitle.uri)) {
- var uri = subtitle.uri; // Save the original URI
- var index = item.subtitles.index_of (subtitle);
-
- subtitle.uri = this.create_uri_for_item (item,
- -1,
- index,
- null);
- subtitle.add_didl_node (didl_item);
-
- // Now restore the original URI
- subtitle.uri = uri;
- }
- }
-
- if (!this.http_uri_present (item)) {
- this.add_proxy_resource (didl_item, item);
- }
-
- base.add_resources (didl_item, item);
-
- // Thumbnails comes in the end
- foreach (var thumbnail in item.thumbnails) {
- if (this.need_proxy (thumbnail.uri)) {
- var uri = thumbnail.uri; // Save the original URI
- var index = item.thumbnails.index_of (thumbnail);
-
- thumbnail.uri = this.create_uri_for_item (item,
- index,
- -1,
- null);
- thumbnail.add_resource (didl_item, this.get_protocol ());
-
- // Now restore the original URI
- thumbnail.uri = uri;
- }
- }
- }
-
internal void add_proxy_resource (DIDLLiteItem didl_item,
MediaItem item)
throws Error {
+ if (this.http_uri_present (item)) {
+ return;
+ }
+
var uri = this.create_uri_for_item (item, -1, -1, null);
item.add_resource (didl_item,
diff --git a/src/rygel/rygel-http-time-seek.vala b/src/rygel/rygel-http-time-seek.vala
index 2f9cc22..95c84de 100644
--- a/src/rygel/rygel-http-time-seek.vala
+++ b/src/rygel/rygel-http-time-seek.vala
@@ -35,7 +35,7 @@ internal class Rygel.HTTPTimeSeek : Rygel.HTTPSeek {
string range, time;
string[] range_tokens;
int64 start = 0;
- int64 duration = request.item.duration * SECOND;
+ int64 duration = (request.item as AudioItem).duration * SECOND;
int64 stop = duration - SECOND;
range = request.msg.request_headers.get_one ("TimeSeekRange.dlna.org");
@@ -79,7 +79,8 @@ internal class Rygel.HTTPTimeSeek : Rygel.HTTPSeek {
}
public static bool needed (HTTPGet request) {
- return request.item.duration > 0 &&
+ return request.item is AudioItem &&
+ (request.item as AudioItem).duration > 0 &&
(request.handler is HTTPTranscodeHandler ||
(request.thumbnail == null &&
request.subtitle == null &&
diff --git a/src/rygel/rygel-image-item.vala b/src/rygel/rygel-image-item.vala
new file mode 100644
index 0000000..a8cdd63
--- /dev/null
+++ b/src/rygel/rygel-image-item.vala
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2008 Zeeshan Ali <zeenix gmail com>.
+ * Copyright (C) 2010 Nokia Corporation.
+ *
+ * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ * <zeeshan ali nokia 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 GUPnP;
+using Gee;
+
+/**
+ * Represents an image item.
+ */
+public class Rygel.ImageItem : MediaItem, VisualItem {
+ public new const string UPNP_CLASS = "object.item.imageItem";
+
+ public int width { get; set; default = -1; }
+ public int height { get; set; default = -1; }
+ public int pixel_width { get; set; default = -1; }
+ public int pixel_height { get; set; default = -1; }
+ public int color_depth { get; set; default = -1; }
+
+ public ArrayList<Thumbnail> thumbnails { get; protected set; }
+
+ public ImageItem (string id,
+ MediaContainer parent,
+ string title,
+ string upnp_class = ImageItem.UPNP_CLASS) {
+ base (id, parent, title, upnp_class);
+
+ this.thumbnails = new ArrayList<Thumbnail> ();
+ }
+
+ public override bool streamable () {
+ return false;
+ }
+
+ public override void add_uri (string uri) {
+ base.add_uri (uri);
+
+ this.add_thumbnail_for_uri (uri);
+ }
+
+ internal override void add_resources (DIDLLiteItem didl_item,
+ bool allow_internal)
+ throws Error {
+ base.add_resources (didl_item, allow_internal);
+
+ this.add_thumbnail_resources (didl_item, allow_internal);
+ }
+
+ internal override DIDLLiteResource add_resource (
+ DIDLLiteItem didl_item,
+ string? uri,
+ string protocol,
+ string? import_uri = null)
+ throws Error {
+ var res = base.add_resource (didl_item, uri, protocol, import_uri);
+
+ this.add_visual_props (res);
+
+ return res;
+ }
+
+ internal override void add_proxy_resources (HTTPServer server,
+ DIDLLiteItem didl_item)
+ throws Error {
+ base.add_proxy_resources (server, didl_item);
+
+ // Thumbnails comes in the end
+ this.add_thumbnail_proxy_resources (server, didl_item);
+ }
+
+ protected override ProtocolInfo get_protocol_info (string? uri,
+ string protocol) {
+ var protocol_info = base.get_protocol_info (uri, protocol);
+
+ protocol_info.dlna_flags |= DLNAFlags.INTERACTIVE_TRANSFER_MODE;
+
+ return protocol_info;
+ }
+}
diff --git a/src/rygel/rygel-item-creator.vala b/src/rygel/rygel-item-creator.vala
index 1e66853..1d46be0 100644
--- a/src/rygel/rygel-item-creator.vala
+++ b/src/rygel/rygel-item-creator.vala
@@ -71,10 +71,11 @@ internal class Rygel.ItemCreator: GLib.Object, Rygel.StateMachine {
var container = yield this.fetch_container ();
- this.item = new MediaItem (didl_item.id,
- container,
- didl_item.title,
- didl_item.upnp_class);
+ this.item = this.create_item (didl_item.id,
+ container,
+ didl_item.title,
+ didl_item.upnp_class);
+
var resources = didl_item.get_resources ();
if (resources != null) {
var info = resources.nth (0).data.protocol_info;
@@ -188,14 +189,35 @@ internal class Rygel.ItemCreator: GLib.Object, Rygel.StateMachine {
}
private string get_generic_mime_type () {
- switch (this.item.upnp_class) {
- case MediaItem.IMAGE_CLASS:
- return "image";
- case MediaItem.VIDEO_CLASS:
- return "video";
- case MediaItem.AUDIO_CLASS:
- default:
- return "audio";
+ if (this.item is ImageItem) {
+ return "image";
+ } else if (this.item is VideoItem) {
+ return "video";
+ } else {
+ return "audio";
+ }
+ }
+
+ private MediaItem create_item (string id,
+ MediaContainer parent,
+ string title,
+ string upnp_class) throws Error {
+ switch (upnp_class) {
+ case ImageItem.UPNP_CLASS:
+ return new ImageItem (id, parent, title);
+ case PhotoItem.UPNP_CLASS:
+ return new PhotoItem (id, parent, title);
+ case VideoItem.UPNP_CLASS:
+ return new VideoItem (id, parent, title);
+ case AudioItem.UPNP_CLASS:
+ return new AudioItem (id, parent, title);
+ case MusicItem.UPNP_CLASS:
+ return new MusicItem (id, parent, title);
+ default:
+ throw new ContentDirectoryError.BAD_METADATA (
+ "Creation of item of class '%s' " +
+ "not supported.",
+ upnp_class);
}
}
}
diff --git a/src/rygel/rygel-l16-transcoder.vala b/src/rygel/rygel-l16-transcoder.vala
index 5032b06..f2d7c31 100644
--- a/src/rygel/rygel-l16-transcoder.vala
+++ b/src/rygel/rygel-l16-transcoder.vala
@@ -52,7 +52,7 @@ internal class Rygel.L16Transcoder : Rygel.Transcoder {
";rate=" + L16Transcoder.FREQUENCY.to_string () +
";channels=" + L16Transcoder.CHANNELS.to_string ();
- base (mime_type, "LPCM", MediaItem.AUDIO_CLASS);
+ base (mime_type, "LPCM", AudioItem.UPNP_CLASS);
this.endianness = endianness;
}
@@ -83,22 +83,23 @@ internal class Rygel.L16Transcoder : Rygel.Transcoder {
}
public override uint get_distance (MediaItem item) {
- if (!item.upnp_class.has_prefix (MediaItem.AUDIO_CLASS)) {
+ if (!(item is AudioItem)) {
return uint.MAX;
}
+ var audio_item = item as AudioItem;
var distance = uint.MIN;
- if (item.sample_freq > 0) {
- distance += (item.sample_freq - FREQUENCY).abs ();
+ if (audio_item.sample_freq > 0) {
+ distance += (audio_item.sample_freq - FREQUENCY).abs ();
}
- if (item.n_audio_channels > 0) {
- distance += (item.n_audio_channels - CHANNELS).abs ();
+ if (audio_item.n_audio_channels > 0) {
+ distance += (audio_item.n_audio_channels - CHANNELS).abs ();
}
- if (item.bits_per_sample > 0) {
- distance += (item.bits_per_sample - WIDTH).abs ();
+ if (audio_item.bits_per_sample > 0) {
+ distance += (audio_item.bits_per_sample - WIDTH).abs ();
}
return distance;
diff --git a/src/rygel/rygel-media-art-store.vala b/src/rygel/rygel-media-art-store.vala
index 3350ccd..4c8a024 100644
--- a/src/rygel/rygel-media-art-store.vala
+++ b/src/rygel/rygel-media-art-store.vala
@@ -54,8 +54,8 @@ public class Rygel.MediaArtStore : GLib.Object {
return media_art_store;
}
- public Thumbnail? find_media_art (MediaItem item,
- bool simple = false) throws Error {
+ public Thumbnail? find_media_art (MusicItem item,
+ bool simple = false) throws Error {
string[] types = { "track", "album", "artist", "podcast", "radio" };
File file = null;
@@ -87,7 +87,7 @@ public class Rygel.MediaArtStore : GLib.Object {
return thumb;
}
- public Thumbnail? find_media_art_any (MediaItem item) throws Error {
+ public Thumbnail? find_media_art_any (MusicItem item) throws Error {
var thumb = this.find_media_art (item);
if (thumb == null) {
thumb = this.find_media_art (item, true);
@@ -97,7 +97,7 @@ public class Rygel.MediaArtStore : GLib.Object {
}
public File get_media_art_file (string type,
- MediaItem item,
+ MusicItem item,
bool simple = false) {
string hash;
string suffix;
@@ -146,22 +146,22 @@ public class Rygel.MediaArtStore : GLib.Object {
}
}
- private string get_simple_hash (string type, MediaItem item) {
+ private string get_simple_hash (string type, MusicItem item) {
string hash;
switch (type) {
case "artist":
case "radio":
- hash = this.normalize_and_hash (item.author);
+ hash = this.normalize_and_hash (item.artist);
break;
case "podcast":
hash = this.normalize_and_hash (item.title);
break;
case "album":
- hash = this.normalize_and_hash (item.author + "\t" +
+ hash = this.normalize_and_hash (item.artist + "\t" +
item.album);
break;
case "track":
- hash = this.normalize_and_hash (item.author + "\t" +
+ hash = this.normalize_and_hash (item.artist + "\t" +
item.album + "\t" +
item.title);
break;
@@ -172,17 +172,17 @@ public class Rygel.MediaArtStore : GLib.Object {
return hash;
}
- private string get_hash (string type, MediaItem item) {
+ private string get_hash (string type, MusicItem item) {
string b = null, c = null;
switch (type) {
case "track":
- b = this.normalize_and_hash (item.author, false) + "-" +
+ b = this.normalize_and_hash (item.artist, false) + "-" +
this.normalize_and_hash (item.album, false);
c = this.normalize_and_hash (item.title, false);
break;
case "album":
case "artist":
- b = this.normalize_and_hash (item.author, false);
+ b = this.normalize_and_hash (item.artist, false);
c = this.normalize_and_hash (item.album, false);
break;
case "radio":
diff --git a/src/rygel/rygel-media-container.vala b/src/rygel/rygel-media-container.vala
index 065542f..e79d47d 100644
--- a/src/rygel/rygel-media-container.vala
+++ b/src/rygel/rygel-media-container.vala
@@ -252,9 +252,11 @@ public abstract class Rygel.MediaContainer : MediaObject {
if (create_classes != null) {
this.create_classes.add_all (create_classes);
} else {
- this.create_classes.add (MediaItem.IMAGE_CLASS);
- this.create_classes.add (MediaItem.VIDEO_CLASS);
- this.create_classes.add (MediaItem.AUDIO_CLASS);
+ this.create_classes.add (ImageItem.UPNP_CLASS);
+ this.create_classes.add (PhotoItem.UPNP_CLASS);
+ this.create_classes.add (VideoItem.UPNP_CLASS);
+ this.create_classes.add (AudioItem.UPNP_CLASS);
+ this.create_classes.add (MusicItem.UPNP_CLASS);
}
}
diff --git a/src/rygel/rygel-media-item.vala b/src/rygel/rygel-media-item.vala
index 53a842f..7b7cef2 100644
--- a/src/rygel/rygel-media-item.vala
+++ b/src/rygel/rygel-media-item.vala
@@ -1,7 +1,9 @@
/*
* Copyright (C) 2008 Zeeshan Ali <zeenix gmail com>.
+ * Copyright (C) 2010 Nokia Corporation.
*
- * Author: Zeeshan Ali <zeenix gmail com>
+ * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ * <zeeshan ali nokia com>
*
* This file is part of Rygel.
*
@@ -21,7 +23,6 @@
*/
using GUPnP;
-using Gee;
using Gst;
private errordomain Rygel.MediaItemError {
@@ -31,41 +32,14 @@ private errordomain Rygel.MediaItemError {
/**
* Represents a media (Music, Video and Image) item.
*/
-public class Rygel.MediaItem : MediaObject {
- public static const string IMAGE_CLASS = "object.item.imageItem";
- public static const string PHOTO_CLASS = "object.item.imageItem.photo";
- public static const string VIDEO_CLASS = "object.item.videoItem";
- public static const string AUDIO_CLASS = "object.item.audioItem";
- public static const string MUSIC_CLASS = "object.item.audioItem.musicTrack";
-
- public string author;
- public string album;
+public abstract class Rygel.MediaItem : MediaObject {
public string date;
- public string genre;
// Resource info
public string mime_type;
public string dlna_profile;
public int64 size = -1; // Size in bytes
- public long duration = -1; // Duration in seconds
- public int bitrate = -1; // Bytes/second
-
- // Audio/Music
- public int sample_freq = -1;
- public int bits_per_sample = -1;
- public int n_audio_channels = -1;
- public int track_number = -1;
-
- // Image/Video
- public int width = -1;
- public int height = -1;
- public int pixel_width = -1;
- public int pixel_height = -1;
- public int color_depth = -1;
-
- public ArrayList<Thumbnail> thumbnails;
- public ArrayList<Subtitle> subtitles;
internal bool place_holder = false;
@@ -77,9 +51,6 @@ public class Rygel.MediaItem : MediaObject {
this.parent = parent;
this.title = title;
this.upnp_class = upnp_class;
-
- this.thumbnails = new ArrayList<Thumbnail> ();
- this.subtitles = new ArrayList<Subtitle> ();
}
// Live media items need to provide a nice working implementation of this
@@ -116,57 +87,10 @@ public class Rygel.MediaItem : MediaObject {
return this.streamable () && this.size <= 0;
}
- public bool streamable () {
- return !this.upnp_class.has_prefix (IMAGE_CLASS);
- }
+ public abstract bool streamable ();
- public void add_uri (string uri) {
+ public virtual void add_uri (string uri) {
this.uris.add (uri);
-
- if (this.upnp_class.has_prefix (MediaItem.IMAGE_CLASS) ||
- this.upnp_class.has_prefix (MediaItem.VIDEO_CLASS)) {
- // Lets see if we can provide the thumbnails
- var thumbnailer = Thumbnailer.get_default ();
-
- if (thumbnailer == null) {
- return;
- }
-
- try {
- var thumb = thumbnailer.get_thumbnail (uri);
- this.thumbnails.add (thumb);
- } catch (Error err) {}
- }
-
- if (this.upnp_class.has_prefix (MediaItem.VIDEO_CLASS)) {
- var subtitle_manager = SubtitleManager.get_default ();
-
- if (subtitle_manager == null) {
- return;
- }
-
- try {
- var subtitle = subtitle_manager.get_subtitle (uri);
- this.subtitles.add (subtitle);
- } catch (Error err) {}
- }
- }
-
- public void lookup_album_art () {
- assert (this.upnp_class.has_prefix (MediaItem.AUDIO_CLASS) &&
- this.thumbnails.size == 0);
-
- var media_art_store = MediaArtStore.get_default ();
- if (media_art_store == null) {
- return;
- }
-
- try {
- var thumb = media_art_store.find_media_art_any (this);
- if (thumb != null) {
- this.thumbnails.insert (0, thumb);
- }
- } catch (Error err) {};
}
internal int compare_transcoders (void *a, void *b) {
@@ -177,39 +101,12 @@ public class Rygel.MediaItem : MediaObject {
(int) transcoder2.get_distance (this);
}
- internal void add_resources (DIDLLiteItem didl_item,
- bool allow_internal)
- throws Error {
- foreach (var subtitle in this.subtitles) {
- var protocol = this.get_protocol_for_uri (subtitle.uri);
-
- if (allow_internal || protocol != "internal") {
- subtitle.add_didl_node (didl_item);
- }
- }
-
- foreach (var uri in this.uris) {
- var protocol = this.get_protocol_for_uri (uri);
-
- if (allow_internal || protocol != "internal") {
- this.add_resource (didl_item, uri, protocol);
- }
- }
-
- foreach (var thumbnail in this.thumbnails) {
- var protocol = this.get_protocol_for_uri (thumbnail.uri);
-
- if (allow_internal || protocol != "internal") {
- thumbnail.add_resource (didl_item, protocol);
- }
- }
- }
-
- internal DIDLLiteResource add_resource (DIDLLiteItem didl_item,
- string? uri,
- string protocol,
- string? import_uri = null)
- throws Error {
+ internal virtual DIDLLiteResource add_resource (
+ DIDLLiteItem didl_item,
+ string? uri,
+ string protocol,
+ string? import_uri = null)
+ throws Error {
var res = didl_item.add_resource ();
if (uri != null) {
@@ -221,16 +118,6 @@ public class Rygel.MediaItem : MediaObject {
}
res.size64 = this.size;
- res.duration = this.duration;
- res.bitrate = this.bitrate;
-
- res.sample_freq = this.sample_freq;
- res.bits_per_sample = this.bits_per_sample;
- res.audio_channels = this.n_audio_channels;
-
- res.width = this.width;
- res.height = this.height;
- res.color_depth = this.color_depth;
/* Protocol info */
res.protocol_info = this.get_protocol_info (uri, protocol);
@@ -243,12 +130,6 @@ public class Rygel.MediaItem : MediaObject {
var item = media_object as MediaItem;
switch (property) {
- case "dc:creator":
- case "dc:artist":
- case "dc:author":
- return this.compare_string_props (this.author, item.author);
- case "upnp:album":
- return this.compare_string_props (this.album, item.album);
case "dc:date":
return this.compare_by_date (item);
default:
@@ -256,8 +137,55 @@ public class Rygel.MediaItem : MediaObject {
}
}
- private ProtocolInfo get_protocol_info (string? uri,
- string protocol) {
+ internal virtual DIDLLiteItem serialize (DIDLLiteWriter writer)
+ throws Error {
+ var didl_item = writer.add_item ();
+
+ didl_item.id = this.id;
+ if (this.parent != null) {
+ didl_item.parent_id = this.parent.id;
+ } else {
+ didl_item.parent_id = "0";
+ }
+
+ didl_item.restricted = false;
+ didl_item.title = this.title;
+ didl_item.upnp_class = this.upnp_class;
+
+ /* We list proxy/transcoding resources first instead of original URIs
+ * because some crappy MediaRenderer/ControlPoint implemenation out
+ * there just choose the first one in the list instead of the one they
+ * can handle.
+ */
+ if (this.place_holder) {
+ this.add_proxy_resources (writer.http_server, didl_item);
+ } else {
+ // Add the transcoded/proxy URIs first
+ this.add_proxy_resources (writer.http_server, didl_item);
+
+ // then original URIs
+ bool internal_allowed;
+ internal_allowed = writer.http_server.context.interface == "lo" ||
+ writer.http_server.context.host_ip ==
+ "127.0.0.1";
+ this.add_resources (didl_item, internal_allowed);
+ }
+
+ return didl_item;
+ }
+
+ internal virtual void add_proxy_resources (HTTPServer server,
+ DIDLLiteItem didl_item)
+ throws Error {
+ // Proxy resource for the original resources
+ server.add_proxy_resource (didl_item, this);
+
+ // Transcoding resources
+ server.add_resources (didl_item, this);
+ }
+
+ protected virtual ProtocolInfo get_protocol_info (string? uri,
+ string protocol) {
var protocol_info = new ProtocolInfo ();
protocol_info.mime_type = this.mime_type;
@@ -265,9 +193,7 @@ public class Rygel.MediaItem : MediaObject {
protocol_info.protocol = protocol;
protocol_info.dlna_flags = DLNAFlags.DLNA_V15;
- if (this.upnp_class.has_prefix (MediaItem.IMAGE_CLASS)) {
- protocol_info.dlna_flags |= DLNAFlags.INTERACTIVE_TRANSFER_MODE;
- } else {
+ if (this.streamable ()) {
protocol_info.dlna_flags |= DLNAFlags.STREAMING_TRANSFER_MODE;
}
@@ -282,7 +208,7 @@ public class Rygel.MediaItem : MediaObject {
return protocol_info;
}
- private string get_protocol_for_uri (string uri) throws Error {
+ internal string get_protocol_for_uri (string uri) throws Error {
var scheme = Uri.parse_scheme (uri);
if (scheme == null) {
throw new MediaItemError.BAD_URI (_("Bad URI: %s"), uri);
@@ -305,6 +231,18 @@ public class Rygel.MediaItem : MediaObject {
}
}
+ protected virtual void add_resources (DIDLLiteItem didl_item,
+ bool allow_internal)
+ throws Error {
+ foreach (var uri in this.uris) {
+ var protocol = this.get_protocol_for_uri (uri);
+
+ if (allow_internal || protocol != "internal") {
+ this.add_resource (didl_item, uri, protocol);
+ }
+ }
+ }
+
private int compare_by_date (MediaItem item) {
if (this.date == null) {
return -1;
diff --git a/src/rygel/rygel-mp2ts-transcoder.vala b/src/rygel/rygel-mp2ts-transcoder.vala
index 43f578c..772e8fb 100644
--- a/src/rygel/rygel-mp2ts-transcoder.vala
+++ b/src/rygel/rygel-mp2ts-transcoder.vala
@@ -51,7 +51,7 @@ internal class Rygel.MP2TSTranscoder : Rygel.Transcoder {
private MP2TSProfile profile;
public MP2TSTranscoder (MP2TSProfile profile) {
- base ("video/mpeg", PROFILES[profile], MediaItem.VIDEO_CLASS);
+ base ("video/mpeg", PROFILES[profile], VideoItem.UPNP_CLASS);
this.profile = profile;
}
@@ -78,22 +78,23 @@ internal class Rygel.MP2TSTranscoder : Rygel.Transcoder {
}
public override uint get_distance (MediaItem item) {
- if (!item.upnp_class.has_prefix (MediaItem.VIDEO_CLASS)) {
+ if (!(item is VideoItem)) {
return uint.MAX;
}
+ var video_item = item as VideoItem;
var distance = uint.MIN;
- if (item.bitrate > 0) {
- distance += (item.bitrate - BITRATE).abs ();
+ if (video_item.bitrate > 0) {
+ distance += (video_item.bitrate - BITRATE).abs ();
}
- if (item.width > 0) {
- distance += (item.width - WIDTH[this.profile]).abs ();
+ if (video_item.width > 0) {
+ distance += (video_item.width - WIDTH[this.profile]).abs ();
}
- if (item.height > 0) {
- distance += (item.height - HEIGHT[this.profile]).abs ();
+ if (video_item.height > 0) {
+ distance += (video_item.height - HEIGHT[this.profile]).abs ();
}
return distance;
@@ -120,9 +121,15 @@ internal class Rygel.MP2TSTranscoder : Rygel.Transcoder {
int pixel_w;
int pixel_h;
- if (item.pixel_width > 0 && item.pixel_height > 0) {
- pixel_w = item.width * HEIGHT[this.profile] * item.pixel_width;
- pixel_h = item.height * WIDTH[this.profile] * item.pixel_height;
+ var video_item = item as VideoItem;
+
+ if (video_item.pixel_width > 0 && video_item.pixel_height > 0) {
+ pixel_w = video_item.width *
+ HEIGHT[this.profile] *
+ video_item.pixel_width;
+ pixel_h = video_item.height *
+ WIDTH[this.profile] *
+ video_item.pixel_height;
} else {
// Original pixel-ratio not provided, lets just use 1:1
pixel_w = 1;
diff --git a/src/rygel/rygel-mp3-transcoder.vala b/src/rygel/rygel-mp3-transcoder.vala
index 0c2f494..73e6151 100644
--- a/src/rygel/rygel-mp3-transcoder.vala
+++ b/src/rygel/rygel-mp3-transcoder.vala
@@ -39,7 +39,7 @@ internal class Rygel.MP3Transcoder : Rygel.Transcoder {
private MP3Layer layer;
public MP3Transcoder (MP3Layer layer) {
- base ("audio/mpeg", "MP3", MediaItem.AUDIO_CLASS);
+ base ("audio/mpeg", "MP3", AudioItem.UPNP_CLASS);
this.layer = layer;
}
@@ -65,14 +65,15 @@ internal class Rygel.MP3Transcoder : Rygel.Transcoder {
}
public override uint get_distance (MediaItem item) {
- if (!item.upnp_class.has_prefix (MediaItem.AUDIO_CLASS)) {
+ if (!(item is AudioItem)) {
return uint.MAX;
}
+ var audio_item = item as AudioItem;
var distance = uint.MIN;
- if (item.bitrate > 0) {
- distance += (item.bitrate - BITRATE).abs ();
+ if (audio_item.bitrate > 0) {
+ distance += (audio_item.bitrate - BITRATE).abs ();
}
return distance;
diff --git a/src/rygel/rygel-music-item.vala b/src/rygel/rygel-music-item.vala
new file mode 100644
index 0000000..3885c13
--- /dev/null
+++ b/src/rygel/rygel-music-item.vala
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2008 Zeeshan Ali <zeenix gmail com>.
+ * Copyright (C) 2010 Nokia Corporation.
+ *
+ * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ * <zeeshan ali nokia 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 GUPnP;
+using Gst;
+
+/**
+ * Represents a music item.
+ */
+public class Rygel.MusicItem : AudioItem {
+ public new const string UPNP_CLASS = "object.item.audioItem.musicTrack";
+
+ public string artist;
+ public string album;
+ public string genre;
+ public int track_number = -1;
+
+ public Thumbnail album_art;
+
+ public MusicItem (string id,
+ MediaContainer parent,
+ string title,
+ string upnp_class = MusicItem.UPNP_CLASS) {
+ base (id, parent, title, upnp_class);
+ }
+
+ public void lookup_album_art () {
+ assert (this.album_art == null);
+
+ var media_art_store = MediaArtStore.get_default ();
+ if (media_art_store == null) {
+ return;
+ }
+
+ try {
+ this.album_art = media_art_store.find_media_art_any (this);
+ } catch (Error err) {};
+ }
+
+ internal override void add_resources (DIDLLiteItem didl_item,
+ bool allow_internal)
+ throws Error {
+ base.add_resources (didl_item, allow_internal);
+
+ if (this.album_art != null) {
+ var protocol = this.get_protocol_for_uri (this.album_art.uri);
+
+ if (allow_internal || protocol != "internal") {
+ album_art.add_resource (didl_item, protocol);
+ }
+ }
+ }
+
+ internal override int compare_by_property (MediaObject media_object,
+ string property) {
+ var item = media_object as MusicItem;
+
+ switch (property) {
+ case "dc:artist":
+ return this.compare_string_props (this.artist, item.artist);
+ case "upnp:album":
+ return this.compare_string_props (this.album, item.album);
+ default:
+ return base.compare_by_property (item, property);
+ }
+ }
+
+ internal override DIDLLiteItem serialize (DIDLLiteWriter writer)
+ throws Error {
+ var didl_item = base.serialize (writer);
+
+ if (this.artist != null && this.artist != "") {
+ var contributor = didl_item.add_artist ();
+ contributor.name = this.artist;
+ }
+
+ if (this.track_number >= 0) {
+ didl_item.track_number = this.track_number;
+ }
+
+ if (this.album != null && this.album != "") {
+ didl_item.album = this.album;
+ }
+
+ if (this.genre != null && this.genre != "") {
+ didl_item.genre = this.genre;
+ }
+
+ return didl_item;
+ }
+
+ internal override void add_proxy_resources (HTTPServer server,
+ DIDLLiteItem didl_item)
+ throws Error {
+ base.add_proxy_resources (server, didl_item);
+
+ // Album-art URI comes in the end
+ if (this.album_art != null && server.need_proxy (this.album_art.uri)) {
+ var uri = album_art.uri; // Save the original URI
+
+ album_art.uri = server.create_uri_for_item (this, 0, -1, null);
+ album_art.add_resource (didl_item, server.get_protocol ());
+
+ // Now restore the original URI
+ album_art.uri = uri;
+ }
+ }
+}
diff --git a/src/rygel/rygel-photo-item.vala b/src/rygel/rygel-photo-item.vala
new file mode 100644
index 0000000..df46cb1
--- /dev/null
+++ b/src/rygel/rygel-photo-item.vala
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 Zeeshan Ali <zeenix gmail com>.
+ * Copyright (C) 2010 Nokia Corporation.
+ *
+ * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ * <zeeshan ali nokia 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 GUPnP;
+using Gee;
+using Gst;
+
+/**
+ * Represents a photo item.
+ */
+public class Rygel.PhotoItem : ImageItem {
+ public new const string UPNP_CLASS = "object.item.imageItem.photo";
+
+ public string creator;
+
+ public PhotoItem (string id,
+ MediaContainer parent,
+ string title,
+ string upnp_class = PhotoItem.UPNP_CLASS) {
+ base (id, parent, title, upnp_class);
+ }
+
+ internal override int compare_by_property (MediaObject media_object,
+ string property) {
+ var item = media_object as PhotoItem;
+
+ switch (property) {
+ case "dc:creator":
+ return this.compare_string_props (this.creator, item.creator);
+ default:
+ return base.compare_by_property (item, property);
+ }
+ }
+
+ internal override DIDLLiteItem serialize (DIDLLiteWriter writer)
+ throws Error {
+ var didl_item = base.serialize (writer);
+
+ if (this.creator != null && this.creator != "") {
+ var contributor = didl_item.add_creator ();
+ contributor.name = this.creator;
+ }
+
+ return didl_item;
+ }
+}
diff --git a/src/rygel/rygel-relational-expression.vala b/src/rygel/rygel-relational-expression.vala
index 90a5d1e..24d3348 100644
--- a/src/rygel/rygel-relational-expression.vala
+++ b/src/rygel/rygel-relational-expression.vala
@@ -47,12 +47,12 @@ public class Rygel.RelationalExpression :
var container = media_object as MediaContainer;
return this.compare_create_class (container);
case "dc:creator":
- if (!(media_object is MediaItem)) {
+ if (!(media_object is PhotoItem)) {
return false;
}
- var item = media_object as MediaItem;
- return this.compare_string (item.author);
+ var photo = media_object as PhotoItem;
+ return this.compare_string (photo.creator);
default:
return false;
}
diff --git a/src/rygel/rygel-transcode-manager.vala b/src/rygel/rygel-transcode-manager.vala
index a8f83b8..f6dff1e 100644
--- a/src/rygel/rygel-transcode-manager.vala
+++ b/src/rygel/rygel-transcode-manager.vala
@@ -88,9 +88,8 @@ internal abstract class Rygel.TranscodeManager : GLib.Object {
int subtitle_index,
string? transcode_target);
- public virtual void add_resources (DIDLLiteItem didl_item,
- MediaItem item)
- throws Error {
+ public void add_resources (DIDLLiteItem didl_item, MediaItem item)
+ throws Error {
var list = new GLib.List<Transcoder> ();
foreach (var transcoder in this.transcoders) {
diff --git a/src/rygel/rygel-transcoder.vala b/src/rygel/rygel-transcoder.vala
index fe6c8c2..3b9e394 100644
--- a/src/rygel/rygel-transcoder.vala
+++ b/src/rygel/rygel-transcoder.vala
@@ -79,7 +79,7 @@ internal abstract class Rygel.Transcoder : GLib.Object {
protocol_info.dlna_flags = DLNAFlags.STREAMING_TRANSFER_MODE |
DLNAFlags.SENDER_PACED |
DLNAFlags.DLNA_V15;
- if (item.duration > 0) {
+ if (item is AudioItem && (item as AudioItem).duration > 0) {
protocol_info.dlna_operation = DLNAOperation.TIMESEEK;
} else {
protocol_info.dlna_operation = DLNAOperation.NONE;
diff --git a/src/rygel/rygel-video-item.vala b/src/rygel/rygel-video-item.vala
new file mode 100644
index 0000000..4a2ef74
--- /dev/null
+++ b/src/rygel/rygel-video-item.vala
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2008 Zeeshan Ali <zeenix gmail com>.
+ * Copyright (C) 2010 Nokia Corporation.
+ *
+ * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ * <zeeshan ali nokia 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 GUPnP;
+using Gee;
+using Gst;
+
+/**
+ * Represents a video item.
+ */
+public class Rygel.VideoItem : AudioItem, VisualItem {
+ public new const string UPNP_CLASS = "object.item.videoItem";
+
+ public string author;
+
+ public int width { get; set; default = -1; }
+ public int height { get; set; default = -1; }
+ public int pixel_width { get; set; default = -1; }
+ public int pixel_height { get; set; default = -1; }
+ public int color_depth { get; set; default = -1; }
+
+ public ArrayList<Thumbnail> thumbnails { get; protected set; }
+ public ArrayList<Subtitle> subtitles;
+
+ public VideoItem (string id,
+ MediaContainer parent,
+ string title,
+ string upnp_class = VideoItem.UPNP_CLASS) {
+ base (id, parent, title, upnp_class);
+
+ this.thumbnails = new ArrayList<Thumbnail> ();
+ this.subtitles = new ArrayList<Subtitle> ();
+ }
+
+ public override bool streamable () {
+ return true;
+ }
+
+ public override void add_uri (string uri) {
+ base.add_uri (uri);
+
+ this.add_thumbnail_for_uri (uri);
+
+ var subtitle_manager = SubtitleManager.get_default ();
+
+ if (subtitle_manager != null) {
+ try {
+ var subtitle = subtitle_manager.get_subtitle (uri);
+ this.subtitles.add (subtitle);
+ } catch (Error err) {}
+ }
+ }
+
+ internal override void add_resources (DIDLLiteItem didl_item,
+ bool allow_internal)
+ throws Error {
+ foreach (var subtitle in this.subtitles) {
+ var protocol = this.get_protocol_for_uri (subtitle.uri);
+
+ if (allow_internal || protocol != "internal") {
+ subtitle.add_didl_node (didl_item);
+ }
+ }
+
+ base.add_resources (didl_item, allow_internal);
+
+ add_thumbnail_resources (didl_item, allow_internal);
+ }
+
+ internal override DIDLLiteResource add_resource (
+ DIDLLiteItem didl_item,
+ string? uri,
+ string protocol,
+ string? import_uri = null)
+ throws Error {
+ var res = base.add_resource (didl_item, uri, protocol, import_uri);
+
+ this.add_visual_props (res);
+
+ return res;
+ }
+
+ internal override int compare_by_property (MediaObject media_object,
+ string property) {
+ var item = media_object as VideoItem;
+
+ switch (property) {
+ case "dc:author":
+ return this.compare_string_props (this.author, item.author);
+ default:
+ return base.compare_by_property (item, property);
+ }
+ }
+
+ internal override DIDLLiteItem serialize (DIDLLiteWriter writer)
+ throws Error {
+ var didl_item = base.serialize (writer);
+
+ if (this.author != null && this.author != "") {
+ var contributor = didl_item.add_author ();
+ contributor.name = this.author;
+ }
+
+ return didl_item;
+ }
+
+ internal override void add_proxy_resources (HTTPServer server,
+ DIDLLiteItem didl_item)
+ throws Error {
+ // Subtitles first
+ foreach (var subtitle in this.subtitles) {
+ if (server.need_proxy (subtitle.uri)) {
+ var uri = subtitle.uri; // Save the original URI
+ var index = this.subtitles.index_of (subtitle);
+
+ subtitle.uri = server.create_uri_for_item (this,
+ -1,
+ index,
+ null);
+ subtitle.add_didl_node (didl_item);
+
+ // Now restore the original URI
+ subtitle.uri = uri;
+ }
+ }
+
+ base.add_proxy_resources (server, didl_item);
+
+ // Thumbnails comes in the end
+ this.add_thumbnail_proxy_resources (server, didl_item);
+ }
+}
diff --git a/src/rygel/rygel-visual-item.vala b/src/rygel/rygel-visual-item.vala
new file mode 100644
index 0000000..e57132f
--- /dev/null
+++ b/src/rygel/rygel-visual-item.vala
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008 Zeeshan Ali <zeenix gmail com>.
+ * Copyright (C) 2010 Nokia Corporation.
+ *
+ * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ * <zeeshan ali nokia 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 GUPnP;
+using Gee;
+using Gst;
+
+/**
+ * An interface that visual (video and image) items must implement.
+ */
+public interface Rygel.VisualItem : MediaItem {
+ public abstract int width { get; set; }
+ public abstract int height { get; set; }
+ public abstract int pixel_width { get; set; }
+ public abstract int pixel_height { get; set; }
+ public abstract int color_depth { get; set; }
+
+ public abstract ArrayList<Thumbnail> thumbnails { get; protected set; }
+
+ internal void add_thumbnail_for_uri (string uri) {
+ // Lets see if we can provide the thumbnails
+ var thumbnailer = Thumbnailer.get_default ();
+
+ if (thumbnailer != null) {
+ try {
+ var thumb = thumbnailer.get_thumbnail (uri);
+ this.thumbnails.add (thumb);
+ } catch (Error err) {}
+ }
+ }
+
+ internal void add_thumbnail_resources (DIDLLiteItem didl_item,
+ bool allow_internal)
+ throws Error {
+ foreach (var thumbnail in this.thumbnails) {
+ var protocol = this.get_protocol_for_uri (thumbnail.uri);
+
+ if (allow_internal || protocol != "internal") {
+ thumbnail.add_resource (didl_item, protocol);
+ }
+ }
+ }
+
+ internal void add_visual_props (DIDLLiteResource res) {
+ res.width = this.width;
+ res.height = this.height;
+ res.color_depth = this.color_depth;
+ }
+
+ internal void add_thumbnail_proxy_resources (HTTPServer server,
+ DIDLLiteItem didl_item)
+ throws Error {
+ foreach (var thumbnail in this.thumbnails) {
+ if (server.need_proxy (thumbnail.uri)) {
+ var uri = thumbnail.uri; // Save the original URI
+ var index = this.thumbnails.index_of (thumbnail);
+
+ thumbnail.uri = server.create_uri_for_item (this,
+ index,
+ -1,
+ null);
+ thumbnail.add_resource (didl_item, server.get_protocol ());
+
+ // Now restore the original URI
+ thumbnail.uri = uri;
+ }
+ }
+ }
+}
diff --git a/src/rygel/rygel-wma-transcoder.vala b/src/rygel/rygel-wma-transcoder.vala
index f356f6c..c18fc04 100644
--- a/src/rygel/rygel-wma-transcoder.vala
+++ b/src/rygel/rygel-wma-transcoder.vala
@@ -28,7 +28,7 @@ internal class Rygel.WMATranscoder : Rygel.Transcoder {
private const string CONVERT_SINK_PAD = "convert-sink-pad";
public WMATranscoder () {
- base ("audio/x-wma", "WMA", MediaItem.AUDIO_CLASS);
+ base ("audio/x-wma", "WMA", AudioItem.UPNP_CLASS);
}
public override Element create_source (MediaItem item,
@@ -52,14 +52,15 @@ internal class Rygel.WMATranscoder : Rygel.Transcoder {
}
public override uint get_distance (MediaItem item) {
- if (!item.upnp_class.has_prefix (MediaItem.AUDIO_CLASS)) {
+ if (!(item is AudioItem)) {
return uint.MAX;
}
+ var audio_item = item as AudioItem;
var distance = uint.MIN;
- if (item.bitrate > 0) {
- distance += (item.bitrate - BITRATE).abs ();
+ if (audio_item.bitrate > 0) {
+ distance += (audio_item.bitrate - BITRATE).abs ();
}
return distance;
diff --git a/src/rygel/rygel-wmv-transcoder.vala b/src/rygel/rygel-wmv-transcoder.vala
index 5f3b375..18a4744 100644
--- a/src/rygel/rygel-wmv-transcoder.vala
+++ b/src/rygel/rygel-wmv-transcoder.vala
@@ -32,7 +32,7 @@ internal class Rygel.WMVTranscoder : Rygel.Transcoder {
private const string VIDEO_SCALE = "videoscale";
public WMVTranscoder () {
- base ("video/x-ms-wmv", "WMVHIGH_FULL", MediaItem.VIDEO_CLASS);
+ base ("video/x-ms-wmv", "WMVHIGH_FULL", VideoItem.UPNP_CLASS);
}
public override Element create_source (MediaItem item,
@@ -49,22 +49,25 @@ internal class Rygel.WMVTranscoder : Rygel.Transcoder {
if (resource == null)
return null;
- resource.width = item.width;
- resource.height = item.height;
+ var video_item = item as VideoItem;
+
+ resource.width = video_item.width;
+ resource.height = video_item.height;
resource.bitrate = (VIDEO_BITRATE + WMATranscoder.BITRATE) * 1000 / 8;
return resource;
}
public override uint get_distance (MediaItem item) {
- if (!item.upnp_class.has_prefix (MediaItem.VIDEO_CLASS)) {
+ if (!(item is VideoItem)) {
return uint.MAX;
}
+ var video_item = item as VideoItem;
var distance = uint.MIN;
- if (item.bitrate > 0) {
- distance += (item.bitrate - BITRATE).abs ();
+ if (video_item.bitrate > 0) {
+ distance += (video_item.bitrate - BITRATE).abs ();
}
return distance;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]