* Represents MediaExport item.
*/
public class Rygel.MediaExport.MediaExportItem : Rygel.MediaItem {
- private const string TAG_WIDTH = MetadataExtractor.TAG_RYGEL_WIDTH;
- private const string TAG_HEIGHT = MetadataExtractor.TAG_RYGEL_HEIGHT;
- private const string
- TAG_DLNA_PROFILE = MetadataExtractor.TAG_RYGEL_DLNA_PROFILE;
-
- public static MediaExportItem? create_from_taglist (MediaContainer parent,
- File file,
- Gst.TagList tag_list) {
+ public static MediaExportItem? create_from_info (
+ MediaContainer parent,
+ File file,
+ GUPnP.DLNAInformation dlna_info,
+ string mime,
+ uint64 size,
+ uint64 mtime) {
string id = Checksum.compute_for_string (ChecksumType.MD5,
file.get_uri ());
- int width = -1;
- int height = -1;
- string class_guessed = null;
-
- if (tag_list != null) {
- string codec;
-
- if (!tag_list.get_string (TAG_VIDEO_CODEC, out codec)) {
- if (!tag_list.get_string (TAG_AUDIO_CODEC, out codec)) {
- if (tag_list.get_int (TAG_WIDTH, out width) ||
- tag_list.get_int (TAG_HEIGHT, out height)) {
- class_guessed = Rygel.MediaItem.PHOTO_CLASS;
- } else {
- // if it has width and height and a duration, assume
- // it is a video (to capture the MPEG TS without audio
- // case)
- uint64 duration;
- if (tag_list.get_uint64 (TAG_DURATION,
- out duration)) {
- class_guessed = Rygel.MediaItem.VIDEO_CLASS;
- } else {
- string content_type;
- tag_list.get_string (MetadataExtractor.TAG_RYGEL_MIME,
- out content_type);
- debug (_("File '%s' is of unknown format/type."),
- file.get_uri ());
- debug (_("Trying to guess from content type %s"),
- content_type);
- if (content_type.has_prefix ("video/")) {
- class_guessed = Rygel.MediaItem.VIDEO_CLASS;
- } else if (content_type.has_prefix ("audio/")) {
- class_guessed = Rygel.MediaItem.AUDIO_CLASS;
- } else if (content_type.has_prefix ("image/")) {
- class_guessed = Rygel.MediaItem.PHOTO_CLASS;
- }
-
- if (class_guessed == null) {
- class_guessed = Rygel.MediaItem.AUDIO_CLASS;
- warning (_("Failed to detect UPnP class for '%s', assuming '%s'"),
- file.get_uri (),
- class_guessed);
- }
- }
- }
- } else {
- // MPEG TS streams seem to miss VIDEO_CODEC; so if we have
- // an AUDIO_CODEC and width or height, assume video as
- // well
- if (tag_list.get_int (TAG_WIDTH, out width) ||
- tag_list.get_int (TAG_HEIGHT, out height)) {
- class_guessed = Rygel.MediaItem.VIDEO_CLASS;
- } else {
- class_guessed = Rygel.MediaItem.AUDIO_CLASS;
- }
- }
+ unowned Gst.StreamInformation audio = null;
+ unowned Gst.StreamInformation video = null;
+
+ foreach (unowned Gst.StreamInformation stream_info in
+ dlna_info.info.stream_list) {
+ if (audio == null &&
+ stream_info.streamtype == Gst.StreamType.AUDIO) {
+ audio = stream_info;
+ } else if (video == null &&
+ (stream_info.streamtype == Gst.StreamType.VIDEO ||
+ stream_info.streamtype == Gst.StreamType.IMAGE)) {
+ video = stream_info;
+ }
+ }
+
+ if (video != null) {
+ if (audio == null && video.streamtype == Gst.StreamType.IMAGE) {
+ return new MediaExportItem.photo (
+ parent,
+ id,
+ file,
+ dlna_info,
+ (Gst.StreamVideoInformation) video,
+ mime,
+ size,
+ mtime);
} else {
- class_guessed = Rygel.MediaItem.VIDEO_CLASS;
+ return new MediaExportItem.video (
+ parent,
+ id,
+ file,
+ dlna_info,
+ (Gst.StreamVideoInformation) video,
+ (Gst.StreamAudioInformation) audio,
+ mime,
+ size,
+ mtime);
}
+ } else if (audio != null) {
+ return new MediaExportItem.audio (
+ parent,
+ id,
+ file,
+ dlna_info,
+ (Gst.StreamAudioInformation) audio,
+ mime,
+ size,
+ mtime);
} else {
- // throw error. Taglist can't be empty
- warning (_("Got empty taglist for file %s"), file.get_uri ());
-
return null;
}
+ }
+
+ private MediaExportItem.video (MediaContainer parent,
+ string id,
+ File file,
+ GUPnP.DLNAInformation dlna_info,
+ Gst.StreamVideoInformation? video,
+ Gst.StreamAudioInformation? audio,
+ string mime,
+ uint64 size,
+ uint64 mtime) {
+ this (parent,
+ id,
+ file,
+ dlna_info,
+ mime,
+ size,
+ mtime,
+ MediaItem.VIDEO_CLASS);
+
+ this.width = (int) video.width;
+ this.height = (int) video.height;
+ this.color_depth = (int) video.depth;
+
+ if (video.tags != null) {
+ uint tmp;
+
+ video.tags.get_uint (TAG_BITRATE, out tmp);
+ this.bitrate = (int) tmp / 8;
+ }
- return new MediaExportItem (parent,
- id,
- file,
- tag_list,
- class_guessed);
+ this.n_audio_channels = (int) audio.channels;
+ this.sample_freq = (int) audio.sample_rate;
}
- private MediaExportItem (MediaContainer parent,
- string id,
- File file,
- Gst.TagList tag_list,
- string upnp_class) {
- string title = null;
- if (upnp_class == Rygel.MediaItem.AUDIO_CLASS ||
- upnp_class == Rygel.MediaItem.MUSIC_CLASS) {
+ private MediaExportItem.photo (MediaContainer parent,
+ string id,
+ File file,
+ GUPnP.DLNAInformation dlna_info,
+ Gst.StreamVideoInformation? video,
+ string mime,
+ uint64 size,
+ uint64 mtime) {
+ this (parent,
+ id,
+ file,
+ dlna_info,
+ mime,
+ size,
+ mtime,
+ MediaItem.PHOTO_CLASS);
+
+ this.width = (int) video.width;
+ this.height = (int) video.height;
+ this.color_depth = (int) video.depth;
+ }
- if (!tag_list.get_string (TAG_TITLE, out title)) {
- title = file.get_basename ();
- }
+ private MediaExportItem.audio (MediaContainer parent,
+ string id,
+ File file,
+ GUPnP.DLNAInformation dlna_info,
+ Gst.StreamAudioInformation? audio,
+ string mime,
+ uint64 size,
+ uint64 mtime) {
+ this (parent,
+ id,
+ file,
+ dlna_info,
+ mime,
+ size,
+ mtime,
+ MediaItem.MUSIC_CLASS);
+
+ this.n_audio_channels = (int) audio.channels;
+ this.sample_freq = (int) audio.sample_rate;
+ }
- } else {
+ private MediaExportItem (MediaContainer parent,
+ string id,
+ File file,
+ GUPnP.DLNAInformation dlna_info,
+ string mime,
+ uint64 size,
+ uint64 mtime,
+ string upnp_class) {
+ string title = null;
+
+ if (dlna_info.info.tags == null ||
+ !dlna_info.info.tags.get_string (TAG_TITLE, out title)) {
title = file.get_basename ();
}
- base (id, parent, title, upnp_class);
- tag_list.get_int (TAG_WIDTH, out this.width);
- tag_list.get_int (TAG_HEIGHT, out this.height);
- tag_list.get_int (MetadataExtractor.TAG_RYGEL_DEPTH,
- out this.color_depth);
- uint64 duration;
- tag_list.get_uint64 (TAG_DURATION, out duration);
- this.duration = (duration == -1) ? -1 : (long) (duration / 1000000000);
+ base (id, parent, title, upnp_class);
- tag_list.get_int (MetadataExtractor.TAG_RYGEL_CHANNELS,
- out this.n_audio_channels);
+ if (dlna_info.info.duration > -1) {
+ this.duration = -1;
+ } else {
+ this.duration = dlna_info.info.duration / Gst.SECOND;
+ }
- tag_list.get_string (TAG_ARTIST, out this.author);
- tag_list.get_string (TAG_ALBUM, out this.album);
+ 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);
- uint tmp;
- tag_list.get_uint (TAG_TRACK_NUMBER, out tmp);
- this.track_number = (int) tmp;
- tag_list.get_uint (TAG_BITRATE, out tmp);
- this.bitrate = (int) tmp / 8;
- tag_list.get_int (MetadataExtractor.TAG_RYGEL_RATE,
- out this.sample_freq);
+ 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;
+ } else {
+ TimeVal tv = { (long) mtime, 0 };
+ this.date = tv.to_iso8601 ();
+ }
+ }
- int64 size;
- tag_list.get_int64 (MetadataExtractor.TAG_RYGEL_SIZE,
- out size);
this.size = (long) size;
-
- uint64 mtime;
- tag_list.get_uint64 (MetadataExtractor.TAG_RYGEL_MTIME,
- out mtime);
this.modified = (int64) mtime;
- GLib.Date? date;
- if (tag_list.get_date (TAG_DATE, out date)) {
- char[] datestr = new char[30];
- date.strftime (datestr, "%F");
- this.date = (string) datestr;
+ if (dlna_info.name != null) {
+ this.dlna_profile = dlna_info.name;
+ this.mime_type = dlna_info.mime;
} else {
- TimeVal tv = { (long) mtime, 0 };
- this.date = tv.to_iso8601 ();
+ this.mime_type = mime;
}
- tag_list.get_string (TAG_DLNA_PROFILE, out this.dlna_profile);
- tag_list.get_string (MetadataExtractor.TAG_RYGEL_MIME,
- out this.mime_type);
-
this.add_uri (file.get_uri (), null);
}
}
* metadata_available for each key/value pair extracted.
*/
public class Rygel.MediaExport.MetadataExtractor: GLib.Object {
- public const string TAG_RYGEL_SIZE = "rygel-size";
- public const string TAG_RYGEL_MIME = "rygel-mime";
- public const string TAG_RYGEL_CHANNELS = "rygel-channels";
- public const string TAG_RYGEL_RATE = "rygel-rate";
- public const string TAG_RYGEL_WIDTH = "rygel-width";
- public const string TAG_RYGEL_HEIGHT = "rygel-height";
- public const string TAG_RYGEL_DEPTH = "rygel-depth";
- public const string TAG_RYGEL_MTIME = "rygel-mtime";
- public const string TAG_RYGEL_DLNA_PROFILE = "rygel-dlna-profile";
-
/* Signals */
- public signal void extraction_done (File file, Gst.TagList tag_list);
+ public signal void extraction_done (File file,
+ GUPnP.DLNAInformation info,
+ string mime,
+ uint64 size,
+ uint64 mtime);
/**
* Signalize that an error occured during metadata extraction
private HashMap<string, File> file_hash;
private uint64 timeout = 10; /* seconds */
- private static void register_custom_tag (string tag, Type type) {
- Gst.tag_register (tag,
- TagFlag.META,
- type,
- tag,
- "",
- Gst.tag_merge_use_first);
- }
-
public static MetadataExtractor? create () {
return new MetadataExtractor ();
}
public MetadataExtractor () {
- this.register_custom_tag (TAG_RYGEL_SIZE, typeof (int64));
- this.register_custom_tag (TAG_RYGEL_MIME, typeof (string));
- this.register_custom_tag (TAG_RYGEL_CHANNELS, typeof (int));
- this.register_custom_tag (TAG_RYGEL_RATE, typeof (int));
- this.register_custom_tag (TAG_RYGEL_WIDTH, typeof (int));
- this.register_custom_tag (TAG_RYGEL_HEIGHT, typeof (int));
- this.register_custom_tag (TAG_RYGEL_DEPTH, typeof (int));
- this.register_custom_tag (TAG_RYGEL_MTIME, typeof (uint64));
- this.register_custom_tag (TAG_RYGEL_DLNA_PROFILE, typeof (string));
-
this.file_hash = new HashMap<string, File> ();
this.discoverer = new GUPnP.DLNADiscoverer ((ClockTime)
assert (this.file_hash.has_key (dlna.info.uri));
File file = this.file_hash.get (dlna.info.uri);
- TagList tag_list = new TagList ();
this.file_hash.unset (dlna.info.uri);
}
try {
- this.extract_mime_and_size (file, tag_list);
- this.extract_duration (dlna.info, tag_list);
- this.extract_stream_info (dlna.info, tag_list);
- if (dlna.name != null) {
- tag_list.add (TagMergeMode.REPLACE,
- TAG_RYGEL_DLNA_PROFILE,
- dlna.name);
- tag_list.add (TagMergeMode.REPLACE, TAG_RYGEL_MIME, dlna.mime);
- }
- this.extraction_done (file, tag_list);
+ uint64 size, mtime;
+ string mime;
+
+ this.extract_file_info (file, out mime, out size, out mtime);
+ this.extraction_done (file, dlna, mime, size, mtime);
} catch (Error e) {
debug (_("Failed to extract metadata from %s: %s"),
dlna.info.uri,
this.discoverer.discover_uri (uri);
}
- private void extract_mime_and_size (File file,
- TagList tag_list) throws Error {
+ private void extract_file_info (File file,
+ out string mime,
+ out uint64 size,
+ out uint64 mtime) throws Error {
FileInfo file_info;
try {
}
string content_type = file_info.get_content_type ();
- string mime = g_content_type_get_mime_type (content_type);
-
- if (mime != null) {
- /* add custom mime tag to tag list */
- tag_list.add (TagMergeMode.REPLACE, TAG_RYGEL_MIME, mime);
- }
-
- var size = file_info.get_size ();
- tag_list.add (TagMergeMode.REPLACE, TAG_RYGEL_SIZE, size);
-
- var mtime = file_info.get_attribute_uint64 (
- FILE_ATTRIBUTE_TIME_MODIFIED);
- tag_list.add (TagMergeMode.REPLACE, TAG_RYGEL_MTIME, mtime);
- }
-
- private void extract_duration (Gst.DiscovererInformation info,
- TagList tag_list) {
- tag_list.add (TagMergeMode.REPLACE,
- TAG_DURATION,
- info.duration);
- }
-
- private void extract_stream_info (Gst.DiscovererInformation info,
- TagList tag_list) {
- foreach (unowned Gst.StreamInformation i in info.stream_list) {
- if (i.streamtype == Gst.StreamType.VIDEO) {
- extract_video_info ((Gst.StreamVideoInformation) i, tag_list);
- } else if (i.streamtype == Gst.StreamType.AUDIO) {
- extract_audio_info ((Gst.StreamAudioInformation) i, tag_list);
- }
- }
- }
-
- private void extract_audio_info (Gst.StreamAudioInformation info,
- TagList tag_list) {
- if (info.sample_rate != 0)
- tag_list.add (TagMergeMode.REPLACE,
- TAG_RYGEL_RATE,
- info.sample_rate);
- if (info.channels != 0)
- tag_list.add (TagMergeMode.REPLACE,
- TAG_RYGEL_CHANNELS,
- info.channels);
- }
-
- private void extract_video_info (Gst.StreamVideoInformation info,
- TagList tag_list) {
- if (info.depth != 0)
- tag_list.add (TagMergeMode.REPLACE,
- TAG_RYGEL_DEPTH,
- info.depth);
- if (info.width != 0)
- tag_list.add (TagMergeMode.REPLACE,
- TAG_RYGEL_WIDTH,
- info.width);
- if (info.height != 0)
- tag_list.add (TagMergeMode.REPLACE,
- TAG_RYGEL_HEIGHT,
- info.height);
+ mime = g_content_type_get_mime_type (content_type);
+ size = file_info.get_size ();
+ mtime = file_info.get_attribute_uint64 (FILE_ATTRIBUTE_TIME_MODIFIED);
}
}