[Rhythmbox-devel] MPEG-4 metadata loading
- From: Bastien Nocera <hadess hadess net>
- To: Rhythmbox Dev <rhythmbox-devel gnome org>
- Cc: Matthias Saou <matthias rpmforge net>
- Subject: [Rhythmbox-devel] MPEG-4 metadata loading
- Date: Mon, 17 Nov 2003 22:15:09 +0000
Heya,
Here we go, iTunes can encode them, we play them.
We use libmp4v2 from libfaad2 to get the metadata and all. The xine-lib
backend can play them back out of the box, no idea about GStreamer.
About the patch:
- configure checks for mp4.h and mpeg4ip.h
- add the audio/x-m4a mime-type as supported (requires CVS HEAD
gnome-mime-data)
- MP4 stream metadata implementation (new files)
- change the name of the xine backend to "xine-lib"
- parsing fixes for directory loading
Note that the faad2-devel package on freshrpms.net contains a couple of
bugs that might break the build:
- mp4.h and mpeg4ip.h headers missing
- the stock mpeg4ip.h includes a non-existant (and not needed afaics)
systems.h file)
- libmp4v2.so isn't linked against libstdc++ (bit of a bummer, worked
around in the configure.ac patch)
Matthias, I hope you can fix those for us :)
TODO (but not by me):
- be able to load non-local files using gnome-vfs with the file
callbacks (see MP4ReadCb)
- setting the metadata (the API is neato, this is like 30 minutes work,
get_value and set the metadata)
Cheers
---
Bastien Nocera <hadess@hadess.net>
McMurphy fell 12 stories, hitting the pavement like a paper bag filled
with vegetable soup.
Index: configure.ac
===================================================================
RCS file: /cvs/gnome/rhythmbox/configure.ac,v
retrieving revision 1.58
diff -u -r1.58 configure.ac
--- configure.ac 12 Nov 2003 19:01:12 -0000 1.58
+++ configure.ac 17 Nov 2003 22:03:22 -0000
@@ -188,6 +188,21 @@
fi
AM_CONDITIONAL(HAVE_MP3,test "x$enable_mp3" = "xyes")
+dnl Check for libmp4v2
+
+AC_ARG_ENABLE(mp4, AC_HELP_STRING([--disable-mp4],
+ [don't build with MPEG-4 support]))
+if test "x$enable_mp4" != "xno"; then
+ AC_CHECK_HEADER(mp4.h, [
+ AC_CHECK_HEADER(mpeg4ip.h, [enable_mp4=yes],)],)
+fi
+if test "x$enable_mp4" != "xno"; then
+ LIBS="$LIBS -lmp4v2 -lstdc++"
+ AC_DEFINE(HAVE_MP4,,[Define if we have MPEG-4 support])
+fi
+
+AM_CONDITIONAL(HAVE_MP4, test "x$enable_mp4" = "xyes")
+
dnl Check for Ogg Vorbis
AC_ARG_ENABLE(vorbis, AC_HELP_STRING([--disable-vorbis],
@@ -417,6 +432,11 @@
AC_MSG_NOTICE([ FLAC support is disabled])
else
AC_MSG_NOTICE([** FLAC support is enabled])
+fi
+if test x"$enable_mp4" != "xyes"; then
+ AC_MSG_NOTICE([ MPEG-4 support is disabled])
+else
+ AC_MSG_NOTICE([** MPEG-4 support is enabled])
fi
dnl if test x"$enable_musicbrainz" != "xyes"; then
dnl AC_MSG_NOTICE([ MusicBrainz support is disabled])
Index: lib/rb-playlist.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/lib/rb-playlist.c,v
retrieving revision 1.5
diff -u -r1.5 rb-playlist.c
--- lib/rb-playlist.c 5 Nov 2003 17:16:42 -0000 1.5
+++ lib/rb-playlist.c 17 Nov 2003 22:03:25 -0000
@@ -937,7 +937,7 @@
info = gnome_vfs_file_info_new ();
res = gnome_vfs_directory_read_next (handle, info);
while (res == GNOME_VFS_OK) {
- char *fullpath;
+ char *str, *fullpath;
if (info->name != NULL && (strcmp (info->name, ".") == 0
|| strcmp (info->name, "..") == 0)) {
@@ -945,13 +945,18 @@
continue;
}
- fullpath = g_build_filename (G_DIR_SEPARATOR_S,
+ str = g_build_filename (G_DIR_SEPARATOR_S,
url, info->name, NULL);
- if (rb_playlist_parse (playlist, strstr (fullpath, "://")
- ? fullpath + 1 : fullpath) != FALSE) {
- retval = TRUE;
- }
- g_free (fullpath);
+ if (strstr (str, "://") != NULL)
+ fullpath = str + 1;
+ else
+ fullpath = str;
+
+ if (rb_playlist_parse (playlist, fullpath) == FALSE)
+ rb_playlist_add_one_url (playlist, fullpath, NULL);
+
+ retval = TRUE;
+ g_free (str);
res = gnome_vfs_directory_read_next (handle, info);
}
Index: monkey-media/monkey-media.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/monkey-media/monkey-media.c,v
retrieving revision 1.5
diff -u -r1.5 monkey-media.c
--- monkey-media/monkey-media.c 16 Nov 2003 17:59:08 -0000 1.5
+++ monkey-media/monkey-media.c 17 Nov 2003 22:03:26 -0000
@@ -55,6 +55,9 @@
#ifdef HAVE_FLAC
#include "flac-stream-info-impl.h"
#endif
+#ifdef HAVE_MP4
+#include "mp4-stream-info-impl.h"
+#endif
static void monkey_media_init_internal (void);
static void monkey_media_audio_driver_changed (GConfClient *client, guint cnxn_id,
@@ -197,6 +200,10 @@
TYPE_MP3_STREAM_INFO_IMPL);
register_type ("audio/x-wav",
TYPE_MP3_STREAM_INFO_IMPL);
+#endif
+#ifdef HAVE_MP4
+ register_type ("audio/x-m4a",
+ TYPE_MP4_STREAM_INFO_IMPL);
#endif
#ifdef HAVE_AUDIOCD
register_type ("audiocd",
Index: monkey-media/stream-info-impl/Makefile.am
===================================================================
RCS file: /cvs/gnome/rhythmbox/monkey-media/stream-info-impl/Makefile.am,v
retrieving revision 1.4
diff -u -r1.4 Makefile.am
--- monkey-media/stream-info-impl/Makefile.am 16 Nov 2003 16:56:43 -0000 1.4
+++ monkey-media/stream-info-impl/Makefile.am 17 Nov 2003 22:03:26 -0000
@@ -28,6 +28,10 @@
libstream_info_impl_la_SOURCES += mp3-stream-info-impl.c mp3-stream-info-impl.h
endif
+if HAVE_MP4
+libstream_info_impl_la_SOURCES += mp4-stream-info-impl.c mp4-stream-info-impl.h
+endif
+
INCLUDES = \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
-DG_LOG_DOMAIN=\"MonkeyMedia\" \
Index: monkey-media/stream-info-impl/mp4-stream-info-impl.c
===================================================================
RCS file: monkey-media/stream-info-impl/mp4-stream-info-impl.c
diff -N monkey-media/stream-info-impl/mp4-stream-info-impl.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ monkey-media/stream-info-impl/mp4-stream-info-impl.c 17 Nov 2003 22:03:27 -0000
@@ -0,0 +1,511 @@
+/* monkey-sound
+ *
+ * arch-tag: Implementation of MP4 metadata loading
+ *
+ * Copyright (C) 2003 Bastien Nocera <hadess@hadess.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <libgnomevfs/gnome-vfs.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <mp4.h>
+
+#include "rb-string-helpers.h"
+
+#include "monkey-media-stream-info.h"
+#include "monkey-media-private.h"
+
+#include "mp4-stream-info-impl.h"
+
+/* MP4 audio type */
+#define MP4_MPEG4_AUDIO_TYPE 0x40
+
+static void MP4_stream_info_impl_class_init (MP4StreamInfoImplClass *klass);
+static void MP4_stream_info_impl_init (MP4StreamInfoImpl *ma);
+static void MP4_stream_info_impl_finalize (GObject *object);
+static void MP4_stream_info_impl_open_stream (MonkeyMediaStreamInfo *info);
+static gboolean MP4_stream_info_impl_get_value (MonkeyMediaStreamInfo *info,
+ MonkeyMediaStreamInfoField field,
+ int index,
+ GValue *value);
+static gboolean MP4_stream_info_impl_set_value (MonkeyMediaStreamInfo *info,
+ MonkeyMediaStreamInfoField field,
+ int index,
+ const GValue *value);
+static int MP4_stream_info_impl_get_n_values (MonkeyMediaStreamInfo *info,
+ MonkeyMediaStreamInfoField field);
+
+struct MP4StreamInfoImplPrivate
+{
+ MP4FileHandle file;
+ int track_id;
+};
+
+static GObjectClass *parent_class = NULL;
+
+GType
+MP4_stream_info_impl_get_type (void)
+{
+ static GType MP4_stream_info_impl_type = 0;
+
+ if (MP4_stream_info_impl_type == 0)
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (MP4StreamInfoImplClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) MP4_stream_info_impl_class_init,
+ NULL,
+ NULL,
+ sizeof (MP4StreamInfoImpl),
+ 0,
+ (GInstanceInitFunc) MP4_stream_info_impl_init
+ };
+
+ MP4_stream_info_impl_type = g_type_register_static (MONKEY_MEDIA_TYPE_STREAM_INFO,
+ "MP4StreamInfoImpl",
+ &our_info, 0);
+ }
+
+ return MP4_stream_info_impl_type;
+}
+
+static void
+MP4_stream_info_impl_class_init (MP4StreamInfoImplClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ MonkeyMediaStreamInfoClass *info_class = MONKEY_MEDIA_STREAM_INFO_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->finalize = MP4_stream_info_impl_finalize;
+
+ info_class->open_stream = MP4_stream_info_impl_open_stream;
+ info_class->get_n_values = MP4_stream_info_impl_get_n_values;
+ info_class->get_value = MP4_stream_info_impl_get_value;
+ info_class->set_value = MP4_stream_info_impl_set_value;
+}
+
+static void
+MP4_stream_info_impl_init (MP4StreamInfoImpl *impl)
+{
+ impl->priv = g_new0 (MP4StreamInfoImplPrivate, 1);
+}
+
+static void
+MP4_stream_info_impl_finalize (GObject *object)
+{
+ MP4StreamInfoImpl *impl;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_MP4_STREAM_INFO_IMPL (object));
+
+ impl = MP4_STREAM_INFO_IMPL (object);
+
+ g_return_if_fail (impl->priv != NULL);
+
+ if (impl->priv->file != 0)
+ MP4Close (impl->priv->file);
+
+ g_free (impl->priv);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+MP4_stream_info_impl_open_stream (MonkeyMediaStreamInfo *info)
+{
+ MP4StreamInfoImpl *impl = MP4_STREAM_INFO_IMPL (info);
+ char *uri, *path;
+ GError *error;
+ int num_tracks, i;
+ gboolean found;
+
+ g_object_get (G_OBJECT (info),
+ "error", &error,
+ "location", &uri,
+ NULL);
+
+ path = g_filename_from_uri (uri, NULL, NULL);
+
+ if (path == NULL)
+ {
+ impl->priv->file = MP4Read (uri, 0);
+ } else {
+ impl->priv->file = MP4Read (path, 0);
+ }
+
+ g_free (path);
+ g_free (uri);
+
+ if (impl->priv->file == 0)
+ {
+ error = g_error_new (MONKEY_MEDIA_STREAM_INFO_ERROR,
+ MONKEY_MEDIA_STREAM_INFO_ERROR_OPEN_FAILED,
+ _("Failed to recognise filetype"));
+ g_object_set (G_OBJECT (info), "error", error, NULL);
+ return;
+ }
+
+ /* Find a sound track */
+ num_tracks = MP4GetNumberOfTracks (impl->priv->file, NULL, 0);
+ found = FALSE;
+ for (i = 0; i < num_tracks; i++)
+ {
+ MP4TrackId track_id;
+ const char *track_type;
+
+ track_id = MP4FindTrackId (impl->priv->file, i, NULL, 0);
+ track_type = MP4GetTrackType (impl->priv->file, track_id);
+
+ /* Did we find an audio track ? */
+ if (strcmp (track_type, MP4_AUDIO_TRACK_TYPE) == 0)
+ {
+ int j;
+ guint8 audio_type;
+
+ j = 0;
+ audio_type = MP4GetTrackAudioType (impl->priv->file,
+ track_id);
+ if (audio_type == MP4_MPEG4_AUDIO_TYPE)
+ {
+ impl->priv->track_id = track_id;
+ found = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (found == FALSE)
+ {
+ error = g_error_new (MONKEY_MEDIA_STREAM_INFO_ERROR,
+ MONKEY_MEDIA_STREAM_INFO_ERROR_OPEN_FAILED,
+ _("Failed to find an audio track"));
+ g_object_set (G_OBJECT (info), "error", error, NULL);
+ return;
+ }
+}
+
+static int
+MP4_stream_info_impl_get_n_values (MonkeyMediaStreamInfo *info,
+ MonkeyMediaStreamInfoField field)
+{
+ MP4StreamInfoImpl *impl;
+ char *tmp;
+ gboolean ret = FALSE;
+
+ g_return_val_if_fail (IS_MP4_STREAM_INFO_IMPL (info), 0);
+
+ impl = MP4_STREAM_INFO_IMPL (info);
+
+ tmp = NULL;
+
+ switch (field)
+ {
+ /* tags */
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_TITLE:
+ MP4GetMetadataName (impl->priv->file, &tmp);
+ ret = (tmp != NULL);
+ g_free (tmp);
+ return ret;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_ARTIST:
+ MP4GetMetadataArtist (impl->priv->file, &tmp);
+ ret = (tmp != NULL);
+ g_free (tmp);
+ return ret;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_ALBUM:
+ MP4GetMetadataAlbum (impl->priv->file, &tmp);
+ ret = (tmp != NULL);
+ g_free (tmp);
+ return ret;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_DATE:
+ MP4GetMetadataYear (impl->priv->file, &tmp);
+ ret = (tmp != NULL);
+ g_free (tmp);
+ return ret;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_GENRE:
+ MP4GetMetadataGenre (impl->priv->file, &tmp);
+ ret = (tmp != NULL);
+ g_free (tmp);
+ return ret;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_COMMENT:
+ MP4GetMetadataComment (impl->priv->file, &tmp);
+ ret = (tmp != NULL);
+ g_free (tmp);
+ return ret;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_TRACK_NUMBER:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_MAX_TRACK_NUMBER:
+ {
+ guint16 track, total_tracks;
+
+ return MP4GetMetadataTrack (impl->priv->file, &track,
+ &total_tracks);
+ }
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_LOCATION:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_DESCRIPTION:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_VERSION:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_ISRC:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_ORGANIZATION:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_COPYRIGHT:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_CONTACT:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_LICENSE:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_PERFORMER:
+ return 0;
+
+ /* generic bits */
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_FILE_SIZE:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_DURATION:
+ return 1;
+
+ /* audio bits */
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_HAS_AUDIO:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_CODEC_INFO:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_BIT_RATE:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_AVERAGE_BIT_RATE:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_VARIABLE_BIT_RATE:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_QUALITY:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_SAMPLE_RATE:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_CHANNELS:
+ return 1;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_SERIAL_NUMBER:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_VENDOR:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_ALBUM_GAIN:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_TRACK_GAIN:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_ALBUM_PEAK:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_TRACK_PEAK:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_TRM_ID:
+ return 0;
+
+ /* video bits */
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_HAS_VIDEO:
+ return 1;
+
+ /* default */
+ default:
+ return 0;
+ }
+}
+
+static gboolean
+MP4_stream_info_impl_get_value (MonkeyMediaStreamInfo *info,
+ MonkeyMediaStreamInfoField field,
+ int index,
+ GValue *value)
+{
+ MP4StreamInfoImpl *impl;
+ char *tmp;
+
+ g_return_val_if_fail (IS_MP4_STREAM_INFO_IMPL (info), FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+
+ impl = MP4_STREAM_INFO_IMPL (info);
+
+ if (MP4_stream_info_impl_get_n_values (info, field) <= 0)
+ return FALSE;
+
+ tmp = NULL;
+
+ switch (field)
+ {
+ /* tags */
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_TITLE:
+ g_value_init (value, G_TYPE_STRING);
+ MP4GetMetadataName (impl->priv->file, &tmp);
+ g_value_set_string (value, tmp);
+ g_free (tmp);
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_ARTIST:
+ g_value_init (value, G_TYPE_STRING);
+ MP4GetMetadataArtist (impl->priv->file, &tmp);
+ g_value_set_string (value, tmp);
+ g_free (tmp);
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_ALBUM:
+ g_value_init (value, G_TYPE_STRING);
+ MP4GetMetadataAlbum (impl->priv->file, &tmp);
+ g_value_set_string (value, tmp);
+ g_free (tmp);
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_DATE:
+ g_value_init (value, G_TYPE_STRING);
+ MP4GetMetadataYear (impl->priv->file, &tmp);
+ g_value_set_string (value, tmp);
+ g_free (tmp);
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_GENRE:
+ g_value_init (value, G_TYPE_STRING);
+ MP4GetMetadataGenre (impl->priv->file, &tmp);
+ g_value_set_string (value, tmp);
+ g_free (tmp);
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_COMMENT:
+ g_value_init (value, G_TYPE_STRING);
+ MP4GetMetadataComment (impl->priv->file, &tmp);
+ g_value_set_string (value, tmp);
+ g_free (tmp);
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_TRACK_NUMBER:
+ {
+ guint16 track, total_tracks;
+
+ g_value_init (value, G_TYPE_INT);
+
+ MP4GetMetadataTrack (impl->priv->file, &track,
+ &total_tracks);
+ g_value_set_int (value, track);
+ }
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_MAX_TRACK_NUMBER:
+ {
+ guint16 track, total_tracks;
+
+ g_value_init (value, G_TYPE_INT);
+
+ MP4GetMetadataTrack (impl->priv->file, &track,
+ &total_tracks);
+ g_value_set_int (value, total_tracks);
+ }
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_LOCATION:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_DESCRIPTION:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_VERSION:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_ISRC:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_ORGANIZATION:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_COPYRIGHT:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_CONTACT:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_LICENSE:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_PERFORMER:
+ g_value_init (value, G_TYPE_STRING);
+ g_value_set_string (value, "");
+ break;
+
+ /* generic bits */
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_FILE_SIZE:
+ {
+ GnomeVFSFileInfo *i;
+ GnomeVFSResult res;
+ char *uri;
+
+ g_object_get (G_OBJECT (info), "location", &uri, NULL);
+
+ g_value_init (value, G_TYPE_LONG);
+
+ i = gnome_vfs_file_info_new ();
+ res = gnome_vfs_get_file_info (uri, i,
+ GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
+ if (res == GNOME_VFS_OK)
+ g_value_set_long (value, i->size);
+ else
+ g_value_set_long (value, 0);
+
+ gnome_vfs_file_info_unref (i);
+ }
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_DURATION:
+ g_value_init (value, G_TYPE_LONG);
+ g_value_set_long (value, MP4ConvertFromTrackDuration
+ (impl->priv->file, impl->priv->track_id,
+ MP4GetTrackDuration (impl->priv->file,
+ impl->priv->track_id),
+ MP4_MSECS_TIME_SCALE) / 1000);
+ break;
+
+ /* audio bits */
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_HAS_AUDIO:
+ g_value_init (value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (value, TRUE);
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_CODEC_INFO:
+ g_value_init (value, G_TYPE_STRING);
+ g_value_set_string (value, _("MPEG-4 audio (MPEG-4 AAC)"));
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_BIT_RATE:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_AVERAGE_BIT_RATE:
+ g_value_init (value, G_TYPE_INT);
+ g_value_set_int (value, MP4GetTrackBitRate (impl->priv->file,
+ impl->priv->track_id) / 1000);
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_QUALITY:
+ g_value_init (value, MONKEY_MEDIA_TYPE_AUDIO_QUALITY);
+ g_value_set_enum (value, monkey_media_audio_quality_from_bit_rate (MP4GetTrackBitRate (impl->priv->file, impl->priv->track_id)));
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_TRM_ID:
+ g_value_init (value, G_TYPE_STRING);
+ g_value_set_string (value, NULL);
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_VARIABLE_BIT_RATE:
+ g_value_init (value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (value, (MP4GetTrackFixedSampleDuration
+ (impl->priv->file, impl->priv->track_id) != MP4_INVALID_DURATION));
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_SAMPLE_RATE:
+ /* FIXME we're lying, we can't possibly use the decoder here */
+ g_value_init (value, G_TYPE_LONG);
+ g_value_set_long (value, 44100);
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_CHANNELS:
+ /* Lying again */
+ g_value_init (value, G_TYPE_INT);
+ g_value_set_int (value, 2);
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_SERIAL_NUMBER:
+ g_value_init (value, G_TYPE_LONG);
+ g_value_set_long (value, 0);
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_VENDOR:
+ g_value_init (value, G_TYPE_STRING);
+ g_value_set_string (value, "");
+ break;
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_ALBUM_GAIN:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_TRACK_GAIN:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_ALBUM_PEAK:
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_TRACK_PEAK:
+ g_value_init (value, G_TYPE_DOUBLE);
+ g_value_set_double (value, 0.0);
+ break;
+
+ /* video bits */
+ case MONKEY_MEDIA_STREAM_INFO_FIELD_HAS_VIDEO:
+ g_value_init (value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (value, FALSE);
+ break;
+
+ /* default */
+ default:
+ g_warning ("Invalid field!");
+ g_value_init (value, G_TYPE_NONE);
+ break;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+MP4_stream_info_impl_set_value (MonkeyMediaStreamInfo *info,
+ MonkeyMediaStreamInfoField field,
+ int index,
+ const GValue *value)
+{
+ /* FIXME */
+ return FALSE;
+}
+
Index: monkey-media/stream-info-impl/mp4-stream-info-impl.h
===================================================================
RCS file: monkey-media/stream-info-impl/mp4-stream-info-impl.h
diff -N monkey-media/stream-info-impl/mp4-stream-info-impl.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ monkey-media/stream-info-impl/mp4-stream-info-impl.h 17 Nov 2003 22:03:27 -0000
@@ -0,0 +1,57 @@
+/* monkey-sound
+ *
+ * arch-tag: Header for MP4 metadata loading
+ *
+ * Copyright (C) 2003 Bastien Nocera <hadess@hadess.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __MP4_STREAM_INFO_IMPL_H
+#define __MP4_STREAM_INFO_IMPL_H
+
+#include <glib-object.h>
+
+#include "monkey-media-stream-info.h"
+
+G_BEGIN_DECLS
+
+#define TYPE_MP4_STREAM_INFO_IMPL (MP4_stream_info_impl_get_type ())
+#define MP4_STREAM_INFO_IMPL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TYPE_MP4_STREAM_INFO_IMPL, MP4StreamInfoImpl))
+#define MP4_STREAM_INFO_IMPL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), TYPE_MP4_STREAM_INFO_IMPL, MP4StreamInfoImplClass))
+#define IS_MP4_STREAM_INFO_IMPL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TYPE_MP4_STREAM_INFO_IMPL))
+#define IS_MP4_STREAM_INFO_IMPL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_MP4_STREAM_INFO_IMPL))
+#define MP4_STREAM_INFO_IMPL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_MP4_STREAM_INFO_IMPL, MP4StreamInfoImplClass))
+
+typedef struct MP4StreamInfoImplPrivate MP4StreamInfoImplPrivate;
+
+typedef struct
+{
+ MonkeyMediaStreamInfo parent;
+
+ MP4StreamInfoImplPrivate *priv;
+} MP4StreamInfoImpl;
+
+typedef struct
+{
+ MonkeyMediaStreamInfoClass parent_class;
+} MP4StreamInfoImplClass;
+
+GType MP4_stream_info_impl_get_type (void);
+
+G_END_DECLS
+
+#endif /* __MP4_STREAM_INFO_IMPL_H */
Index: shell/rb-shell.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/shell/rb-shell.c,v
retrieving revision 1.218
diff -u -r1.218 rb-shell.c
--- shell/rb-shell.c 15 Nov 2003 05:49:19 -0000 1.218
+++ shell/rb-shell.c 17 Nov 2003 22:03:31 -0000
@@ -1599,7 +1599,7 @@
#ifdef HAVE_GSTREAMER
backend = "GStreamer";
#else
- backend = "Xine";
+ backend = "xine-lib";
#endif
#ifdef HAVE_MP3
g_string_append (formats, "MP3 ");
@@ -1610,7 +1610,7 @@
#ifdef HAVE_FLAC
g_string_append (formats, "FLAC ");
#endif
-
+
comment = g_strdup_printf (_("Music management and playback software for GNOME.\nAudio backend: %s\nAudio formats: %s\n"), backend, formats->str);
g_string_free (formats, TRUE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]