mp4tag/mp4file.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002 copyright            : (C) 2005 by Andy Leadbetter
00003 email                : andrew.leadbetter@gmail.com
00004 
00005 copyright            : (C) 2005 by Martin Aumueller
00006 email                : aumuell@reserv.at
00007                        (write support)
00008  ***************************************************************************/
00009 
00010 /***************************************************************************
00011  *   This library is free software; you can redistribute it and/or modify  *
00012  *   it  under the terms of the GNU Lesser General Public License version  *
00013  *   2.1 as published by the Free Software Foundation.                     *
00014  *                                                                         *
00015  *   This library is distributed in the hope that it will be useful, but   *
00016  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
00017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00018  *   Lesser General Public License for more details.                       *
00019  *                                                                         *
00020  *   You should have received a copy of the GNU Lesser General Public      *
00021  *   License along with this library; if not, write to the Free Software   *
00022  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,            *
00023  *   MA  02110-1301  USA                                                   *
00024  ***************************************************************************/
00025 
00026 #include "mp4file.h"
00027 
00028 #include "mp4tag.h"
00029 #include <tfile.h>
00030 #include <audioproperties.h>
00031 
00032 #include <stdint.h>
00033 
00034 #define MP4V2_HAS_WRITE_BUG 1
00035 
00036 namespace TagLib {
00038 // public members
00040 
00041 MP4::File::File(const char *file,
00042         bool readProperties,
00043         Properties::ReadStyle propertiesStyle,
00044         MP4FileHandle handle) : TagLib::File(file),
00045         mp4tag(NULL), properties(NULL)
00046 {
00047 
00048     //   debug ("MP4::File: create new file object.");
00049     //debug ( file );
00054     if(handle == MP4_INVALID_FILE_HANDLE)
00055     {
00056         mp4file = MP4Read(file);
00057     }
00058     else
00059     {
00060         mp4file = handle;
00061     }
00062 
00063     if( isOpen() )
00064     {
00065         read(readProperties, propertiesStyle );
00066     }
00067 }
00068 
00069 MP4::File::~File()
00070 {
00071     MP4Close(mp4file);
00072     delete mp4tag;
00073     delete properties;
00074 }
00075 
00076 TagLib::Tag *MP4::File::tag() const
00077 {
00078     return mp4tag;
00079 }
00080 
00081 TagLib::MP4::Tag *MP4::File::getMP4Tag() const
00082 {
00083     return mp4tag;
00084 }
00085 
00086 MP4::Properties *MP4::File::audioProperties() const
00087 {
00088     return properties;
00089 }
00090 
00091 bool MP4::File::save()
00092 {
00093     MP4Close(mp4file);
00094 
00095     MP4FileHandle handle = MP4Modify(name());
00096     if(handle == MP4_INVALID_FILE_HANDLE)
00097     {
00098         mp4file = MP4Read(name());
00099         return false;
00100     }
00101 
00102 #ifdef MP4V2_HAS_WRITE_BUG
00103     /* according to gtkpod we have to delete all meta data before modifying it,
00104        save the stuff we would not touch */
00105 
00106     // need to fetch/rewrite this only if we aren't going to anyway
00107     uint8_t compilation = 0;
00108     bool has_compilation = mp4tag->compilation() == MP4::Tag::Undefined ? MP4GetMetadataCompilation(handle, &compilation) : false;
00109 
00110     char *tool = NULL;
00111     MP4GetMetadataTool(handle, &tool);
00112 
00113     MP4MetadataDelete(handle);
00114 #endif
00115 
00116 
00117 
00118 #define setmeta(val, tag) \
00119     if(mp4tag->val().isNull()) { \
00120         /*MP4DeleteMetadata##tag(handle);*/ \
00121         MP4SetMetadata##tag(handle, ""); \
00122     } else { \
00123         MP4SetMetadata##tag(handle, mp4tag->val().toCString(true)); \
00124     }
00125 
00126     setmeta(title, Name);
00127     setmeta(artist, Artist);
00128     setmeta(album, Album);
00129     setmeta(comment, Comment);
00130     setmeta(genre, Genre);
00131 
00132     char buf[100] = "";
00133     if(mp4tag->year())
00134         snprintf(buf, sizeof(buf), "%u", mp4tag->year());
00135     MP4SetMetadataYear(handle, buf);
00136     u_int16_t t1, t2;
00137     MP4GetMetadataTrack(handle, &t1, &t2);
00138     MP4SetMetadataTrack(handle, mp4tag->track(), t2);
00139     if(mp4tag->bpm() != 0)
00140         MP4SetMetadataTempo(handle, mp4tag->bpm());
00141     if(mp4tag->compilation() != MP4::Tag::Undefined) {
00142         MP4SetMetadataCompilation(handle, mp4tag->compilation());
00143     }
00144 
00145     MP4SetMetadataCoverArt(handle, mp4tag->cover().size() ? const_cast<u_int8_t *>( reinterpret_cast<const u_int8_t *>( mp4tag->cover().data() ) ) : 0, mp4tag->cover().size());
00146 
00147 #ifdef MP4V2_HAS_WRITE_BUG
00148     // set the saved data again
00149 
00150     if(has_compilation)
00151         MP4SetMetadataCompilation(handle, compilation);
00152     if(tool)
00153     {
00154         MP4SetMetadataTool(handle, tool);
00155         free(tool);
00156     }
00157 #endif
00158 
00159     if(!MP4Close(handle))
00160     {
00161         fprintf(stderr, "close failed\n");
00162     }
00163 
00164     mp4file = MP4Read(name());
00165     if(mp4file == MP4_INVALID_FILE_HANDLE)
00166     {
00167         fprintf(stderr, "reopen failed\n");
00168         return false;
00169     }
00170 
00171     return true;
00172 }
00173 
00174 bool MP4::File::isOpen()
00175 {
00176     return mp4file != MP4_INVALID_FILE_HANDLE;
00177 }
00178 
00180 // private members
00182 
00183 void MP4::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
00184 {
00185     properties =  new MP4::Properties(propertiesStyle);
00186     mp4tag = new MP4::Tag();
00187 
00188     if (mp4file != MP4_INVALID_FILE_HANDLE) {
00189 
00190         if(readProperties)
00191         {
00192             // Parse bitrate etc.
00193             properties->readMP4Properties( mp4file );
00194         }
00195 
00196         mp4tag->readTags( mp4file );
00197     }
00198 }
00199 
00200 }

Generated on Mon Aug 6 21:24:19 2007 for plai by  doxygen 1.5.1