#include #include "matroskafile.h" #include "matroskatag.h" #include "matroskasimpletag.h" #include "matroskaattachments.h" #include "matroskaattachedfile.h" #include "matroskachapters.h" #include "matroskachapteredition.h" #include "tstring.h" #include "tutils.h" #include "tbytevector.h" #define GREEN_TEXT(s) "" s "" #define PRINT_PRETTY(label, value) printf(" " GREEN_TEXT(label) ": %s\n", value) int main(int argc, char *argv[]) { if(argc != 2) { printf("Usage: matroskareader FILE\n"); return 1; } TagLib::Matroska::File file(argv[1]); if(!file.isValid()) { printf("File is not valid\n"); return 1; } auto tag = dynamic_cast(file.tag()); if(!tag) { printf("File has no tag\n"); return 0; } const TagLib::Matroska::SimpleTagsList &list = tag->simpleTagsList(); printf("Found %u tag(s):\n", list.size()); for(const TagLib::Matroska::SimpleTag &t : list) { PRINT_PRETTY("Tag Name", t.name().toCString(true)); if(t.type() == TagLib::Matroska::SimpleTag::StringType) PRINT_PRETTY("Tag Value", t.toString().toCString(true)); else if(t.type() == TagLib::Matroska::SimpleTag::BinaryType) PRINT_PRETTY("Tag Value", TagLib::Utils::formatString("Binary with size %i", t.toByteVector().size()).toCString(false) ); auto targetTypeValue = static_cast(t.targetTypeValue()); PRINT_PRETTY("Target Type Value", targetTypeValue == 0 ? "None" : TagLib::Utils::formatString("%i", targetTypeValue).toCString(false) ); if(auto trackUid = t.trackUid()) { PRINT_PRETTY("Track UID", TagLib::Utils::formatString("%llu",trackUid).toCString(false) ); } const TagLib::String &language = t.language(); PRINT_PRETTY("Language", !language.isEmpty() ? language.toCString(false) : "Not set"); printf("\n"); } TagLib::Matroska::Attachments *attachments = file.attachments(); if(attachments) { const TagLib::Matroska::Attachments::AttachedFileList &list = attachments->attachedFileList(); printf("Found %u attachment(s)\n", list.size()); for(const auto &attachedFile : list) { PRINT_PRETTY("Filename", attachedFile.fileName().toCString(true)); const TagLib::String &description = attachedFile.description(); PRINT_PRETTY("Description", !description.isEmpty() ? description.toCString(true) : "None"); const TagLib::String &mediaType = attachedFile.mediaType(); PRINT_PRETTY("Media Type", !mediaType.isEmpty() ? mediaType.toCString(false) : "None"); PRINT_PRETTY("Data Size", TagLib::Utils::formatString("%u byte(s)", attachedFile.data().size()).toCString(false) ); PRINT_PRETTY("UID", TagLib::Utils::formatString("%llu", attachedFile.uid()).toCString(false) ); } } else printf("File has no attachments\n"); TagLib::Matroska::Chapters *chapters = file.chapters(); if(chapters) { printf("Chapters:\n"); const TagLib::Matroska::Chapters::ChapterEditionList &editions = chapters->chapterEditionList(); for(const auto &edition : editions) { if(edition.uid()) { PRINT_PRETTY("Edition UID", TagLib::Utils::formatString("%llu", edition.uid()) .toCString(false)); } PRINT_PRETTY("Edition Flags", TagLib::Utils::formatString("default=%d, ordered=%d", edition.isDefault(), edition.isOrdered()) .toCString(false)); printf("\n"); for(const auto &chapter : edition.chapterList()) { PRINT_PRETTY("Chapter UID", TagLib::Utils::formatString("%llu", chapter.uid()) .toCString(false)); PRINT_PRETTY("Chapter flags", TagLib::Utils::formatString("hidden=%d", chapter.isHidden()) .toCString(false)); PRINT_PRETTY("Start-End", TagLib::Utils::formatString("%llu-%llu", chapter.timeStart(), chapter.timeEnd()).toCString(false)); for(const auto &display : chapter.displayList()) { PRINT_PRETTY("Display", display.string().toCString(false)); PRINT_PRETTY("Language", !display.language().isEmpty() ? display.language().toCString(false) : "Not set"); } printf("\n"); } } } else printf("File has no chapters\n"); if(auto properties = dynamic_cast(file.audioProperties())) { printf("Properties:\n"); PRINT_PRETTY("Doc Type", properties->docType().toCString(false)); PRINT_PRETTY("Doc Type Version", TagLib::String::number(properties->docTypeVersion()).toCString(false)); PRINT_PRETTY("Codec Name", properties->codecName().toCString(true)); PRINT_PRETTY("Bitrate", TagLib::String::number(properties->bitrate()).toCString(false)); PRINT_PRETTY("Sample Rate", TagLib::String::number(properties->sampleRate()).toCString(false)); PRINT_PRETTY("Channels", TagLib::String::number(properties->channels()).toCString(false)); PRINT_PRETTY("Length [ms]", TagLib::String::number(properties->lengthInMilliseconds()).toCString(false)); } return 0; }