From 1a42822d10499925d7d44775e8100aa9b8f0defd Mon Sep 17 00:00:00 2001 From: barbieri Date: Fri, 1 Feb 2008 19:44:51 +0000 Subject: [PATCH] Merge git://staff.get-e.org/users/andrunko/lightmediascanner * git://staff.get-e.org/users/andrunko/lightmediascanner: Make sure metadata is converted to the proper charset. Added mp4 plugin. --- lightmediascanner/configure.ac | 11 + lightmediascanner/src/plugins/Makefile.am | 7 +- lightmediascanner/src/plugins/mp4/Makefile.am | 10 + lightmediascanner/src/plugins/mp4/mp4.c | 231 ++++++++++++++++++++ lightmediascanner/src/plugins/rm/rm.c | 5 +- .../src/plugins/video-dummy/video-dummy.c | 1 - 6 files changed, 262 insertions(+), 3 deletions(-) create mode 100644 lightmediascanner/src/plugins/mp4/Makefile.am create mode 100644 lightmediascanner/src/plugins/mp4/mp4.c diff --git a/lightmediascanner/configure.ac b/lightmediascanner/configure.ac index dcb4817..2ead7f8 100644 --- a/lightmediascanner/configure.ac +++ b/lightmediascanner/configure.ac @@ -52,6 +52,15 @@ define([CHECK_MODULE_OGG], AC_LMS_CHECK_PKG(VORBIS, vorbis, [], [OGG=false]) ]) +AM_CONDITIONAL(HAVE_MP4V2, false) +define([CHECK_MODULE_MP4], +[ + AC_CHECK_LIB(mp4v2, MP4Read, [], [MP4=false]) + MP4V2_LIBS="-lmp4v2" + AC_SUBST(MP4V2_LIBS) +]) + + # plugins declarations AC_LMS_OPTIONAL_MODULE([dummy], true) AC_LMS_OPTIONAL_MODULE([jpeg], true) @@ -64,6 +73,7 @@ AC_LMS_OPTIONAL_MODULE([ogg], true, [CHECK_MODULE_OGG]) AC_LMS_OPTIONAL_MODULE([pls], true) AC_LMS_OPTIONAL_MODULE([asf], true) AC_LMS_OPTIONAL_MODULE([rm], true) +AC_LMS_OPTIONAL_MODULE([mp4], true, [CHECK_MODULE_MP4]) AC_OUTPUT([ lightmediascanner.pc @@ -84,6 +94,7 @@ src/plugins/ogg/Makefile src/plugins/pls/Makefile src/plugins/asf/Makefile src/plugins/rm/Makefile +src/plugins/mp4/Makefile ]) diff --git a/lightmediascanner/src/plugins/Makefile.am b/lightmediascanner/src/plugins/Makefile.am index bd96557..c43537f 100644 --- a/lightmediascanner/src/plugins/Makefile.am +++ b/lightmediascanner/src/plugins/Makefile.am @@ -46,6 +46,10 @@ if USE_MODULE_RM SUBDIRS += rm endif +if USE_MODULE_MP4 +SUBDIRS += mp4 +endif + DIST_SUBDIRS = \ dummy \ jpeg \ @@ -57,4 +61,5 @@ DIST_SUBDIRS = \ ogg \ pls \ asf \ - rm + rm \ + mp4 diff --git a/lightmediascanner/src/plugins/mp4/Makefile.am b/lightmediascanner/src/plugins/mp4/Makefile.am new file mode 100644 index 0000000..340eea5 --- /dev/null +++ b/lightmediascanner/src/plugins/mp4/Makefile.am @@ -0,0 +1,10 @@ +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_srcdir)/src/plugins/mp4 + +pkgdir = $(pluginsdir) +pkg_LTLIBRARIES = mp4.la +mp4_la_SOURCES = mp4.c +mp4_la_DEPENDENCIES = $(top_builddir)/config.h +mp4_la_LIBADD = $(top_builddir)/src/lib/liblightmediascanner.la @MP4V2_LIBS@ +mp4_la_LDFLAGS = -module -avoid-version diff --git a/lightmediascanner/src/plugins/mp4/mp4.c b/lightmediascanner/src/plugins/mp4/mp4.c new file mode 100644 index 0000000..e83a1e8 --- /dev/null +++ b/lightmediascanner/src/plugins/mp4/mp4.c @@ -0,0 +1,231 @@ +/** + * Copyright (C) 2008 by INdT + * + * This program 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. + * + * 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 Lesser 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. + * + * @author Andre Moreira Magalhaes + */ + +/** + * @brief + * + * mp4 file parser. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +enum StreamTypes { + STREAM_TYPE_UNKNOWN = 0, + STREAM_TYPE_AUDIO, + STREAM_TYPE_VIDEO +}; + +struct mp4_info { + struct lms_string_size title; + struct lms_string_size artist; + struct lms_string_size album; + struct lms_string_size genre; +}; + +struct plugin { + struct lms_plugin plugin; + lms_db_audio_t *audio_db; + lms_db_video_t *video_db; +}; + +static const char _name[] = "mp4"; +static const struct lms_string_size _exts[] = { + LMS_STATIC_STRING_SIZE(".mp4") +}; + +static void +_strstrip(char **str, unsigned int *p_len) +{ + if (*str) + lms_strstrip(*str, p_len); + + if (*p_len == 0 && *str) { + free(*str); + *str = NULL; + } +} + +static void * +_match(struct plugin *p, const char *path, int len, int base) +{ + int i; + + i = lms_which_extension(path, len, _exts, LMS_ARRAY_SIZE(_exts)); + if (i < 0) + return NULL; + else + return (void*)(i + 1); +} + +static int +_parse(struct plugin *plugin, struct lms_context *ctxt, const struct lms_file_info *finfo, void *match) +{ + struct mp4_info info = {{0}, {0}, {0}, {0}}; + struct lms_audio_info audio_info = {0, {0}, {0}, {0}, {0}, 0, 0, 0}; + struct lms_video_info video_info = {0, {0}, {0}}; + int r, stream_type = STREAM_TYPE_AUDIO; + MP4FileHandle mp4_fh; + u_int32_t num_tracks; + + mp4_fh = MP4Read(finfo->path, 0); + if (mp4_fh == MP4_INVALID_FILE_HANDLE) { + fprintf(stderr, "ERROR: cannot read mp4 file\n"); + return -1; + } + + MP4GetMetadataName(mp4_fh, &info.title.str); + if (info.title.str) + info.title.len = strlen(info.title.str); + MP4GetMetadataArtist(mp4_fh, &info.artist.str); + if (info.artist.str) + info.artist.len = strlen(info.artist.str); + MP4GetMetadataAlbum(mp4_fh, &info.album.str); + if (info.album.str) + info.album.len = strlen(info.album.str); + MP4GetMetadataGenre(mp4_fh, &info.genre.str); + if (info.genre.str) + info.genre.len = strlen(info.genre.str); + + /* check if the file contains a video track */ + num_tracks = MP4GetNumberOfTracks(mp4_fh, MP4_VIDEO_TRACK_TYPE, 0); + if (num_tracks > 0) + stream_type = STREAM_TYPE_VIDEO; + + _strstrip(&info.title.str, &info.title.len); + _strstrip(&info.artist.str, &info.artist.len); + _strstrip(&info.album.str, &info.album.len); + _strstrip(&info.genre.str, &info.genre.len); + + if (!info.title.str) { + int ext_idx; + ext_idx = ((int)match) - 1; + info.title.len = finfo->path_len - finfo->base - _exts[ext_idx].len; + info.title.str = malloc((info.title.len + 1) * sizeof(char)); + memcpy(info.title.str, finfo->path + finfo->base, info.title.len); + info.title.str[info.title.len] = '\0'; + } + lms_charset_conv(ctxt->cs_conv, &info.title.str, &info.title.len); + + if (info.artist.str) + lms_charset_conv(ctxt->cs_conv, &info.artist.str, &info.artist.len); + if (info.album.str) + lms_charset_conv(ctxt->cs_conv, &info.album.str, &info.album.len); + if (info.genre.str) + lms_charset_conv(ctxt->cs_conv, &info.genre.str, &info.genre.len); + +#if 1 + fprintf(stderr, "file %s info\n", finfo->path); + fprintf(stderr, "\ttitle='%s'\n", info.title.str); + fprintf(stderr, "\tartist='%s'\n", info.artist.str); + fprintf(stderr, "\talbum='%s'\n", info.album.str); + fprintf(stderr, "\tgenre='%s'\n", info.genre.str); +#endif + + if (stream_type == STREAM_TYPE_AUDIO) { + audio_info.id = finfo->id; + audio_info.title = info.title; + audio_info.artist = info.artist; + audio_info.album = info.album; + audio_info.genre = info.genre; + r = lms_db_audio_add(plugin->audio_db, &audio_info); + } + else { + video_info.id = finfo->id; + video_info.title = info.title; + video_info.artist = info.artist; + r = lms_db_video_add(plugin->video_db, &video_info); + } + + MP4Close(mp4_fh); + + if (info.title.str) + free(info.title.str); + if (info.artist.str) + free(info.artist.str); + if (info.album.str) + free(info.album.str); + if (info.genre.str) + free(info.genre.str); + + return r; +} + +static int +_setup(struct plugin *plugin, struct lms_context *ctxt) +{ + plugin->audio_db = lms_db_audio_new(ctxt->db); + if (!plugin->audio_db) + return -1; + plugin->video_db = lms_db_video_new(ctxt->db); + if (!plugin->video_db) + return -1; + + return 0; +} + +static int +_start(struct plugin *plugin, struct lms_context *ctxt) +{ + int r; + r = lms_db_audio_start(plugin->audio_db); + r |= lms_db_video_start(plugin->video_db); + return r; +} + +static int +_finish(struct plugin *plugin, struct lms_context *ctxt) +{ + if (plugin->audio_db) + lms_db_audio_free(plugin->audio_db); + if (plugin->video_db) + lms_db_video_free(plugin->video_db); + + return 0; +} + +static int +_close(struct plugin *plugin) +{ + free(plugin); + return 0; +} + +API struct lms_plugin * +lms_plugin_open(void) +{ + struct plugin *plugin; + + plugin = (struct plugin *)malloc(sizeof(*plugin)); + plugin->plugin.name = _name; + plugin->plugin.match = (lms_plugin_match_fn_t)_match; + plugin->plugin.parse = (lms_plugin_parse_fn_t)_parse; + plugin->plugin.close = (lms_plugin_close_fn_t)_close; + plugin->plugin.setup = (lms_plugin_setup_fn_t)_setup; + plugin->plugin.start = (lms_plugin_start_fn_t)_start; + plugin->plugin.finish = (lms_plugin_finish_fn_t)_finish; + + return (struct lms_plugin *)plugin; +} diff --git a/lightmediascanner/src/plugins/rm/rm.c b/lightmediascanner/src/plugins/rm/rm.c index 3938914..1390a2b 100644 --- a/lightmediascanner/src/plugins/rm/rm.c +++ b/lightmediascanner/src/plugins/rm/rm.c @@ -284,8 +284,11 @@ _parse(struct plugin *plugin, struct lms_context *ctxt, const struct lms_file_in info.title.str = malloc((info.title.len + 1) * sizeof(char)); memcpy(info.title.str, finfo->path + finfo->base, info.title.len); info.title.str[info.title.len] = '\0'; - lms_charset_conv(ctxt->cs_conv, &info.title.str, &info.title.len); } + lms_charset_conv(ctxt->cs_conv, &info.title.str, &info.title.len); + + if (info.artist.str) + lms_charset_conv(ctxt->cs_conv, &info.artist.str, &info.artist.len); #if 0 fprintf(stderr, "file %s info\n", finfo->path); diff --git a/lightmediascanner/src/plugins/video-dummy/video-dummy.c b/lightmediascanner/src/plugins/video-dummy/video-dummy.c index 85e9822..affceb0 100644 --- a/lightmediascanner/src/plugins/video-dummy/video-dummy.c +++ b/lightmediascanner/src/plugins/video-dummy/video-dummy.c @@ -42,7 +42,6 @@ static const struct lms_string_size _exts[] = { LMS_STATIC_STRING_SIZE(".mpeg"), LMS_STATIC_STRING_SIZE(".3gp"), LMS_STATIC_STRING_SIZE(".ram"), - LMS_STATIC_STRING_SIZE(".mp4"), LMS_STATIC_STRING_SIZE(".ogm"), }; -- 1.7.9.5