1 /*************************************************************************** 2 copyright : (C) 2002 - 2008 by Scott Wheeler 3 email : [email protected] 4 ***************************************************************************/ 5 6 /*************************************************************************** 7 * This library is free software; you can redistribute it and/or modify * 8 * it under the terms of the GNU Lesser General Public License version * 9 * 2.1 as published by the Free Software Foundation. * 10 * * 11 * This library is distributed in the hope that it will be useful, but * 12 * WITHOUT ANY WARRANTY; without even the implied warranty of * 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 14 * Lesser General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU Lesser General Public * 17 * License along with this library; if not, write to the Free Software * 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 19 * 02110-1301 USA * 20 * * 21 * Alternatively, this file is available under the Mozilla Public * 22 * License Version 1.1. You may obtain a copy of the License at * 23 * http://www.mozilla.org/MPL/ * 24 ***************************************************************************/ 25 26 #ifndef TAGLIB_MPEGFILE_H 27 #define TAGLIB_MPEGFILE_H 28 29 #include "taglib_export.h" 30 #include "tfile.h" 31 #include "tag.h" 32 33 #include "mpegproperties.h" 34 35 #include "id3v2.h" 36 37 namespace TagLib { 38 39 namespace ID3v2 { class Tag; class FrameFactory; } 40 namespace ID3v1 { class Tag; } 41 namespace APE { class Tag; } 42 43 //! An implementation of TagLib::File with MPEG (MP3) specific methods 44 45 namespace MPEG { 46 47 //! An MPEG file class with some useful methods specific to MPEG 48 49 /*! 50 * This implements the generic TagLib::File API and additionally provides 51 * access to properties that are distinct to MPEG files, notably access 52 * to the different ID3 tags. 53 */ 54 55 class TAGLIB_EXPORT File : public TagLib::File 56 { 57 public: 58 /*! 59 * This set of flags is used for various operations and is suitable for 60 * being OR-ed together. 61 */ 62 enum TagTypes { 63 //! Empty set. Matches no tag types. 64 NoTags = 0x0000, 65 //! Matches ID3v1 tags. 66 ID3v1 = 0x0001, 67 //! Matches ID3v2 tags. 68 ID3v2 = 0x0002, 69 //! Matches APE tags. 70 APE = 0x0004, 71 //! Matches all tag types. 72 AllTags = 0xffff 73 }; 74 75 /*! 76 * Constructs an MPEG file from \a file. If \a readProperties is true the 77 * file's audio properties will also be read. 78 * 79 * \note In the current implementation, \a propertiesStyle is ignored. 80 * 81 * \deprecated This constructor will be dropped in favor of the one below 82 * in a future version. 83 */ 84 File(FileName file, bool readProperties = true, 85 Properties::ReadStyle propertiesStyle = Properties::Average); 86 87 /*! 88 * Constructs an MPEG file from \a file. If \a readProperties is true the 89 * file's audio properties will also be read. 90 * 91 * If this file contains and ID3v2 tag the frames will be created using 92 * \a frameFactory. 93 * 94 * \note In the current implementation, \a propertiesStyle is ignored. 95 */ 96 // BIC: merge with the above constructor 97 File(FileName file, ID3v2::FrameFactory *frameFactory, 98 bool readProperties = true, 99 Properties::ReadStyle propertiesStyle = Properties::Average); 100 101 /*! 102 * Constructs an MPEG file from \a stream. If \a readProperties is true the 103 * file's audio properties will also be read. 104 * 105 * \note TagLib will *not* take ownership of the stream, the caller is 106 * responsible for deleting it after the File object. 107 * 108 * If this file contains and ID3v2 tag the frames will be created using 109 * \a frameFactory. 110 * 111 * \note In the current implementation, \a propertiesStyle is ignored. 112 */ 113 File(IOStream *stream, ID3v2::FrameFactory *frameFactory, 114 bool readProperties = true, 115 Properties::ReadStyle propertiesStyle = Properties::Average); 116 117 /*! 118 * Destroys this instance of the File. 119 */ 120 virtual ~File(); 121 122 /*! 123 * Returns a pointer to a tag that is the union of the ID3v2 and ID3v1 124 * tags. The ID3v2 tag is given priority in reading the information -- if 125 * requested information exists in both the ID3v2 tag and the ID3v1 tag, 126 * the information from the ID3v2 tag will be returned. 127 * 128 * If you would like more granular control over the content of the tags, 129 * with the concession of generality, use the tag-type specific calls. 130 * 131 * \note As this tag is not implemented as an ID3v2 tag or an ID3v1 tag, 132 * but a union of the two this pointer may not be cast to the specific 133 * tag types. 134 * 135 * \see ID3v1Tag() 136 * \see ID3v2Tag() 137 * \see APETag() 138 */ 139 virtual Tag *tag() const; 140 141 /*! 142 * Implements the reading part of the unified property interface. 143 * If the file contains more than one tag, only the 144 * first one (in the order ID3v2, APE, ID3v1) will be converted to the 145 * PropertyMap. 146 */ 147 PropertyMap properties() const; 148 149 void removeUnsupportedProperties(const StringList &properties); 150 151 /*! 152 * Implements the writing part of the unified tag dictionary interface. 153 * In order to avoid problems with deprecated tag formats, this method 154 * always creates an ID3v2 tag if necessary. 155 * If an ID3v1 tag exists, it will be updated as well, within the 156 * limitations of that format. 157 * The returned PropertyMap refers to the ID3v2 tag only. 158 */ 159 PropertyMap setProperties(const PropertyMap &); 160 161 /*! 162 * Returns the MPEG::Properties for this file. If no audio properties 163 * were read then this will return a null pointer. 164 */ 165 virtual Properties *audioProperties() const; 166 167 /*! 168 * Save the file. If at least one tag -- ID3v1 or ID3v2 -- exists this 169 * will duplicate its content into the other tag. This returns true 170 * if saving was successful. 171 * 172 * If neither exists or if both tags are empty, this will strip the tags 173 * from the file. 174 * 175 * This is the same as calling save(AllTags); 176 * 177 * If you would like more granular control over the content of the tags, 178 * with the concession of generality, use parameterized save call below. 179 * 180 * \see save(int tags) 181 */ 182 virtual bool save(); 183 184 /*! 185 * Save the file. This will attempt to save all of the tag types that are 186 * specified by OR-ing together TagTypes values. The save() method above 187 * uses AllTags. This returns true if saving was successful. 188 * 189 * This strips all tags not included in the mask, but does not modify them 190 * in memory, so later calls to save() which make use of these tags will 191 * remain valid. This also strips empty tags. 192 */ 193 bool save(int tags); 194 195 /*! 196 * \deprecated 197 */ 198 // BIC: combine with the above method 199 TAGLIB_DEPRECATED bool save(int tags, bool stripOthers); 200 201 /*! 202 * \deprecated 203 */ 204 // BIC: combine with the above method 205 TAGLIB_DEPRECATED bool save(int tags, bool stripOthers, int id3v2Version); 206 207 /*! 208 * \deprecated 209 */ 210 // BIC: combine with the above method 211 TAGLIB_DEPRECATED bool save(int tags, bool stripOthers, int id3v2Version, bool duplicateTags); 212 213 /*! 214 * Save the file. This will attempt to save all of the tag types that are 215 * specified by OR-ing together TagTypes values. 216 * 217 * \a strip can be set to strip all tags except those in \a tags. Those 218 * tags will not be modified in memory, and thus remain valid. 219 * 220 * \a version specifies the ID3v2 version to be used for writing tags. By 221 * default, the latest standard, ID3v2.4 is used. 222 * 223 * If \a duplicate is set to DuplicateTags and at least one tag -- ID3v1 224 * or ID3v2 -- exists this will duplicate its content into the other tag. 225 */ 226 bool save(int tags, StripTags strip, 227 ID3v2::Version version = ID3v2::v4, 228 DuplicateTags duplicate = Duplicate); 229 230 /*! 231 * Returns a pointer to the ID3v2 tag of the file. 232 * 233 * If \a create is false (the default) this may return a null pointer 234 * if there is no valid ID3v2 tag. If \a create is true it will create 235 * an ID3v2 tag if one does not exist and returns a valid pointer. 236 * 237 * \note This may return a valid pointer regardless of whether or not the 238 * file on disk has an ID3v2 tag. Use hasID3v2Tag() to check if the file 239 * on disk actually has an ID3v2 tag. 240 * 241 * \note The Tag <b>is still</b> owned by the MPEG::File and should not be 242 * deleted by the user. It will be deleted when the file (object) is 243 * destroyed. 244 * 245 * \see hasID3v2Tag() 246 */ 247 ID3v2::Tag *ID3v2Tag(bool create = false); 248 249 /*! 250 * Returns a pointer to the ID3v1 tag of the file. 251 * 252 * If \a create is false (the default) this may return a null pointer 253 * if there is no valid ID3v1 tag. If \a create is true it will create 254 * an ID3v1 tag if one does not exist and returns a valid pointer. 255 * 256 * \note This may return a valid pointer regardless of whether or not the 257 * file on disk has an ID3v1 tag. Use hasID3v1Tag() to check if the file 258 * on disk actually has an ID3v1 tag. 259 * 260 * \note The Tag <b>is still</b> owned by the MPEG::File and should not be 261 * deleted by the user. It will be deleted when the file (object) is 262 * destroyed. 263 * 264 * \see hasID3v1Tag() 265 */ 266 ID3v1::Tag *ID3v1Tag(bool create = false); 267 268 /*! 269 * Returns a pointer to the APE tag of the file. 270 * 271 * If \a create is false (the default) this may return a null pointer 272 * if there is no valid APE tag. If \a create is true it will create 273 * an APE tag if one does not exist and returns a valid pointer. 274 * 275 * \note This may return a valid pointer regardless of whether or not the 276 * file on disk has an APE tag. Use hasAPETag() to check if the file 277 * on disk actually has an APE tag. 278 * 279 * \note The Tag <b>is still</b> owned by the MPEG::File and should not be 280 * deleted by the user. It will be deleted when the file (object) is 281 * destroyed. 282 * 283 * \see hasAPETag() 284 */ 285 APE::Tag *APETag(bool create = false); 286 287 /*! 288 * This will strip the tags that match the OR-ed together TagTypes from the 289 * file. By default it strips all tags. It returns true if the tags are 290 * successfully stripped. 291 * 292 * This is equivalent to strip(tags, true) 293 * 294 * \note This will also invalidate pointers to the ID3 and APE tags 295 * as their memory will be freed. 296 * 297 * \note This will update the file immediately. 298 */ 299 bool strip(int tags = AllTags); 300 301 /*! 302 * This will strip the tags that match the OR-ed together TagTypes from the 303 * file. By default it strips all tags. It returns true if the tags are 304 * successfully stripped. 305 * 306 * If \a freeMemory is true the ID3 and APE tags will be deleted and 307 * pointers to them will be invalidated. 308 * 309 * \note This will update the file immediately. 310 */ 311 // BIC: merge with the method above 312 bool strip(int tags, bool freeMemory); 313 314 /*! 315 * Set the ID3v2::FrameFactory to something other than the default. 316 * 317 * \see ID3v2FrameFactory 318 * \deprecated This value should be passed in via the constructor 319 */ 320 TAGLIB_DEPRECATED void setID3v2FrameFactory(const ID3v2::FrameFactory *factory); 321 322 /*! 323 * Returns the position in the file of the first MPEG frame. 324 */ 325 long firstFrameOffset(); 326 327 /*! 328 * Returns the position in the file of the next MPEG frame, 329 * using the current position as start 330 */ 331 long nextFrameOffset(long position); 332 333 /*! 334 * Returns the position in the file of the previous MPEG frame, 335 * using the current position as start 336 */ 337 long previousFrameOffset(long position); 338 339 /*! 340 * Returns the position in the file of the last MPEG frame. 341 */ 342 long lastFrameOffset(); 343 344 /*! 345 * Returns whether or not the file on disk actually has an ID3v1 tag. 346 * 347 * \see ID3v1Tag() 348 */ 349 bool hasID3v1Tag() const; 350 351 /*! 352 * Returns whether or not the file on disk actually has an ID3v2 tag. 353 * 354 * \see ID3v2Tag() 355 */ 356 bool hasID3v2Tag() const; 357 358 /*! 359 * Returns whether or not the file on disk actually has an APE tag. 360 * 361 * \see APETag() 362 */ 363 bool hasAPETag() const; 364 365 /*! 366 * Returns whether or not the given \a stream can be opened as an MPEG 367 * file. 368 * 369 * \note This method is designed to do a quick check. The result may 370 * not necessarily be correct. 371 */ 372 static bool isSupported(IOStream *stream); 373 374 private: 375 File(const File &); 376 File &operator=(const File &); 377 378 void read(bool readProperties); 379 long findID3v2(); 380 381 class FilePrivate; 382 FilePrivate *d; 383 }; 384 } 385 } 386 387 #endif 388