summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSlávek Banko <[email protected]>2013-05-12 12:22:21 +0200
committerSlávek Banko <[email protected]>2013-05-12 12:29:01 +0200
commit8bad2664cb6f8ab191d44647937acfd45b977920 (patch)
treeaf013d4a64427c2822df377a79429ef263a89475
parent534ba7f879c28f4ee283b9f14f3477b462effd77 (diff)
downloadamarok-8bad2664cb6f8ab191d44647937acfd45b977920.tar.gz
amarok-8bad2664cb6f8ab191d44647937acfd45b977920.zip
Add mp4v2 MP4Tags* API support
This resolves Bug 346
-rw-r--r--amarok/configure.in.in20
-rw-r--r--amarok/src/metadata/mp4/mp4file.cpp66
-rw-r--r--amarok/src/metadata/mp4/mp4properties.h7
-rw-r--r--amarok/src/metadata/mp4/mp4tag.cpp56
-rw-r--r--amarok/src/metadata/mp4/mp4tag.h7
-rw-r--r--amarok/src/metadata/mp4/taglib_mp4filetyperesolver.cpp4
-rw-r--r--config.h.in3
7 files changed, 155 insertions, 8 deletions
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 <systems.h>
#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 <systems.h>
+ #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 : [email protected]
* MA 02110-1301 USA *
***************************************************************************/
+#include <config.h>
+
#include "mp4file.h"
#include "mp4tag.h"
@@ -34,7 +36,11 @@ email : [email protected]
#include <stdlib.h>
#include <sys/types.h>
+#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<u_int8_t *>( reinterpret_cast<const u_int8_t *>( 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<u_int8_t *>( reinterpret_cast<const u_int8_t *>( 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 : [email protected]
#ifndef TAGLIB_MP4PROPERTIES_H
#define TAGLIB_MP4PROPERTIES_H
+#include <config.h>
+
#include <audioproperties.h>
#include <tstring.h>
+#ifdef HAVE_MP4V2_H
#include <mp4v2/mp4v2.h>
+#endif
+#ifdef HAVE_MP4_H
+#include <mp4.h>
// 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 : [email protected]
* MA 02110-1301 USA *
***************************************************************************/
+#include <config.h>
+
#include "mp4tag.h"
#include <tag.h>
@@ -29,6 +31,10 @@ email : [email protected]
#include <stdlib.h>
#include <sys/types.h>
+#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<const char *>( 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<const char *>( 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 : [email protected]
#ifndef TAGLIB_MP4TAG_H
#define TAGLIB_MP4TAG_H
+#include <config.h>
+
#include <tag.h>
#include "mp4file.h"
+#ifdef HAVE_MP4V2_H
#include <mp4v2/mp4v2.h>
+#endif
+#ifdef HAVE_MP4_H
+#include <mp4.h>
+#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 <mp4v2/mp4v2.h> header file. */
+#undef HAVE_MP4V2_H
+
/* Define to 1 if you have the <mp4.h> header file. */
#undef HAVE_MP4_H