diff --git a/amarok/configure.in.in b/amarok/configure.in.in index 67f53d6c..9c7be42d 100644 --- a/amarok/configure.in.in +++ b/amarok/configure.in.in @@ -995,15 +995,29 @@ if test "$have_mp4v2" != "no"; then ac_cppflags_save=$CPPFLAGS CPPFLAGS="$CPPFLAGS -I." AC_CHECK_HEADERS(systems.h) - AC_CHECK_HEADERS([mp4v2/mp4v2.h], [have_mp4_h=yes], [], + AC_CHECK_HEADERS([mp4v2/mp4v2.h], [have_mp4v2_h=yes], [], [#ifdef HAVE_SYSTEMS_H # include #endif ]) + if test "$have_mp4v2_h" = "yes"; then + AC_DEFINE(HAVE_MP4V2_H, 1, [have mp4v2 h]) + else + AC_CHECK_HEADERS([mp4.h], [have_mp4_h=yes], [], + [#ifdef HAVE_SYSTEMS_H + # include + #endif + ]) + if test "$have_mp4_h" = "yes"; then + AC_DEFINE(HAVE_MP4_H, 1, [have mp4 h]) + fi + fi - AC_CHECK_LIB( mp4v2, MP4Read, have_mp4v2=yes, have_mp4v2=no ) + if test "$have_mp4v2_h" = "yes" -o "$have_mp4_h" = "yes"; then + AC_CHECK_LIB( mp4v2, MP4Read, have_mp4v2=yes, have_mp4v2=no ) + fi - if test "$have_mp4v2" = "yes" -a "$have_mp4_h" = "yes"; then + if test "$have_mp4v2" = "yes"; then AC_DEFINE(HAVE_MP4V2, 1, [have mp4v2]) MP4V2_INCLUDES="-I$mp4v2_dir/include" MP4V2_LIBS="-L$mp4v2_dir/lib -lmp4v2" diff --git a/amarok/src/metadata/mp4/mp4file.cpp b/amarok/src/metadata/mp4/mp4file.cpp index 3019e37a..536955c3 100644 --- a/amarok/src/metadata/mp4/mp4file.cpp +++ b/amarok/src/metadata/mp4/mp4file.cpp @@ -23,6 +23,8 @@ email : aumuell@reserv.at * MA 02110-1301 USA * ***************************************************************************/ +#include + #include "mp4file.h" #include "mp4tag.h" @@ -34,7 +36,11 @@ email : aumuell@reserv.at #include #include +#ifdef HAVE_MP4V2_H +#define USE_ITMF_TAGS +#else #define MP4V2_HAS_WRITE_BUG 1 +#endif namespace TagLib { //////////////////////////////////////////////////////////////////////////////// @@ -102,6 +108,11 @@ bool MP4::File::save() return false; } +#ifdef USE_ITMF_TAGS + const MP4Tags* filetags = MP4TagsAlloc(); + MP4TagsFetch(filetags, handle); +#endif + #ifdef MP4V2_HAS_WRITE_BUG /* according to gtkpod we have to delete all meta data before modifying it, save the stuff we would not touch */ @@ -117,7 +128,14 @@ bool MP4::File::save() #endif - +#ifdef USE_ITMF_TAGS + MP4TagsSetName(filetags, mp4tag->title().isNull() ? "" : mp4tag->title().toCString(true)); + MP4TagsSetArtist(filetags, mp4tag->artist().isNull() ? "" : mp4tag->artist().toCString(true)); + MP4TagsSetAlbum(filetags, mp4tag->album().isNull() ? "" : mp4tag->album().toCString(true)); + MP4TagsSetComments(filetags, mp4tag->comment().isNull() ? "" : mp4tag->comment().toCString(true)); + MP4TagsSetGenre(filetags, mp4tag->genre().isNull() ? "" : mp4tag->genre().toCString(true)); + MP4TagsSetComposer(filetags, mp4tag->composer().isNull() ? "" : mp4tag->composer().toCString(true)); +#else #define setmeta(val, tag) \ if(mp4tag->val().isNull()) { \ /*MP4DeleteMetadata##tag(handle);*/ \ @@ -125,27 +143,65 @@ bool MP4::File::save() } else { \ MP4SetMetadata##tag(handle, mp4tag->val().toCString(true)); \ } - setmeta(title, Name); setmeta(artist, Artist); setmeta(album, Album); setmeta(comment, Comment); setmeta(genre, Genre); + setmeta(composer, Writer); +#endif char buf[100] = ""; if(mp4tag->year()) snprintf(buf, sizeof(buf), "%u", mp4tag->year()); +#ifdef USE_ITMF_TAGS + MP4TagsSetReleaseDate(filetags, buf); +#else MP4SetMetadataYear(handle, buf); +#endif u_int16_t t1, t2; + +#ifdef USE_ITMF_TAGS + MP4TagTrack track = *filetags->track; + track.index = t1; + MP4TagsSetTrack(filetags, &track); +#else MP4GetMetadataTrack(handle, &t1, &t2); MP4SetMetadataTrack(handle, mp4tag->track(), t2); - if(mp4tag->bpm() != 0) +#endif + if(mp4tag->bpm() != 0) { +#ifdef USE_ITMF_TAGS + u_int16_t tempo = mp4tag->bpm(); + MP4TagsSetTempo(filetags, &tempo); +#else MP4SetMetadataTempo(handle, mp4tag->bpm()); +#endif + } if(mp4tag->compilation() != MP4::Tag::Undefined) { +#ifdef USE_ITMF_TAGS + u_int8_t compilation = mp4tag->compilation(); + MP4TagsSetCompilation(filetags, &compilation); +#else MP4SetMetadataCompilation(handle, mp4tag->compilation()); +#endif } +#ifdef USE_ITMF_TAGS + if(mp4tag->cover().size()) { + MP4TagArtwork art; + art.size = mp4tag->cover().size(); + art.data = mp4tag->cover().size() ? const_cast( reinterpret_cast( mp4tag->cover().data() ) ) : 0; + art.type = MP4_ART_UNDEFINED; // delegate typing to libmp4v2 + if(filetags->artworkCount > 0) { + MP4TagsSetArtwork(filetags, 0, &art); + } + else { + MP4TagsAddArtwork(filetags, &art); + } + } +#else MP4SetMetadataCoverArt(handle, mp4tag->cover().size() ? const_cast( reinterpret_cast( mp4tag->cover().data() ) ) : 0, mp4tag->cover().size()); +#endif #ifdef MP4V2_HAS_WRITE_BUG // set the saved data again @@ -159,6 +215,10 @@ bool MP4::File::save() } #endif +#ifdef USE_ITMF_TAGS + MP4TagsStore(filetags, handle); + MP4TagsFree(filetags); +#endif MP4Close(handle); mp4file = MP4Read(name()); diff --git a/amarok/src/metadata/mp4/mp4properties.h b/amarok/src/metadata/mp4/mp4properties.h index 95c83035..bbe3fa48 100644 --- a/amarok/src/metadata/mp4/mp4properties.h +++ b/amarok/src/metadata/mp4/mp4properties.h @@ -22,13 +22,20 @@ email : andrew.leadbetter@gmail.com #ifndef TAGLIB_MP4PROPERTIES_H #define TAGLIB_MP4PROPERTIES_H +#include + #include #include +#ifdef HAVE_MP4V2_H #include +#endif +#ifdef HAVE_MP4_H +#include // mp4.h drags in mp4_config.h that defines these // get rid of them so they don't conflict with our config.h #undef VERSION #undef PACKAGE +#endif namespace TagLib { diff --git a/amarok/src/metadata/mp4/mp4tag.cpp b/amarok/src/metadata/mp4/mp4tag.cpp index ee032d3a..642df2b1 100644 --- a/amarok/src/metadata/mp4/mp4tag.cpp +++ b/amarok/src/metadata/mp4/mp4tag.cpp @@ -20,6 +20,8 @@ email : andrew.leadbetter@gmail.com * MA 02110-1301 USA * ***************************************************************************/ +#include + #include "mp4tag.h" #include @@ -29,6 +31,10 @@ email : andrew.leadbetter@gmail.com #include #include +#ifdef HAVE_MP4V2_H +#define USE_ITMF_TAGS +#endif + using namespace TagLib; MP4::Tag::Tag() : TagLib::Tag::Tag() { @@ -67,21 +73,66 @@ void MP4::Tag::duplicate(const Tag *source, Tag *target, bool overwrite) { // Duplicate standard information Tag::duplicate(source, target, overwrite); - if (overwrite || target->compilation() == Undefined && source->compilation() != Undefined) + if ((overwrite || target->compilation() == Undefined) && (source->compilation() != Undefined)) { target->setCompilation(source->compilation()); + } - if (overwrite || target->cover().size() == 0) + if (overwrite || target->cover().size() == 0) { target->setCover(source->cover()); + } } void MP4::Tag::readTags( MP4FileHandle mp4file ) { // Now parse tag. +#ifdef USE_ITMF_TAGS + const MP4Tags* filetags = MP4TagsAlloc(); + MP4TagsFetch(filetags, mp4file); + + if(filetags->name != NULL) { + m_title = String(filetags->name, String::UTF8); + } + if(filetags->artist != NULL) { + m_artist = String(filetags->artist, String::UTF8); + } + if(filetags->comments != NULL) { + m_comment = String(filetags->comments, String::UTF8); + } + if(filetags->releaseDate != NULL) { + m_year = strtol(filetags->releaseDate, NULL, 0); + } + if(filetags->album != NULL) { + m_album = String(filetags->album, String::UTF8); + } + if(filetags->track != NULL) { + m_track = filetags->track->index; + } + if(filetags->disk != NULL) { + m_disk = filetags->disk->index; + } + if(filetags->tempo != NULL) { + m_bpm = *filetags->tempo; + } + if(filetags->compilation != NULL) { + m_compilation = *filetags->compilation; + } + if(filetags->genre != NULL) { + m_genre = String(filetags->genre, String::UTF8); + } + if(filetags->composer != NULL) { + m_composer = String(filetags->composer, String::UTF8); + } + if(filetags->artworkCount > 0) { + m_image.setData(reinterpret_cast( filetags->artwork[0].data ), filetags->artwork[0].size); + } + MP4TagsFree(filetags); +#else char *value; uint8_t boolvalue; uint16_t numvalue, numvalue2; uint8_t *image; uint32_t imageSize; + if (MP4GetMetadataName(mp4file, &value) && value != NULL) { m_title = String(value, String::UTF8); free(value); @@ -128,4 +179,5 @@ void MP4::Tag::readTags( MP4FileHandle mp4file ) m_image.setData(reinterpret_cast( image ), imageSize); free(image); } +#endif } diff --git a/amarok/src/metadata/mp4/mp4tag.h b/amarok/src/metadata/mp4/mp4tag.h index 9ba20bc0..34f95054 100644 --- a/amarok/src/metadata/mp4/mp4tag.h +++ b/amarok/src/metadata/mp4/mp4tag.h @@ -21,9 +21,16 @@ email : andrew.leadbetter@gmail.com #ifndef TAGLIB_MP4TAG_H #define TAGLIB_MP4TAG_H +#include + #include #include "mp4file.h" +#ifdef HAVE_MP4V2_H #include +#endif +#ifdef HAVE_MP4_H +#include +#endif namespace TagLib { diff --git a/amarok/src/metadata/mp4/taglib_mp4filetyperesolver.cpp b/amarok/src/metadata/mp4/taglib_mp4filetyperesolver.cpp index 43edd197..e179da5d 100644 --- a/amarok/src/metadata/mp4/taglib_mp4filetyperesolver.cpp +++ b/amarok/src/metadata/mp4/taglib_mp4filetyperesolver.cpp @@ -36,7 +36,11 @@ TagLib::File *MP4FileTypeResolver::createFile(const char *fileName, || !strcasecmp(ext, ".mp4") || !strcasecmp(ext, ".m4v") || !strcasecmp(ext, ".mp4v"))) { +#if defined(MP4V2_PROJECT_version_hex) && MP4V2_PROJECT_version_hex >= 0x00020000 + MP4FileHandle h = MP4Read(fileName); +#else MP4FileHandle h = MP4Read(fileName, 0); +#endif if(MP4_INVALID_FILE_HANDLE == h) { return 0; diff --git a/config.h.in b/config.h.in index 9645ebf9..86dab1c2 100644 --- a/config.h.in +++ b/config.h.in @@ -106,6 +106,9 @@ /* have mp4v2 */ #undef HAVE_MP4V2 +/* Define to 1 if you have the header file. */ +#undef HAVE_MP4V2_H + /* Define to 1 if you have the header file. */ #undef HAVE_MP4_H