void testCovrWrite() { string filename = copyFile("has-tags", ".m4a"); MP4::File *f = new MP4::File(filename.c_str()); CPPUNIT_ASSERT(f->tag()->itemListMap().contains("covr")); MP4::CoverArtList l = f->tag()->itemListMap()["covr"].toCoverArtList(); l.append(MP4::CoverArt(MP4::CoverArt::PNG, "foo")); f->tag()->itemListMap()["covr"] = l; f->save(); delete f; f = new MP4::File(filename.c_str()); CPPUNIT_ASSERT(f->tag()->itemListMap().contains("covr")); l = f->tag()->itemListMap()["covr"].toCoverArtList(); CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), l.size()); CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, l[0].format()); CPPUNIT_ASSERT_EQUAL(TagLib::uint(79), l[0].data().size()); CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::JPEG, l[1].format()); CPPUNIT_ASSERT_EQUAL(TagLib::uint(287), l[1].data().size()); CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, l[2].format()); CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), l[2].data().size()); delete f; deleteFile(filename); }
void MP4::Tag::parseCovr(const MP4::Atom *atom) { MP4::CoverArtList value; ByteVector data = d->file->readBlock(atom->length - 8); unsigned int pos = 0; while(pos < data.size()) { const int length = static_cast<int>(data.toUInt(pos)); if(length < 12) { debug("MP4: Too short atom"); break;; } const ByteVector name = data.mid(pos + 4, 4); const int flags = static_cast<int>(data.toUInt(pos + 8)); if(name != "data") { debug("MP4: Unexpected atom \"" + name + "\", expecting \"data\""); break; } if(flags == TypeJPEG || flags == TypePNG || flags == TypeBMP || flags == TypeGIF || flags == TypeImplicit) { value.append(MP4::CoverArt(MP4::CoverArt::Format(flags), data.mid(pos + 16, length - 16))); } else { debug("MP4: Unknown covr format " + String::number(flags)); } pos += length; } if(value.size() > 0) addItem(atom->name, value); }
void testCovrWrite() { ScopedFileCopy copy("has-tags", ".m4a"); string filename = copy.fileName(); MP4::File *f = new MP4::File(filename.c_str()); CPPUNIT_ASSERT(f->tag()->contains("covr")); MP4::CoverArtList l = f->tag()->item("covr").toCoverArtList(); l.append(MP4::CoverArt(MP4::CoverArt::PNG, "foo")); f->tag()->setItem("covr", l); f->save(); delete f; f = new MP4::File(filename.c_str()); CPPUNIT_ASSERT(f->tag()->contains("covr")); l = f->tag()->item("covr").toCoverArtList(); CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), l.size()); CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, l[0].format()); CPPUNIT_ASSERT_EQUAL(TagLib::uint(79), l[0].data().size()); CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::JPEG, l[1].format()); CPPUNIT_ASSERT_EQUAL(TagLib::uint(287), l[1].data().size()); CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, l[2].format()); CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), l[2].data().size()); delete f; }
bool CTagLoaderTagLib::ParseMP4Tag(MP4::Tag *mp4, EmbeddedArt *art, CMusicInfoTag& tag) { if (!mp4) return false; MP4::ItemListMap& itemListMap = mp4->itemListMap(); for (MP4::ItemListMap::ConstIterator it = itemListMap.begin(); it != itemListMap.end(); ++it) { if (it->first == "\251nam") tag.SetTitle(it->second.toStringList().front().to8Bit(true)); else if (it->first == "\251ART") SetArtist(tag, StringListToVectorString(it->second.toStringList())); else if (it->first == "\251alb") tag.SetAlbum(it->second.toStringList().front().to8Bit(true)); else if (it->first == "aART") SetAlbumArtist(tag, StringListToVectorString(it->second.toStringList())); else if (it->first == "\251gen") SetGenre(tag, StringListToVectorString(it->second.toStringList())); else if (it->first == "\251cmt") tag.SetComment(it->second.toStringList().front().to8Bit(true)); else if (it->first == "cpil") tag.SetCompilation(it->second.toBool()); else if (it->first == "trkn") tag.SetTrackNumber(it->second.toIntPair().first); else if (it->first == "disk") tag.SetPartOfSet(it->second.toIntPair().first); else if (it->first == "\251day") tag.SetYear(it->second.toStringList().front().toInt()); else if (it->first == "----:com.apple.iTunes:MusicBrainz Artist Id") tag.SetMusicBrainzArtistID(it->second.toStringList().front().to8Bit(true)); else if (it->first == "----:com.apple.iTunes:MusicBrainz Album Artist Id") tag.SetMusicBrainzAlbumArtistID(it->second.toStringList().front().to8Bit(true)); else if (it->first == "----:com.apple.iTunes:MusicBrainz Album Id") tag.SetMusicBrainzAlbumID(it->second.toStringList().front().to8Bit(true)); else if (it->first == "----:com.apple.iTunes:MusicBrainz Track Id") tag.SetMusicBrainzTrackID(it->second.toStringList().front().to8Bit(true)); else if (it->first == "covr") { MP4::CoverArtList coverArtList = it->second.toCoverArtList(); for (MP4::CoverArtList::ConstIterator pt = coverArtList.begin(); pt != coverArtList.end(); ++pt) { string mime; switch (pt->format()) { case MP4::CoverArt::PNG: mime = "image/png"; break; case MP4::CoverArt::JPEG: mime = "image/jpeg"; break; default: break; } if (mime.empty()) continue; tag.SetCoverArtInfo(pt->data().size(), mime); if (art) art->set((const uint8_t *)pt->data().data(), pt->data().size(), mime); break; // one is enough } } } return true; }
ByteVector MP4::Tag::renderCovr(const ByteVector &name, const MP4::Item &item) const { ByteVector data; MP4::CoverArtList value = item.toCoverArtList(); for(unsigned int i = 0; i < value.size(); i++) { data.append(renderAtom("data", ByteVector::fromUInt(value[i].format()) + ByteVector(4, '\0') + value[i].data())); } return renderAtom(name, data); }
ByteVector MP4::Tag::renderCovr(const ByteVector &name, const MP4::Item &item) const { ByteVector data; MP4::CoverArtList value = item.toCoverArtList(); for(MP4::CoverArtList::ConstIterator it = value.begin(); it != value.end(); ++it) { data.append(renderAtom("data", ByteVector::fromUInt(it->format()) + ByteVector(4, '\0') + it->data())); } return renderAtom(name, data); }
void testCovrRead() { MP4::File *f = new MP4::File("data/has-tags.m4a"); CPPUNIT_ASSERT(f->tag()->itemListMap().contains("covr")); MP4::CoverArtList l = f->tag()->itemListMap()["covr"].toCoverArtList(); CPPUNIT_ASSERT_EQUAL(TagLib::uint(2), l.size()); CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, l[0].format()); CPPUNIT_ASSERT_EQUAL(TagLib::uint(79), l[0].data().size()); CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::JPEG, l[1].format()); CPPUNIT_ASSERT_EQUAL(TagLib::uint(287), l[1].data().size()); }
void testList() { MP4::CoverArtList l; l.append(MP4::CoverArt(MP4::CoverArt::PNG, "foo")); l.append(MP4::CoverArt(MP4::CoverArt::JPEG, "bar")); CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, l[0].format()); CPPUNIT_ASSERT_EQUAL(ByteVector("foo"), l[0].data()); CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::JPEG, l[1].format()); CPPUNIT_ASSERT_EQUAL(ByteVector("bar"), l[1].data()); }
void testCovrRead2() { MP4::File *f = new MP4::File(TEST_FILE_PATH_C("covr-junk.m4a")); CPPUNIT_ASSERT(f->tag()->contains("covr")); MP4::CoverArtList l = f->tag()->item("covr").toCoverArtList(); CPPUNIT_ASSERT_EQUAL(TagLib::uint(2), l.size()); CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::PNG, l[0].format()); CPPUNIT_ASSERT_EQUAL(TagLib::uint(79), l[0].data().size()); CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::JPEG, l[1].format()); CPPUNIT_ASSERT_EQUAL(TagLib::uint(287), l[1].data().size()); delete f; }
void MP4::Tag::parseCovr(MP4::Atom *atom, TagLib::File *file) { MP4::CoverArtList value; ByteVector data = file->readBlock(atom->length - 8); unsigned int pos = 0; while(pos < data.size()) { int length = data.mid(pos, 4).toUInt(); ByteVector name = data.mid(pos + 4, 4); int flags = data.mid(pos + 8, 4).toUInt(); if(name != "data") { debug("MP4: Unexpected atom \"" + name + "\", expecting \"data\""); return; } if(flags == MP4::CoverArt::PNG || flags == MP4::CoverArt::JPEG) { value.append(MP4::CoverArt(MP4::CoverArt::Format(flags), data.mid(pos + 16, length - 16))); } pos += length; } if(value.size() > 0) d->items.insert(atom->name, value); }
void MP4::Tag::parseCovr(MP4::Atom *atom, TagLib::File *file) { MP4::CoverArtList value; ByteVector data = file->readBlock(atom->length - 8); unsigned int pos = 0; while(pos < data.size()) { int length = data.mid(pos, 4).toUInt(); ByteVector name = data.mid(pos + 4, 4); int flags = data.mid(pos + 8, 4).toUInt(); if(name != "data") { debug("MP4: Unexpected atom \"" + name + "\", expecting \"data\""); break; } if (flags == 0) { //detect cover format when the cover format bytes are not set ByteVector picHeader = data.mid(pos+16,9); const char jpeg[] = {0xff, 0xd8, 0xff, 0xe0 }; const char jfif[] = {0x10, 0x4a, 0x46, 0x49, 0x46 }; const char png[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00 }; if ((memcmp(picHeader.data(), png, 9) == 0)) { flags = MP4::CoverArt::PNG; } else if ((memcmp(picHeader.data(), jpeg, 4) == 0)) { flags = MP4::CoverArt::JPEG; } else if ((memcmp(picHeader.data(), jfif, 5) == 0)) { flags = MP4::CoverArt::JPEG; } } if(flags == MP4::CoverArt::PNG || flags == MP4::CoverArt::JPEG || flags == 0) { value.append(MP4::CoverArt(MP4::CoverArt::Format(flags), data.mid(pos + 16, length - 16))); } pos += length; } if(value.size() > 0) d->items.insert(atom->name, value); }
bool TagEditor::save() { if ( fRef ) { bool mustSave = false, result = false; if ( !isChecked() ) clearValues(); File &file = *fRef->file(); Tag &tag = getTag( *fRef, file ); if ( titleE->text() != tag.title().toCString( true ) ) { tag.setTitle( String( titleE->text().toUtf8().data(), String::UTF8 ) ); mustSave = true; } if ( artistE->text() != tag.artist().toCString( true ) ) { tag.setArtist( String( artistE->text().toUtf8().data(), String::UTF8 ) ); mustSave = true; } if ( albumE->text() != tag.album().toCString( true ) ) { tag.setAlbum( String( albumE->text().toUtf8().data(), String::UTF8 ) ); mustSave = true; } if ( commentE->text() != tag.comment().toCString( true ) ) { tag.setComment( String( commentE->text().toUtf8().data(), String::UTF8 ) ); mustSave = true; } if ( genreE->text() != tag.genre().toCString( true ) ) { tag.setGenre( String( genreE->text().toUtf8().data(), String::UTF8 ) ); mustSave = true; } if ( ( uint )yearB->value() != tag.year() ) { tag.setYear( yearB->value() ); mustSave = true; } if ( ( uint )trackB->value() != tag.track() ) { tag.setTrack( trackB->value() ); mustSave = true; } if ( isChecked() && ( pictureModificated || pictureBChecked != pictureB->isChecked() ) ) { const bool hasPicture = pictureB->isChecked() && !picture->isEmpty(); if ( instanceOf( file, MPEG::File ) || instanceOf( file, RIFF::AIFF::File ) ) { ID3v2::Tag *id3v2 = NULL; if ( instanceOf( file, MPEG::File ) ) id3v2 = ( ( MPEG::File & )file ).ID3v2Tag( hasPicture ); else if ( instanceOf( file, RIFF::AIFF::File ) ) id3v2 = ( ( RIFF::AIFF::File & )file ).tag(); if ( id3v2 ) { id3v2->removeFrames( "APIC" ); if ( hasPicture ) { ID3v2::AttachedPictureFrame *pictureFrame = new ID3v2::AttachedPictureFrame; pictureFrame->setType( ID3v2::AttachedPictureFrame::FrontCover ); pictureFrame->setMimeType( pictureMimeType.data() ); pictureFrame->setPicture( *picture ); id3v2->addFrame( pictureFrame ); } mustSave = true; } } else if ( instanceOf( file, FLAC::File ) ) { FLAC::File &flacF = ( FLAC::File & )file; flacF.removePictures(); if ( hasPicture ) { FLAC::Picture *flacPicture = new FLAC::Picture; flacPicture->setMimeType( pictureMimeType.data() ); flacPicture->setType( FLAC::Picture::FrontCover ); flacPicture->setData( *picture ); flacF.addPicture( flacPicture ); } mustSave = true; } else if ( instanceOf( file, MP4::File ) ) { MP4::ItemListMap &itemListMap = ( ( MP4::File & )file ).tag()->itemListMap(); if ( itemListMap.contains( "covr" ) ) itemListMap.erase( "covr" ); if ( hasPicture ) { MP4::CoverArt::Format format = ( MP4::CoverArt::Format )0; if ( pictureMimeType == "image/jpeg" ) format = MP4::CoverArt::JPEG; else if ( pictureMimeType == "image/png" ) format = MP4::CoverArt::PNG; #if TAGLIB18 else if ( pictureMimeType == "image/bmp" ) format = MP4::CoverArt::BMP; else if ( pictureMimeType == "image/gif" ) format = MP4::CoverArt::GIF; #endif if ( format ) { MP4::CoverArtList coverArtList; coverArtList.append( MP4::CoverArt( format, *picture ) ); itemListMap.insert( "covr", coverArtList ); } } mustSave = true; } else if ( isOgg( file ) ) { Ogg::XiphComment *xiphComment = getXiphComment( file ); if ( xiphComment ) { xiphComment->removeField( "METADATA_BLOCK_PICTURE" ); if ( hasPicture ) { FLAC::Picture flacPicture; flacPicture.setMimeType( pictureMimeType.data() ); flacPicture.setType( FLAC::Picture::FrontCover ); flacPicture.setData( *picture ); const ByteVector pict_data = flacPicture.render(); xiphComment->addField( "METADATA_BLOCK_PICTURE", QByteArray::fromRawData( pict_data.data(), pict_data.size() ).toBase64().data() ); } mustSave = true; } } } else if ( !isChecked() ) //Usuwanie wszystkich znanych tagów { mustSave = true; if ( instanceOf( file, MPEG::File ) ) ( ( MPEG::File & )file ).strip(); else if ( instanceOf( file, MPC::File ) ) ( ( MPC::File & )file ).strip(); else if ( instanceOf( file, WavPack::File ) ) ( ( WavPack::File & )file ).strip(); else if ( instanceOf( file, TrueAudio::File ) ) ( ( TrueAudio::File & )file ).strip(); else if ( instanceOf( file, APE::File ) ) ( ( APE::File & )file ).strip(); else if ( instanceOf( file, MP4::File ) ) ( ( MP4::File & )file ).tag()->itemListMap().clear(); else if ( instanceOf( file, ASF::File ) ) ( ( ASF::File & )file ).tag()->attributeListMap().clear(); else if ( isOgg( file ) ) removeXiphComment( getXiphComment( file ) ); else if ( instanceOf( file, FLAC::File ) ) { FLAC::File &flacF = ( FLAC::File & )file; flacF.removePictures(); #if TAGLIB19 if ( flacF.hasXiphComment() ) #endif removeXiphComment( flacF.xiphComment() ); } else if ( instanceOf( file, RIFF::AIFF::File ) ) { ID3v2::Tag *id3v2 = ( ( RIFF::AIFF::File & )file ).tag(); if ( id3v2 ) { ID3v2::FrameList frameList = id3v2->frameList(); for ( ID3v2::FrameList::ConstIterator it = frameList.begin() ; it != frameList.end() ; ++it ) id3v2->removeFrame( *it ); } } #if TAGLIB18 else if ( instanceOf( file, Mod::File ) || instanceOf( file, S3M::File ) || instanceOf( file, IT::File ) || instanceOf( file, XM::File ) ) { Mod::Tag *modTag = NULL; if ( instanceOf( file, Mod::File ) ) modTag = ( ( Mod::File & )file ).tag(); else if ( instanceOf( file, S3M::File ) ) modTag = ( ( S3M::File & )file ).tag(); else if ( instanceOf( file, IT::File ) ) modTag = ( ( IT::File & )file ).tag(); else if ( instanceOf( file, XM::File ) ) modTag = ( ( XM::File & )file ).tag(); if ( modTag ) modTag->setTrackerName( String::null ); } #endif } /* FLAC::File writer BUG workaround - remove ID3 tags */ if ( mustSave && instanceOf( file, FLAC::File ) ) { FLAC::File &flacF = ( FLAC::File & )file; #if TAGLIB19 if ( flacF.hasID3v1Tag() || flacF.hasID3v2Tag() ) #else if ( flacF.ID3v1Tag() || flacF.ID3v2Tag() ) #endif { const FileName fName = fRef->file()->name(); result = fRef->save(); delete fRef; fRef = NULL; if ( result ) result = MPEG::File( fName, false ).save( MPEG::File::NoTags ); mustSave = false; } } #if TAGLIB19 /* No ID3v2 in WAV, only InfoTag */ if ( mustSave && instanceOf( file, RIFF::WAV::File ) ) { RIFF::WAV::File &wavF = ( RIFF::WAV::File & )file; wavF.save( wavF.InfoTag()->isEmpty() ? RIFF::WAV::File::NoTags : RIFF::WAV::File::Info ); mustSave = false; } #endif return mustSave ? fRef->save() : ( fRef ? true : result ); } return false; }
bool TagEditor::open( const QString &fileName ) { clear(); #ifdef Q_OS_WIN fRef = new FileRef( ( const wchar_t * )fileName.utf16(), false ); #else fRef = new FileRef( fileName.toLocal8Bit(), false ); #endif if ( !fRef->isNull() && fRef->tag() ) { File &file = *fRef->file(); #if TAGLIB19 /* Copy ID3v2 to InfoTag */ if ( instanceOf( file, RIFF::WAV::File ) ) { const Tag &tag = *fRef->tag(); RIFF::Info::Tag &infoTag = *( ( RIFF::WAV::File & )file ).InfoTag(); if ( infoTag.isEmpty() && !tag.isEmpty() ) { infoTag.setTitle( tag.title() ); infoTag.setArtist( tag.artist() ); infoTag.setAlbum( tag.album() ); infoTag.setComment( tag.comment() ); infoTag.setGenre( tag.genre() ); infoTag.setYear( tag.year() ); infoTag.setTrack( tag.track() ); } } #endif const Tag &tag = getTag( *fRef, file ); bool hasTags = !tag.isEmpty(); setChecked( true ); if ( hasTags ) { titleE->setText( tag.title().toCString( true ) ); artistE->setText( tag.artist().toCString( true ) ); albumE->setText( tag.album().toCString( true ) ); commentE->setText( tag.comment().toCString( true ) ); genreE->setText( tag.genre().toCString( true ) ); yearB->setValue( tag.year() ); trackB->setValue( tag.track() ); } /* Covers */ if ( instanceOf( file, MPEG::File ) || instanceOf( file, RIFF::AIFF::File ) ) { pictureB->setEnabled( true ); if ( hasTags ) { ID3v2::Tag *id3v2 = NULL; if ( instanceOf( file, MPEG::File ) ) { MPEG::File &mpegF = ( MPEG::File & )file; #if TAGLIB19 if ( mpegF.hasID3v2Tag() ) #endif id3v2 = mpegF.ID3v2Tag(); } else if ( instanceOf( file, RIFF::AIFF::File ) ) id3v2 = ( ( RIFF::AIFF::File & )file ).tag(); if ( id3v2 ) { const ID3v2::FrameList &frameList = id3v2->frameList( "APIC" ); if ( !frameList.isEmpty() ) { ID3v2::AttachedPictureFrame &pictureFrame = *( ID3v2::AttachedPictureFrame * )frameList.front(); pictureMimeType = pictureFrame.mimeType().toCString(); *picture = pictureFrame.picture(); pictureB->setChecked( true ); pictureW->update(); } } } } else if ( instanceOf( file, FLAC::File ) ) { pictureB->setEnabled( true ); FLAC::File &flacF = ( FLAC::File & )file; if ( !flacF.pictureList().isEmpty() ) { FLAC::Picture &flacPicture = *flacF.pictureList().front(); pictureMimeType = flacPicture.mimeType().toCString(); *picture = flacPicture.data(); pictureB->setChecked( true ); pictureW->update(); hasTags = true; } } else if ( instanceOf( file, MP4::File ) ) { MP4::ItemListMap &itemListMap = ( ( MP4::File & )file ).tag()->itemListMap(); MP4::ItemListMap::ConstIterator it = itemListMap.find( "covr" ); pictureB->setEnabled( true ); if ( it != itemListMap.end() ) { MP4::CoverArtList coverArtList = it->second.toCoverArtList(); if ( !coverArtList.isEmpty() ) { MP4::CoverArt coverArt = coverArtList.front(); switch ( coverArt.format() ) { case MP4::CoverArt::JPEG: pictureMimeType = "image/jpeg"; break; case MP4::CoverArt::PNG: pictureMimeType = "image/png"; break; #if TAGLIB18 case MP4::CoverArt::BMP: pictureMimeType = "image/bmp"; break; case MP4::CoverArt::GIF: pictureMimeType = "image/gif"; break; #endif default: break; } if ( !pictureMimeType.isEmpty() ) { *picture = coverArt.data(); pictureB->setChecked( true ); pictureW->update(); hasTags = true; } } } } else if ( isOgg( file ) ) { const Ogg::XiphComment *xiphComment = getXiphComment( file ); if ( xiphComment ) { const Ogg::FieldListMap &fieldListMap = xiphComment->fieldListMap(); Ogg::FieldListMap::ConstIterator it = fieldListMap.find( "METADATA_BLOCK_PICTURE" ); pictureB->setEnabled( true ); if ( it != fieldListMap.end() && !it->second.isEmpty() ) { /* OGG picture and FLAC picture are the same except OGG picture is encoded into Base64 */ QByteArray pict_frame_decoded = QByteArray::fromBase64( it->second.front().toCString() ); FLAC::Picture flacPicture; if ( flacPicture.parse( ByteVector( pict_frame_decoded.data(), pict_frame_decoded.size() ) ) ) { pictureMimeType = flacPicture.mimeType().toCString(); *picture = flacPicture.data(); pictureB->setChecked( true ); pictureW->update(); } } } } pictureBChecked = pictureB->isChecked(); setChecked( hasTags ); return true; } delete fRef; fRef = NULL; return false; }
bool CTagLoaderTagLib::ParseTag(MP4::Tag *mp4, EmbeddedArt *art, CMusicInfoTag& tag) { if (!mp4) return false; ReplayGain replayGainInfo; MP4::ItemListMap& itemListMap = mp4->itemListMap(); for (MP4::ItemListMap::ConstIterator it = itemListMap.begin(); it != itemListMap.end(); ++it) { if (it->first == "\251nam") tag.SetTitle(it->second.toStringList().front().to8Bit(true)); else if (it->first == "\251ART") SetArtist(tag, StringListToVectorString(it->second.toStringList())); else if (it->first == "----:com.apple.iTunes:ARTISTS") SetArtistHints(tag, StringListToVectorString(it->second.toStringList())); else if (it->first == "\251alb") tag.SetAlbum(it->second.toStringList().front().to8Bit(true)); else if (it->first == "aART") SetAlbumArtist(tag, StringListToVectorString(it->second.toStringList())); else if (it->first == "----:com.apple.iTunes:ALBUMARTISTS") SetAlbumArtistHints(tag, StringListToVectorString(it->second.toStringList())); else if (it->first == "\251gen") SetGenre(tag, StringListToVectorString(it->second.toStringList())); else if (it->first == "----:com.apple.iTunes:MOOD") tag.SetMood(it->second.toStringList().front().to8Bit(true)); else if (it->first == "\251cmt") tag.SetComment(it->second.toStringList().front().to8Bit(true)); else if (it->first == "\251wrt") AddArtistRole(tag, "Composer", StringListToVectorString(it->second.toStringList())); else if (it->first == "----:com.apple.iTunes:CONDUCTOR") AddArtistRole(tag, "Conductor", StringListToVectorString(it->second.toStringList())); //No MP4 standard tag for "ensemble" else if (it->first == "----:com.apple.iTunes:LYRICIST") AddArtistRole(tag, "Lyricist", StringListToVectorString(it->second.toStringList())); else if (it->first == "----:com.apple.iTunes:REMIXER") AddArtistRole(tag, "Remixer", StringListToVectorString(it->second.toStringList())); else if (it->first == "----:com.apple.iTunes:ENGINEER") AddArtistRole(tag, "Engineer", StringListToVectorString(it->second.toStringList())); else if (it->first == "----:com.apple.iTunes:PRODUCER") AddArtistRole(tag, "Producer", StringListToVectorString(it->second.toStringList())); else if (it->first == "----:com.apple.iTunes:DJMIXER") AddArtistRole(tag, "DJMixer", StringListToVectorString(it->second.toStringList())); else if (it->first == "----:com.apple.iTunes:MIXER") AddArtistRole(tag, "Mixer", StringListToVectorString(it->second.toStringList())); //No MP4 standard tag for musician credits else if (it->first == "----:com.apple.iTunes:LABEL") {} // Publisher. Known unsupported, supress warnings else if (it->first == "cpil") tag.SetCompilation(it->second.toBool()); else if (it->first == "trkn") tag.SetTrackNumber(it->second.toIntPair().first); else if (it->first == "disk") tag.SetDiscNumber(it->second.toIntPair().first); else if (it->first == "\251day") tag.SetYear(it->second.toStringList().front().toInt()); else if (it->first == "----:com.apple.iTunes:replaygain_track_gain") replayGainInfo.ParseGain(ReplayGain::TRACK, it->second.toStringList().front().toCString()); else if (it->first == "----:com.apple.iTunes:replaygain_album_gain") replayGainInfo.ParseGain(ReplayGain::ALBUM, it->second.toStringList().front().toCString()); else if (it->first == "----:com.apple.iTunes:replaygain_track_peak") replayGainInfo.ParsePeak(ReplayGain::TRACK, it->second.toStringList().front().toCString()); else if (it->first == "----:com.apple.iTunes:replaygain_album_peak") replayGainInfo.ParsePeak(ReplayGain::ALBUM, it->second.toStringList().front().toCString()); else if (it->first == "----:com.apple.iTunes:MusicBrainz Artist Id") tag.SetMusicBrainzArtistID(SplitMBID(StringListToVectorString(it->second.toStringList()))); else if (it->first == "----:com.apple.iTunes:MusicBrainz Album Artist Id") tag.SetMusicBrainzAlbumArtistID(SplitMBID(StringListToVectorString(it->second.toStringList()))); else if (it->first == "----:com.apple.iTunes:MusicBrainz Album Artist") SetAlbumArtist(tag, StringListToVectorString(it->second.toStringList())); else if (it->first == "----:com.apple.iTunes:MusicBrainz Album Id") tag.SetMusicBrainzAlbumID(it->second.toStringList().front().to8Bit(true)); else if (it->first == "----:com.apple.iTunes:MusicBrainz Track Id") tag.SetMusicBrainzTrackID(it->second.toStringList().front().to8Bit(true)); else if (it->first == "covr") { MP4::CoverArtList coverArtList = it->second.toCoverArtList(); for (MP4::CoverArtList::ConstIterator pt = coverArtList.begin(); pt != coverArtList.end(); ++pt) { std::string mime; switch (pt->format()) { case MP4::CoverArt::PNG: mime = "image/png"; break; case MP4::CoverArt::JPEG: mime = "image/jpeg"; break; default: break; } if (mime.empty()) continue; tag.SetCoverArtInfo(pt->data().size(), mime); if (art) art->set(reinterpret_cast<const uint8_t *>(pt->data().data()), pt->data().size(), mime); break; // one is enough } } } if (mp4->comment() != String::null) tag.SetComment(mp4->comment().toCString(true)); tag.SetReplayGain(replayGainInfo); return true; }