GUPNP_VALA_REQUIRED=0.6.7
DBUS_GLIB_REQUIRED=0.74
GSTREAMER_REQUIRED=0.10.23
+GSTREAMER_TAG_REQUIRED=0.10.28
+GSTREAMER_APP_REQUIRED=0.10.28
GIO_REQUIRED=2.16
GEE_REQUIRED=0.5.2
UUID_REQUIRED=1.41.3
if test "x$enable_media_export_plugin" = "xyes";
then
PKG_CHECK_MODULES(LIBSQLITE3, sqlite3 >= $LIBSQLITE3_REQUIRED)
+ PKG_CHECK_MODULES(GSTREAMER_TAG, gstreamer-tag-0.10 >= $GSTREAMER_TAG_REQUIRED);
+ PKG_CHECK_MODULES(GSTREAMER_APP, gstreamer-app-0.10 >= $GSTREAMER_APP_REQUIRED);
fi
# Gettext
$(LIBSQLITE3_CFLAGS) \
$(GEE_CFLAGS) \
$(UUID_CFLAGS) \
+ $(GSTREAMER_TAG_CFLAGS) \
+ $(GSTREAMER_APP_CFLAGS) \
-I$(top_srcdir)/src/rygel -DDATA_DIR='"$(datadir)"' \
-include config.h
rygel-media-export-recursive-file-monitor.vala \
rygel-media-export-harvester.vala \
rygel-media-export-item.vala \
+ rygel-media-export-jpeg-writer.vala \
rygel-media-export-writable-container.vala \
rygel-media-export-object-factory.vala
--pkg libsoup-2.4 \
--pkg gee-1.0 \
--pkg libxml-2.0 \
+ --pkg gstreamer-tag-0.10 \
+ --pkg gstreamer-app-0.10 \
--pkg sqlite3 -g
librygel_media_export_la_LIBADD = $(LIBGUPNP_LIBS) \
$(LIBGUPNP_DLNA_LIBS) \
$(LIBDBUS_GLIB_LIBS) \
$(LIBGSTREAMER_LIBS) \
+ $(GSTREAMER_TAG_LIBS) \
+ $(GSTREAMER_APP_LIBS) \
$(LIBSQLITE3_LIBS) \
$(GEE_LIBS) \
$(UUID_LIBS)
MediaItem.MUSIC_CLASS);
if (audio_info.tags != null) {
- uint tmp;
+ 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;
+ }
+ }
+ uint tmp;
audio_info.tags.get_uint (TAG_BITRATE, out tmp);
this.bitrate = (int) tmp / 8;
}
--- /dev/null
+/*
+ * Copyright (C) 2010 Jens Georg <mail@jensge.org>.
+ *
+ * Author: Jens Georg <mail@jensge.org>
+ *
+ * This file is part of Rygel.
+ *
+ * Rygel is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Rygel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+using Gst;
+
+/**
+ * Utility class to write media-art content to JPEG files
+ *
+ * This uses a gstreamer pipeline to transcode the image tag as contained in
+ * MP3 files. This class is single-shot, use and then throw away.
+ */
+internal class Rygel.MediaExport.JPEGWriter : GLib.Object {
+ private Bin bin;
+ private AppSrc appsrc;
+ private MainLoop loop;
+ private dynamic Element sink;
+
+ public JPEGWriter () throws Error {
+ this.bin = Gst.parse_launch ("appsrc name=src ! decodebin2 ! " +
+ "ffmpegcolorspace ! " +
+ "jpegenc ! giosink name=sink") as Bin;
+ this.appsrc = bin.get_by_name ("src") as AppSrc;
+ this.sink = bin.get_by_name ("sink");
+ var bus = bin.get_bus ();
+ bus.add_signal_watch ();
+ bus.message["eos"].connect(() => { this.loop.quit (); });
+ bus.message["error"].connect(() => { this.loop.quit (); });
+ this.loop = new MainLoop (null, false);
+ }
+
+ /**
+ * Write a Gst.Buffer as retrieved from the Gst.TagList to disk.
+ *
+ * @param buffer The Gst.Buffer as obtained from tag list
+ * @param file A GLib.File pointing to the target location
+ *
+ * FIXME This uses a nested main-loop to block which is ugly.
+ */
+ public void write (Gst.Buffer buffer, File file) {
+ this.sink.file = file;
+ this.appsrc.push_buffer (buffer);
+ this.appsrc.end_of_stream ();
+ this.bin.set_state (State.PLAYING);
+ this.loop.run ();
+ this.bin.set_state (State.NULL);
+ }
+}