mirror of
https://github.com/taglib/taglib.git
synced 2025-06-04 01:28:21 -04:00
Simple ID3v2.4 => ID3v2.3 frame migration
This commit is contained in:
parent
061b381ea8
commit
e8d0551c9a
@ -334,6 +334,61 @@ ByteVector ID3v2::Tag::render() const
|
||||
return render(4);
|
||||
}
|
||||
|
||||
void ID3v2::Tag::downgradeFrames(FrameList *frames, FrameList *newFrames) const
|
||||
{
|
||||
const char *unsupportedFrames[] = {
|
||||
"ASPI", "EQU2", "RVA2", "SEEK", "SIGN", "TDRL", "TDTG",
|
||||
"TMOO", "TPRO", "TSOA", "TSOT", "TSST", "TSOP", "TIPL",
|
||||
"TMCL", 0
|
||||
};
|
||||
ID3v2::TextIdentificationFrame *frameTDOR = 0;
|
||||
ID3v2::TextIdentificationFrame *frameTDRC = 0;
|
||||
for(FrameList::Iterator it = d->frameList.begin(); it != d->frameList.end(); it++) {
|
||||
ID3v2::Frame *frame = *it;
|
||||
ByteVector frameID = frame->header()->frameID();
|
||||
for(int i = 0; unsupportedFrames[i]; i++) {
|
||||
if(frameID == unsupportedFrames[i]) {
|
||||
debug("A frame that is not supported in ID3v2.3 \'"
|
||||
+ String(frameID) + "\' has been discarded");
|
||||
frame = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(frame && frameID == "TDOR") {
|
||||
frameTDOR = dynamic_cast<ID3v2::TextIdentificationFrame *>(frame);
|
||||
frame = 0;
|
||||
}
|
||||
if(frame && frameID == "TDRC") {
|
||||
frameTDRC = dynamic_cast<ID3v2::TextIdentificationFrame *>(frame);
|
||||
frame = 0;
|
||||
}
|
||||
if(frame) {
|
||||
frames->append(frame);
|
||||
}
|
||||
}
|
||||
if(frameTDOR) {
|
||||
String content = frameTDOR->toString();
|
||||
if(content.size() >= 4) {
|
||||
ID3v2::TextIdentificationFrame *frameTORY = new ID3v2::TextIdentificationFrame("TORY", String::Latin1);
|
||||
frameTORY->setText(content.substr(0, 4));
|
||||
frames->append(frameTORY);
|
||||
newFrames->append(frameTORY);
|
||||
}
|
||||
}
|
||||
if(frameTDRC) {
|
||||
// FIXME we can do better here, define also TDAT and TIME
|
||||
String content = frameTDRC->toString();
|
||||
if(content.size() >= 4) {
|
||||
ID3v2::TextIdentificationFrame *frameTYER = new ID3v2::TextIdentificationFrame("TYER", String::Latin1);
|
||||
frameTYER->setText(content.substr(0, 4));
|
||||
frames->append(frameTYER);
|
||||
newFrames->append(frameTYER);
|
||||
}
|
||||
}
|
||||
// FIXME migrate TIPL and TMCL to IPLS
|
||||
}
|
||||
|
||||
|
||||
ByteVector ID3v2::Tag::render(int version) const
|
||||
{
|
||||
// We need to render the "tag data" first so that we have to correct size to
|
||||
@ -347,7 +402,18 @@ ByteVector ID3v2::Tag::render(int version) const
|
||||
|
||||
// Loop through the frames rendering them and adding them to the tagData.
|
||||
|
||||
for(FrameList::Iterator it = d->frameList.begin(); it != d->frameList.end(); it++) {
|
||||
FrameList newFrames;
|
||||
newFrames.setAutoDelete(true);
|
||||
|
||||
FrameList frameList;
|
||||
if(version == 4) {
|
||||
frameList = d->frameList;
|
||||
}
|
||||
else {
|
||||
downgradeFrames(&frameList, &newFrames);
|
||||
}
|
||||
|
||||
for(FrameList::Iterator it = frameList.begin(); it != frameList.end(); it++) {
|
||||
(*it)->header()->setVersion(version);
|
||||
if((*it)->header()->frameID().size() != 4) {
|
||||
debug("A frame of unsupported or unknown type \'"
|
||||
|
@ -295,6 +295,8 @@ namespace TagLib {
|
||||
*/
|
||||
void setTextFrame(const ByteVector &id, const String &value);
|
||||
|
||||
void downgradeFrames(FrameList *existingFrames, FrameList *newFrames) const;
|
||||
|
||||
private:
|
||||
Tag(const Tag &);
|
||||
Tag &operator=(const Tag &);
|
||||
|
@ -64,6 +64,7 @@ class TestID3v2 : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testUpdateGenre23_2);
|
||||
CPPUNIT_TEST(testUpdateGenre24);
|
||||
CPPUNIT_TEST(testUpdateDate22);
|
||||
CPPUNIT_TEST(testDowngradeTo23);
|
||||
// CPPUNIT_TEST(testUpdateFullDate22); TODO TYE+TDA should be upgraded to TDRC together
|
||||
CPPUNIT_TEST(testCompressedFrameWithBrokenLength);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
@ -474,6 +475,48 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(String("2010-04-03"), f.ID3v2Tag()->frameListMap()["TDRC"].front()->toString());
|
||||
}
|
||||
|
||||
void testDowngradeTo23()
|
||||
{
|
||||
ScopedFileCopy copy("xing", ".mp3");
|
||||
string newname = copy.fileName();
|
||||
|
||||
ID3v2::TextIdentificationFrame *tf;
|
||||
MPEG::File foo(newname.c_str());
|
||||
tf = new ID3v2::TextIdentificationFrame("TDOR", String::Latin1);
|
||||
tf->setText("2011-03-16");
|
||||
foo.ID3v2Tag()->addFrame(tf);
|
||||
tf = new ID3v2::TextIdentificationFrame("TDRC", String::Latin1);
|
||||
tf->setText("2012-04-17");
|
||||
foo.ID3v2Tag()->addFrame(tf);
|
||||
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TDRL", String::Latin1));
|
||||
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TDTG", String::Latin1));
|
||||
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TMOO", String::Latin1));
|
||||
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TPRO", String::Latin1));
|
||||
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSOA", String::Latin1));
|
||||
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSOT", String::Latin1));
|
||||
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSST", String::Latin1));
|
||||
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSOP", String::Latin1));
|
||||
foo.save(MPEG::File::AllTags, true, 3);
|
||||
|
||||
MPEG::File bar(newname.c_str());
|
||||
tf = static_cast<ID3v2::TextIdentificationFrame *>(bar.ID3v2Tag()->frameList("TDOR").front());
|
||||
CPPUNIT_ASSERT(tf);
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), tf->fieldList().size());
|
||||
CPPUNIT_ASSERT_EQUAL(String("2011"), tf->fieldList().front());
|
||||
tf = static_cast<ID3v2::TextIdentificationFrame *>(bar.ID3v2Tag()->frameList("TDRC").front());
|
||||
CPPUNIT_ASSERT(tf);
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), tf->fieldList().size());
|
||||
CPPUNIT_ASSERT_EQUAL(String("2012"), tf->fieldList().front());
|
||||
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TDRL"));
|
||||
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TDTG"));
|
||||
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TMOO"));
|
||||
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TPRO"));
|
||||
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSOA"));
|
||||
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSOT"));
|
||||
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSST"));
|
||||
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSOP"));
|
||||
}
|
||||
|
||||
void testCompressedFrameWithBrokenLength()
|
||||
{
|
||||
MPEG::File f("data/compressed_id3_frame.mp3", false);
|
||||
|
Loading…
x
Reference in New Issue
Block a user