Test parsing and rewriting nested Mkv tags
This commit is contained in:
parent
23e84886d4
commit
ee15e08dd9
|
@ -0,0 +1,29 @@
|
||||||
|
<!ELEMENT Tags (Tag*)>
|
||||||
|
<!ELEMENT Tag (
|
||||||
|
Targets,
|
||||||
|
Simple*)>
|
||||||
|
|
||||||
|
<!ELEMENT Targets (
|
||||||
|
TrackUID*,
|
||||||
|
ChapterUID*,
|
||||||
|
AttachmentUID*,
|
||||||
|
EditionUID*,
|
||||||
|
TargetType?,
|
||||||
|
TargetTypeValue?)>
|
||||||
|
|
||||||
|
<!ELEMENT TrackUID (#PCDATA)>
|
||||||
|
<!ELEMENT ChapterUID (#PCDATA)>
|
||||||
|
<!ELEMENT AttachmentUID (#PCDATA)>
|
||||||
|
<!ELEMENT EditionUID (#PCDATA)>
|
||||||
|
<!ELEMENT TargetType (#PCDATA)>
|
||||||
|
<!ELEMENT TargetTypeValue (#PCDATA)>
|
||||||
|
|
||||||
|
<!ELEMENT Simple (
|
||||||
|
Name,
|
||||||
|
String?,
|
||||||
|
Binary?,
|
||||||
|
TagLanguage?,
|
||||||
|
DefaultLanguage?,
|
||||||
|
Simple*)>
|
||||||
|
<!ELEMENT TagLanguage (#PCDATA)>
|
||||||
|
<!ELEMENT DefaultLanguage (#PCDATA)>
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- <!DOCTYPE Tags SYSTEM "matroskatags.dtd"> -->
|
||||||
|
<Tags>
|
||||||
|
<Tag>
|
||||||
|
<Simple>
|
||||||
|
<Name>TITLE</Name>
|
||||||
|
<String>Vanilla Sky</String>
|
||||||
|
<TagLanguage>und</TagLanguage>
|
||||||
|
</Simple>
|
||||||
|
<Simple>
|
||||||
|
<Name>ARTIST</Name>
|
||||||
|
<String>Test artist</String>
|
||||||
|
<TagLanguage>und</TagLanguage>
|
||||||
|
<Simple>
|
||||||
|
<Name>ADDRESS</Name>
|
||||||
|
<String>Test address</String>
|
||||||
|
<TagLanguage>und</TagLanguage>
|
||||||
|
</Simple>
|
||||||
|
</Simple>
|
||||||
|
<Targets>
|
||||||
|
<TargetTypeValue>50</TargetTypeValue>
|
||||||
|
</Targets>
|
||||||
|
</Tag>
|
||||||
|
<Tag>
|
||||||
|
<Simple>
|
||||||
|
<Name>TITLE</Name>
|
||||||
|
<String>Main video track</String>
|
||||||
|
<TagLanguage>und</TagLanguage>
|
||||||
|
</Simple>
|
||||||
|
<Targets>
|
||||||
|
<TrackUID>3164620769</TrackUID>
|
||||||
|
<TargetTypeValue>50</TargetTypeValue>
|
||||||
|
</Targets>
|
||||||
|
</Tag>
|
||||||
|
<Tag>
|
||||||
|
<Simple>
|
||||||
|
<Name>TITLE</Name>
|
||||||
|
<String>English audio track</String>
|
||||||
|
<TagLanguage>und</TagLanguage>
|
||||||
|
</Simple>
|
||||||
|
<Targets>
|
||||||
|
<TrackUID>3571773145</TrackUID>
|
||||||
|
<TargetTypeValue>50</TargetTypeValue>
|
||||||
|
</Targets>
|
||||||
|
</Tag>
|
||||||
|
</Tags>
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace ConversionUtilities;
|
using namespace ConversionUtilities;
|
||||||
|
using namespace TestUtilities;
|
||||||
using namespace Media;
|
using namespace Media;
|
||||||
|
|
||||||
using namespace CPPUNIT_NS;
|
using namespace CPPUNIT_NS;
|
||||||
|
@ -53,7 +54,8 @@ class OverallTests : public TestFixture
|
||||||
CPPUNIT_TEST(testMp3Making);
|
CPPUNIT_TEST(testMp3Making);
|
||||||
CPPUNIT_TEST(testOggMaking);
|
CPPUNIT_TEST(testOggMaking);
|
||||||
CPPUNIT_TEST(testFlacMaking);
|
CPPUNIT_TEST(testFlacMaking);
|
||||||
CPPUNIT_TEST(testMkvMaking);
|
CPPUNIT_TEST(testMkvMakingWithDifferentSettings);
|
||||||
|
CPPUNIT_TEST(testMkvMakingNestedTags);
|
||||||
#endif
|
#endif
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
|
@ -61,6 +63,7 @@ public:
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
|
||||||
|
private:
|
||||||
void parseFile(const string &path, void (OverallTests::* checkRoutine)(void));
|
void parseFile(const string &path, void (OverallTests::* checkRoutine)(void));
|
||||||
void makeFile(const string &path, void (OverallTests::* modifyRoutine)(void), void (OverallTests::* checkRoutine)(void));
|
void makeFile(const string &path, void (OverallTests::* modifyRoutine)(void), void (OverallTests::* checkRoutine)(void));
|
||||||
|
|
||||||
|
@ -73,6 +76,7 @@ public:
|
||||||
void checkMkvTestfile7();
|
void checkMkvTestfile7();
|
||||||
void checkMkvTestfile8();
|
void checkMkvTestfile8();
|
||||||
void checkMkvTestfileHandbrakeChapters();
|
void checkMkvTestfileHandbrakeChapters();
|
||||||
|
void checkMkvTestfileNestedTags();
|
||||||
void checkMkvTestMetaData();
|
void checkMkvTestMetaData();
|
||||||
void checkMkvPaddingConstraints();
|
void checkMkvPaddingConstraints();
|
||||||
|
|
||||||
|
@ -100,14 +104,18 @@ public:
|
||||||
void setMp3TestMetaData();
|
void setMp3TestMetaData();
|
||||||
void setOggTestMetaData();
|
void setOggTestMetaData();
|
||||||
void removeAllTags();
|
void removeAllTags();
|
||||||
|
void noop();
|
||||||
|
void createMkvWithNestedTags();
|
||||||
|
|
||||||
|
public:
|
||||||
void testMkvParsing();
|
void testMkvParsing();
|
||||||
void testMp4Parsing();
|
void testMp4Parsing();
|
||||||
void testMp3Parsing();
|
void testMp3Parsing();
|
||||||
void testOggParsing();
|
void testOggParsing();
|
||||||
void testFlacParsing();
|
void testFlacParsing();
|
||||||
#ifdef PLATFORM_UNIX
|
#ifdef PLATFORM_UNIX
|
||||||
void testMkvMaking();
|
void testMkvMakingWithDifferentSettings();
|
||||||
|
void testMkvMakingNestedTags();
|
||||||
void testMp4Making();
|
void testMp4Making();
|
||||||
void testMp3Making();
|
void testMp3Making();
|
||||||
void testOggMaking();
|
void testOggMaking();
|
||||||
|
@ -123,6 +131,7 @@ private:
|
||||||
TagValue m_testTotalParts;
|
TagValue m_testTotalParts;
|
||||||
TagValue m_testPosition;
|
TagValue m_testPosition;
|
||||||
queue<TagValue> m_preservedMetaData;
|
queue<TagValue> m_preservedMetaData;
|
||||||
|
string m_nestedTagsMkvPath;
|
||||||
TagStatus m_tagStatus;
|
TagStatus m_tagStatus;
|
||||||
uint16 m_mode;
|
uint16 m_mode;
|
||||||
};
|
};
|
||||||
|
@ -143,7 +152,11 @@ void OverallTests::setUp()
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverallTests::tearDown()
|
void OverallTests::tearDown()
|
||||||
{}
|
{
|
||||||
|
if(!m_nestedTagsMkvPath.empty()) {
|
||||||
|
remove(m_nestedTagsMkvPath.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Parses the specified file and tests the results using the specified check routine.
|
* \brief Parses the specified file and tests the results using the specified check routine.
|
||||||
|
@ -595,6 +608,42 @@ void OverallTests::checkMkvTestfileHandbrakeChapters()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks "mtx-test-data/mkv/nested-tags.mkv" ("mtx-test-data/mkv/tags.mkv" where "mkv/nested-tags.xml" has been applied).
|
||||||
|
*/
|
||||||
|
void OverallTests::checkMkvTestfileNestedTags()
|
||||||
|
{
|
||||||
|
CPPUNIT_ASSERT(m_fileInfo.containerFormat() == ContainerFormat::Matroska);
|
||||||
|
const auto tags = m_fileInfo.tags();
|
||||||
|
bool generalTagFound = false;
|
||||||
|
switch(m_tagStatus) {
|
||||||
|
case TagStatus::Original:
|
||||||
|
case TagStatus::TestMetaDataPresent:
|
||||||
|
CPPUNIT_ASSERT_EQUAL(5ul, tags.size());
|
||||||
|
for(const Tag *tag : tags) {
|
||||||
|
CPPUNIT_ASSERT(tag->type() == TagType::MatroskaTag);
|
||||||
|
const auto *mkvTag = static_cast<const MatroskaTag *>(tag);
|
||||||
|
const auto &target = mkvTag->target();
|
||||||
|
if(target.level() == 50 && target.tracks().empty()) {
|
||||||
|
generalTagFound = true;
|
||||||
|
CPPUNIT_ASSERT_EQUAL("Vanilla Sky"s, tag->value(KnownField::Title).toString());
|
||||||
|
const auto &fields = mkvTag->fields();
|
||||||
|
const auto &artistField = fields.find(mkvTag->fieldId(KnownField::Artist));
|
||||||
|
CPPUNIT_ASSERT(artistField != fields.end());
|
||||||
|
CPPUNIT_ASSERT_EQUAL("Test artist"s, artistField->second.value().toString());
|
||||||
|
const auto &nestedFields = artistField->second.nestedFields();
|
||||||
|
CPPUNIT_ASSERT_EQUAL(1ul, nestedFields.size());
|
||||||
|
CPPUNIT_ASSERT_EQUAL("ADDRESS"s, nestedFields[0].idToString());
|
||||||
|
CPPUNIT_ASSERT_EQUAL("Test address"s, nestedFields[0].value().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CPPUNIT_ASSERT(generalTagFound);
|
||||||
|
break;
|
||||||
|
case TagStatus::Removed:
|
||||||
|
CPPUNIT_ASSERT(tags.size() == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Checks whether test meta data for Matroska files has been applied correctly.
|
* \brief Checks whether test meta data for Matroska files has been applied correctly.
|
||||||
*/
|
*/
|
||||||
|
@ -1298,6 +1347,47 @@ void OverallTests::removeAllTags()
|
||||||
m_fileInfo.removeAllTags();
|
m_fileInfo.removeAllTags();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Does nothing.
|
||||||
|
* \remarks Used to just resave the file.
|
||||||
|
*/
|
||||||
|
void OverallTests::noop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Creates a Matroska test file with nested tags from "mtx-test-data/mkv/nested-tags.mkv" using "mkv/nested-tags.xml".
|
||||||
|
* \remarks Requires mkvmerge.
|
||||||
|
* \todo Make mkvmerge path variable.
|
||||||
|
*/
|
||||||
|
void OverallTests::createMkvWithNestedTags()
|
||||||
|
{
|
||||||
|
#ifdef PLATFORM_UNIX
|
||||||
|
m_nestedTagsMkvPath = workingCopyPathMode("mtx-test-data/mkv/nested-tags.mkv", WorkingCopyMode::NoCopy);
|
||||||
|
remove(m_nestedTagsMkvPath.data());
|
||||||
|
|
||||||
|
cerr << "\n\ncreating testfile \"" << m_nestedTagsMkvPath << "\" with mkvmerge" << endl;
|
||||||
|
const string tagsMkvPath(testFilePath("mtx-test-data/mkv/tags.mkv"));
|
||||||
|
const string tagsXmlPath(testFilePath("mkv/nested-tags.xml"));
|
||||||
|
const char *const mkvmergeArgs[] = {
|
||||||
|
"--ui-language en_US",
|
||||||
|
"--output", m_nestedTagsMkvPath.data(),
|
||||||
|
"--no-global-tags", "--language", "0:und", "--default-track", "0:yes", "--language", "1:und", "--default-track", "1:yes",
|
||||||
|
"(", tagsMkvPath.data(), ")",
|
||||||
|
"--global-tags", tagsXmlPath.data(), "--track-order", "0:0,0:1", nullptr
|
||||||
|
};
|
||||||
|
string mkvmergeOutput, mkvmergeErrors;
|
||||||
|
int res = execHelperApp("/bin/mkvmerge", mkvmergeArgs, mkvmergeOutput, mkvmergeErrors);
|
||||||
|
cout << mkvmergeOutput << endl;
|
||||||
|
cerr << mkvmergeErrors << endl;
|
||||||
|
if(res) {
|
||||||
|
cerr << "Failure (exit code " << res << "); unable to test nested tags" << endl;
|
||||||
|
remove(m_nestedTagsMkvPath.data());
|
||||||
|
m_nestedTagsMkvPath.clear();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Tests the Matroska parser via MediaFileInfo.
|
* \brief Tests the Matroska parser via MediaFileInfo.
|
||||||
*/
|
*/
|
||||||
|
@ -1315,14 +1405,21 @@ void OverallTests::testMkvParsing()
|
||||||
parseFile(TestUtilities::testFilePath("matroska_wave1/test7.mkv"), &OverallTests::checkMkvTestfile7);
|
parseFile(TestUtilities::testFilePath("matroska_wave1/test7.mkv"), &OverallTests::checkMkvTestfile7);
|
||||||
parseFile(TestUtilities::testFilePath("matroska_wave1/test8.mkv"), &OverallTests::checkMkvTestfile8);
|
parseFile(TestUtilities::testFilePath("matroska_wave1/test8.mkv"), &OverallTests::checkMkvTestfile8);
|
||||||
parseFile(TestUtilities::testFilePath("mtx-test-data/mkv/handbrake-chapters-2.mkv"), &OverallTests::checkMkvTestfileHandbrakeChapters);
|
parseFile(TestUtilities::testFilePath("mtx-test-data/mkv/handbrake-chapters-2.mkv"), &OverallTests::checkMkvTestfileHandbrakeChapters);
|
||||||
|
createMkvWithNestedTags();
|
||||||
|
if(!m_nestedTagsMkvPath.empty()) {
|
||||||
|
parseFile(m_nestedTagsMkvPath, &OverallTests::checkMkvTestfileNestedTags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PLATFORM_UNIX
|
#ifdef PLATFORM_UNIX
|
||||||
/*!
|
/*!
|
||||||
* \brief Tests the Matroska maker via MediaFileInfo.
|
* \brief Tests the Matroska maker via MediaFileInfo.
|
||||||
|
*
|
||||||
|
* This method tests various combinations of the possible settings.
|
||||||
|
*
|
||||||
* \remarks Relies on the parser to check results.
|
* \remarks Relies on the parser to check results.
|
||||||
*/
|
*/
|
||||||
void OverallTests::testMkvMaking()
|
void OverallTests::testMkvMakingWithDifferentSettings()
|
||||||
{
|
{
|
||||||
// full parse is required to determine padding
|
// full parse is required to determine padding
|
||||||
m_fileInfo.setForceFullParse(true);
|
m_fileInfo.setForceFullParse(true);
|
||||||
|
@ -1399,6 +1496,23 @@ void OverallTests::testMkvMaking()
|
||||||
makeFile(TestUtilities::workingCopyPath("mtx-test-data/mkv/handbrake-chapters-2.mkv"), modifyRoutine, &OverallTests::checkMkvTestfileHandbrakeChapters);
|
makeFile(TestUtilities::workingCopyPath("mtx-test-data/mkv/handbrake-chapters-2.mkv"), modifyRoutine, &OverallTests::checkMkvTestfileHandbrakeChapters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Tests making a Matroska file with nested tags via MediaFileInfo.
|
||||||
|
* \remarks Relies on the parser to check results.
|
||||||
|
*/
|
||||||
|
void OverallTests::testMkvMakingNestedTags()
|
||||||
|
{
|
||||||
|
createMkvWithNestedTags();
|
||||||
|
if(!m_nestedTagsMkvPath.empty()) {
|
||||||
|
cerr << endl << "Matroska maker - rewrite file with nested tags" << endl;
|
||||||
|
m_fileInfo.setMinPadding(0);
|
||||||
|
m_fileInfo.setMaxPadding(0);
|
||||||
|
m_fileInfo.setTagPosition(ElementPosition::BeforeData);
|
||||||
|
m_fileInfo.setIndexPosition(ElementPosition::BeforeData);
|
||||||
|
makeFile(m_nestedTagsMkvPath, &OverallTests::noop, &OverallTests::checkMkvTestfileNestedTags);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -70,6 +70,8 @@ struct TestFile
|
||||||
{"matroska_wave1/test7.mkv", {"95b21c92ad5a4fe00914ff5009e2a64f12fd4c5fb9cb1c3c888ab50bf0ffe483"}},
|
{"matroska_wave1/test7.mkv", {"95b21c92ad5a4fe00914ff5009e2a64f12fd4c5fb9cb1c3c888ab50bf0ffe483"}},
|
||||||
{"matroska_wave1/test8.mkv", {"9dddcd1550b814dae44d62e2b9f27c0eca31d5e190df2220cbf7492e3d6c63da"}},
|
{"matroska_wave1/test8.mkv", {"9dddcd1550b814dae44d62e2b9f27c0eca31d5e190df2220cbf7492e3d6c63da"}},
|
||||||
{"mtx-test-data/mkv/handbrake-chapters-2.mkv", {"eccc55f3b59a77086b3ffb914525d312c7886eae34e3933352dea2f6f6a1974c"}},
|
{"mtx-test-data/mkv/handbrake-chapters-2.mkv", {"eccc55f3b59a77086b3ffb914525d312c7886eae34e3933352dea2f6f6a1974c"}},
|
||||||
|
{"mtx-test-data/mkv/tags.mkv", {"4330019afc3d846600c1ded38158fcac081297f4e56c749251c236f4871e0287"}},
|
||||||
|
{"mkv/nested-tags.xml", {"85cfcc94920f114e52fd1aa3df24706cd2710626e065a2c8c55dd209ec8dc8ce"}},
|
||||||
{"mp4/test1.m4a", {"4f16e0a22525bd13ba859431406d7f5991e0b4f155c51e10e5f32b0c97034b36"}},
|
{"mp4/test1.m4a", {"4f16e0a22525bd13ba859431406d7f5991e0b4f155c51e10e5f32b0c97034b36"}},
|
||||||
{"mtx-test-data/aac/he-aacv2-ps.m4a", {"be54be0ae45b0184583ced8a84a881a1652a449feb7f6a917e11f60efabb68ac"}},
|
{"mtx-test-data/aac/he-aacv2-ps.m4a", {"be54be0ae45b0184583ced8a84a881a1652a449feb7f6a917e11f60efabb68ac"}},
|
||||||
{"mtx-test-data/alac/othertest-itunes.m4a", {"5e9c64cde00902211533fbe38aaa67ef5f79a945e1d717951b78b4bbf9ff84e8"}},
|
{"mtx-test-data/alac/othertest-itunes.m4a", {"5e9c64cde00902211533fbe38aaa67ef5f79a945e1d717951b78b4bbf9ff84e8"}},
|
||||||
|
|
Loading…
Reference in New Issue