Hi all,
Currently, the code that loads tags from mp4/m4a files doesn't properly deal 
with characters not in ASCII, which creates odd artifacts with names like 
Tiƫsto (the artist that prompted my patch incidentally) containing accents, 
and would likely do even worse things with names in Crylllic, CJK or other 
non-latin scripts. The common practice is to encode the tags in UTF-8 [0], so 
I put in QString::fromUtf8 calls to reflect that.

In trying to fix the above problem, I discovered that the mp4v2 calls currently 
being used to get tags have been deprecated and are scheduled for removal [1], 
so I updated them to the new tags interface [2].

Finally, there were a few (2) casts from const char* to QString, so I fixed 
those.

There was some MSVC-specific code removed in the patch... I don't think it 
should be a problem, but if someone with a working MSVC build system wouldn't 
mind trying it out, I'd appreciate it.

Bill

[0] http://atomicparsley.sourceforge.net/mpeg-4files.html
[1] http://mp4v2.googlecode.com/svn/doc/1.9.0/api/group__mp4__meta.html
[2] http://mp4v2.googlecode.com/svn/doc/1.9.0/api/group__mp4__itmf__tags.html
=== modified file 'mixxx/src/soundsourcem4a.cpp'
--- mixxx/src/soundsourcem4a.cpp	2010-02-25 10:14:57 +0000
+++ mixxx/src/soundsourcem4a.cpp	2010-05-13 23:04:41 +0000
@@ -15,6 +15,7 @@
  ***************************************************************************/
 
 #include <neaacdec.h>
+#include <mp4v2/mp4v2.h>
 
 #ifdef __WINDOWS__
 #include <io.h>
@@ -39,11 +40,11 @@
     memset(&ipd, 0, sizeof(ipd));
 
     // Copy QString to char[] buffer for mp4_open to read from later
-    int bytes = qFileName.length() + 1;
-    ipd.filename = new char[bytes];
+    QByteArray qbaFileName = qFileName.toUtf8();
+    unsigned int fileNameSize = qbaFileName.size() + 1; // for null byte
+    ipd.filename = new char[fileNameSize];
     ipd.remote = false; // File is not an stream
-    strncpy(ipd.filename, qFileName, bytes);
-    ipd.filename[bytes-1] = '\0';
+    strncpy(ipd.filename, qbaFileName.data(), fileNameSize);
 
     int mp4_open_status = mp4_open(&ipd);
     if (mp4_open_status != 0) {
@@ -159,48 +160,29 @@
 
 int SoundSourceM4A::ParseHeader( TrackInfoObject * Track){
     QString mp4FileName = Track->getLocation();
-    MP4FileHandle mp4file = MP4Read(mp4FileName);
+    QByteArray qbaFileName = mp4FileName.toUtf8();
+    MP4FileHandle mp4file = MP4Read(qbaFileName.data());
+    const MP4Tags *mp4tags = MP4TagsAlloc();
 
     if (mp4file == MP4_INVALID_FILE_HANDLE) {
         qDebug() << "SSM4A::ParseHeader : " << mp4FileName
                  << "could not be opened using the MP4 decoder.";
         return ERR;
     }
-
+    
+    MP4TagsFetch(mp4tags, mp4file);
     Track->setType("m4a");
-    char* value = NULL;
-    if (MP4GetMetadataName(mp4file, &value) && value != NULL) {
-        Track->setTitle(value);
-        MP4Free(value);
-        value = NULL;
-    }
-
-    if (MP4GetMetadataArtist(mp4file, &value) && value != NULL) {
-        Track->setArtist(value);
-        MP4Free(value);
-        value = NULL;
-    }
-
-    if (MP4GetMetadataComment(mp4file, &value) && value != NULL) {
-        Track->setComment(value);
-        MP4Free(value);
-        value = NULL;
-    }
-
-#ifndef _MSC_VER
-    u_int16_t bpm = 0;
-#else
-    // MSVC doesn't know what a u_int16_t is, so we have to tell it
-    unsigned short bpm = 0;
-#endif
-    if (MP4GetMetadataTempo(mp4file, &bpm)) {
-        if(bpm > 0) {
-#ifdef _MSC_VER
-            Q_ASSERT(sizeof(bpm)==2);   // Just making sure we're in bounds
-#endif
-            Track->setBpm(bpm);
-            Track->setBpmConfirm(true);
-        }
+    
+    if (mp4tags->name)
+        Track->setTitle(QString::fromUtf8(mp4tags->name));
+    if (mp4tags->artist)
+        Track->setArtist(QString::fromUtf8(mp4tags->artist));
+    if (mp4tags->comments)
+        Track->setComment(QString::fromUtf8(mp4tags->comments));
+
+    if (mp4tags->tempo > 0) {
+        Track->setBpm(*mp4tags->tempo);
+        Track->setBpmConfirm(true);
     }
 
     // We are only interested in first track for the initial dev iteration
@@ -220,6 +202,7 @@
     int bits_per_second = MP4GetTrackBitRate(mp4file, track_id);
     Track->setBitrate(bits_per_second/1000);
 
+    MP4TagsFree(mp4tags);
     MP4Close(mp4file);
     Track->setHeaderParsed(true);
     // FIXME: hard-coded to 2 channels - real value is not available until

------------------------------------------------------------------------------

_______________________________________________
Mixxx-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mixxx-devel

Reply via email to