Tag Parser 12.4.0
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
Loading...
Searching...
No Matches
mediafileinfo.cpp
Go to the documentation of this file.
1#include "./helper.h"
2
3#include "../abstracttrack.h"
4#include "../mediafileinfo.h"
6#include "../tag.h"
7
8#include <c++utilities/tests/testutils.h>
9using namespace CppUtilities;
10
11#include <cppunit/TestFixture.h>
12#include <cppunit/extensions/HelperMacros.h>
13
14#include <cstdio>
15
16using namespace std;
17using namespace CppUtilities::Literals;
18using namespace TagParser;
19
20using namespace CPPUNIT_NS;
21
26class MediaFileInfoTests : public TestFixture {
27 CPPUNIT_TEST_SUITE(MediaFileInfoTests);
28 CPPUNIT_TEST(testInitialStatus);
29 CPPUNIT_TEST(testFileSystemMethods);
30 CPPUNIT_TEST(testParsingUnsupportedFile);
32 CPPUNIT_TEST_SUITE_END();
33
34public:
35 void setUp() override;
36 void tearDown() override;
37
38 void testInitialStatus();
42
44};
45
47
51
55
57{
58 const MediaFileInfo file;
59 CPPUNIT_ASSERT(!file.areTagsSupported());
60 CPPUNIT_ASSERT(!file.areTracksSupported());
61 CPPUNIT_ASSERT(!file.areChaptersSupported());
62 CPPUNIT_ASSERT(!file.areAttachmentsSupported());
63 CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.containerParsingStatus());
64 CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.tagsParsingStatus());
65 CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.tracksParsingStatus());
66 CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.chaptersParsingStatus());
67 CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.attachmentsParsingStatus());
68 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Unknown, file.containerFormat());
69}
70
72{
73 MediaFileInfo file("/usr/bin/unsupported.bin"sv);
74 CPPUNIT_ASSERT_EQUAL("/usr/bin"s, file.containingDirectory());
75 CPPUNIT_ASSERT_EQUAL("unsupported.bin"s, file.fileName());
76 CPPUNIT_ASSERT_EQUAL("unsupported"s, file.fileName(true));
77 CPPUNIT_ASSERT_EQUAL("/usr/bin/unsupported"s, file.pathWithoutExtension());
78 CPPUNIT_ASSERT_EQUAL(".bin"s, file.extension());
79 CPPUNIT_ASSERT_EQUAL(static_cast<std::uint64_t>(0), file.size());
80 file.reportPathChanged(testFilePath("unsupported.bin"));
81 file.open(true);
82 CPPUNIT_ASSERT(file.isOpen());
83 CPPUNIT_ASSERT(file.isReadOnly());
84 CPPUNIT_ASSERT_EQUAL(static_cast<std::uint64_t>(41), file.size());
85}
86
88{
89 Diagnostics diag;
91 MediaFileInfo file(testFilePath("unsupported.bin"));
92 file.parseContainerFormat(diag, progress);
93 file.parseTags(diag, progress);
94 CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotSupported, file.containerParsingStatus());
95 CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotSupported, file.tagsParsingStatus());
96 CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.tracksParsingStatus());
97 CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.chaptersParsingStatus());
98 CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.attachmentsParsingStatus());
99 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Unknown, file.containerFormat());
100 file.invalidate();
101}
102
104{
105 Diagnostics diag;
107 MediaFileInfo file(testFilePath("mtx-test-data/aac/he-aacv2-ps.m4a"));
108 file.open(true);
109 file.parseContainerFormat(diag, progress);
110 file.parseTags(diag, progress);
111 file.parseAttachments(diag, progress);
112 file.close();
113 CPPUNIT_ASSERT_THROW_MESSAGE("std::ios_base::failure thrown if file closed", file.parseTracks(diag, progress), std::ios_base::failure);
114 CPPUNIT_ASSERT(file.areTagsSupported());
115 CPPUNIT_ASSERT(file.areTracksSupported());
116 CPPUNIT_ASSERT(!file.areChaptersSupported());
117 CPPUNIT_ASSERT(!file.areAttachmentsSupported());
118 CPPUNIT_ASSERT_EQUAL(ParsingStatus::Ok, file.containerParsingStatus());
119 CPPUNIT_ASSERT_EQUAL(ParsingStatus::Ok, file.tagsParsingStatus());
120 CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.tracksParsingStatus());
121 CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.chaptersParsingStatus());
122 CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotSupported, file.attachmentsParsingStatus());
123 CPPUNIT_ASSERT_EQUAL(0_st, file.trackCount());
124 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Mp4, file.containerFormat());
125 CPPUNIT_ASSERT_EQUAL(Diagnostics({ DiagMessage(DiagLevel::Information,
126 "Parsing attachments is not implemented for the container format of the file.", "parsing attachments") }),
127 diag);
128 CPPUNIT_ASSERT_EQUAL(DiagLevel::Information, diag.level());
129
130 // create/remove tag
131 CPPUNIT_ASSERT_EQUAL(0_st, file.matroskaTags().size());
132 CPPUNIT_ASSERT(!file.id3v1Tag());
133 CPPUNIT_ASSERT_EQUAL(0_st, file.id3v2Tags().size());
134 CPPUNIT_ASSERT(!file.vorbisComment());
135 CPPUNIT_ASSERT(!file.mp4Tag());
136 // NOTE: Maybe it should not be possible to create ID3 tags for MP4 file? It will be ignored anyways.
137 CPPUNIT_ASSERT(file.createId3v1Tag());
138 CPPUNIT_ASSERT(file.id3v1Tag());
139 CPPUNIT_ASSERT(file.createId3v2Tag());
140 CPPUNIT_ASSERT_EQUAL(1_st, file.id3v2Tags().size());
141 CPPUNIT_ASSERT(!file.createVorbisComment());
142 CPPUNIT_ASSERT(!file.vorbisComment());
143 CPPUNIT_ASSERT(!file.removeVorbisComment());
145 CPPUNIT_ASSERT(file.mp4Tag());
146}
147
149{
150 Diagnostics diag;
152 MediaFileInfo file(testFilePath("matroska_wave1/test1.mkv"));
153 file.open(true);
154 file.parseEverything(diag, progress);
155 // calling parse methods twice should not do anything (and hence can not fail anymore because the file has already been closed)
156 file.close();
157 file.parseEverything(diag, progress);
158 CPPUNIT_ASSERT_EQUAL(ParsingStatus::Ok, file.containerParsingStatus());
159 CPPUNIT_ASSERT_EQUAL(ParsingStatus::Ok, file.tagsParsingStatus());
160 CPPUNIT_ASSERT_EQUAL(ParsingStatus::Ok, file.tracksParsingStatus());
161 CPPUNIT_ASSERT_EQUAL(ParsingStatus::Ok, file.chaptersParsingStatus());
162 CPPUNIT_ASSERT_EQUAL(ParsingStatus::Ok, file.attachmentsParsingStatus());
163 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, file.containerFormat());
164
165 // general info
166 CPPUNIT_ASSERT(file.container());
167 CPPUNIT_ASSERT(file.areTagsSupported());
168 CPPUNIT_ASSERT(file.hasAnyTag());
169 CPPUNIT_ASSERT_EQUAL(1_st, file.tags().size());
170 CPPUNIT_ASSERT_EQUAL(1_st, file.matroskaTags().size());
171 CPPUNIT_ASSERT(!file.mp4Tag());
172 CPPUNIT_ASSERT(!file.vorbisComment());
173 CPPUNIT_ASSERT(file.areTracksSupported());
174 CPPUNIT_ASSERT_EQUAL(2_st, file.trackCount());
175 CPPUNIT_ASSERT(file.areChaptersSupported());
176 CPPUNIT_ASSERT_EQUAL(0_st, file.chapters().size());
177 CPPUNIT_ASSERT(file.areAttachmentsSupported());
178 CPPUNIT_ASSERT_EQUAL(0_st, file.attachments().size());
179
180 // notifications
181 CPPUNIT_ASSERT_EQUAL(Diagnostics(), diag);
182 CPPUNIT_ASSERT_EQUAL(DiagLevel::None, diag.level());
183 diag.emplace_back(DiagLevel::Warning, "warning", "test");
184 CPPUNIT_ASSERT_EQUAL(DiagLevel::Warning, diag.level());
185 diag.emplace_back(DiagLevel::Critical, "error", "test");
186 CPPUNIT_ASSERT_EQUAL(DiagLevel::Critical, diag.level());
187
188 // track info / available languages
189 file.tracks().back()->setLocale(Locale("eng"sv, LocaleFormat::ISO_639_2_B));
190 CPPUNIT_ASSERT_EQUAL(unordered_set<string>({ "eng" }), file.availableLanguages());
191 CPPUNIT_ASSERT_EQUAL(unordered_set<string>({}), file.availableLanguages(MediaType::Text));
192 CPPUNIT_ASSERT_EQUAL("ID: 2422994868, type: Video"s, file.tracks()[0]->label());
193 CPPUNIT_ASSERT_EQUAL("ID: 3653291187, type: Audio, language: English"s, file.tracks()[1]->label());
194 CPPUNIT_ASSERT_EQUAL("MS-MPEG-4-480p / MP3-2ch-eng"s, file.technicalSummary());
195}
The MediaFileInfoTests tests convenience methods provided by TagParser::MediaFileInfo.
void testFullParseAndFurtherProperties()
void testParsingUnsupportedFile()
void setUp() override
void tearDown() override
void testPartialParsingAndTagCreationOfMp4File()
The AbortableProgressFeedback class provides feedback about an ongoing operation via callbacks.
static std::string fileName(std::string_view path, bool cutExtension=false)
Returns the file name of the given file.
static std::string extension(std::string_view path)
Returns the extension of the given file.
void reportPathChanged(std::string_view newPath)
Call this function to report that the path changed.
void invalidate()
Invalidates the file info manually.
bool isReadOnly() const
Indicates whether the last open()/reopen() call was read-only.
static std::string containingDirectory(std::string_view path)
Returns the path of the directory containing the given file.
std::uint64_t size() const
Returns size of the current file in bytes.
void open(bool readOnly=false)
Opens a std::fstream for the current file.
static std::string pathWithoutExtension(std::string_view fullPath)
Returns a copy of the given path without the extension/suffix.
void close()
A possibly opened std::fstream will be closed.
bool isOpen() const
Indicates whether a std::fstream is open for the current file.
The DiagMessage class holds an information, warning or error gathered during parsing or making.
Definition diagnostics.h:41
The Diagnostics class is a container for DiagMessage.
DiagLevel level() const
Returns the worst diag level present in the container.
The MediaFileInfo class allows to read and write tag information providing a container/tag format ind...
const std::vector< std::unique_ptr< Id3v2Tag > > & id3v2Tags() const
Returns pointers to the assigned ID3v2 tags.
void parseEverything(Diagnostics &diag, AbortableProgressFeedback &progress)
Parses the container format, the tracks and the tag information of the current file.
const std::vector< std::unique_ptr< MatroskaTag > > & matroskaTags() const
Returns pointers to the assigned Matroska tags.
std::vector< AbstractTrack * > tracks() const
Returns the tracks for the current file.
bool areChaptersSupported() const
Returns an indication whether this library supports parsing the chapters of the current file.
ParsingStatus tagsParsingStatus() const
Returns an indication whether tag information has been parsed yet.
VorbisComment * createVorbisComment()
Creates a Vorbis comment for the current file.
VorbisComment * vorbisComment() const
Returns a pointer to the first assigned Vorbis comment or nullptr if none is assigned.
std::size_t trackCount() const
Returns the number of tracks that could be parsed.
void parseAttachments(Diagnostics &diag, AbortableProgressFeedback &progress)
Parses the attachments of the current file.
void parseTracks(Diagnostics &diag, AbortableProgressFeedback &progress)
Parses the tracks of the current file.
bool areAttachmentsSupported() const
Returns an indication whether this library supports attachment format of the current file.
void parseContainerFormat(Diagnostics &diag, AbortableProgressFeedback &progress)
Parses the container format of the current file.
ParsingStatus tracksParsingStatus() const
Returns an indication whether tracks have been parsed yet.
Id3v1Tag * id3v1Tag() const
Returns a pointer to the assigned ID3v1 tag or nullptr if none is assigned.
std::string technicalSummary() const
Generates a short technical summary about the file's tracks.
bool removeVorbisComment()
Removes all assigned Vorbis comment from the current file.
void parseTags(Diagnostics &diag, AbortableProgressFeedback &progress)
Parses the tag(s) of the current file.
Id3v2Tag * createId3v2Tag()
Creates an ID3v2 tag for the current file.
bool areTracksSupported() const
Returns an indication whether this library supports parsing the tracks information of the current fil...
bool createAppropriateTags(const TagCreationSettings &settings=TagCreationSettings())
Ensures appropriate tags are created according the given settings.
void tags(std::vector< Tag * > &tags) const
Stores all tags assigned to the current file in the specified vector.
ParsingStatus attachmentsParsingStatus() const
Returns whether the attachments have been parsed yet.
Id3v1Tag * createId3v1Tag()
Creates an ID3v1 tag for the current file.
std::unordered_set< std::string > availableLanguages(TagParser::MediaType type=TagParser::MediaType::Audio) const
Determines the available languages for specified media type (by default MediaType::Audio).
bool areTagsSupported() const
Returns an indication whether this library supports the tag format of the current file.
AbstractContainer * container() const
Returns the container for the current file.
ContainerFormat containerFormat() const
Returns the container format of the current file.
ParsingStatus containerParsingStatus() const
Returns an indication whether the container format has been parsed yet.
std::vector< AbstractChapter * > chapters() const
Returns all chapters assigned to the current file.
std::vector< AbstractAttachment * > attachments() const
Returns all attachments assigned to the current file.
ParsingStatus chaptersParsingStatus() const
Returns whether the chapters have been parsed yet.
bool hasAnyTag() const
Returns an indication whether a tag of any format is assigned.
Mp4Tag * mp4Tag() const
Returns a pointer to the assigned MP4 tag or nullptr if none is assigned.
Contains all classes and functions of the TagInfo library.
Definition aaccodebook.h:10
The Locale struct specifies a language and/or a country using one or more LocaleDetail objects.
CPPUNIT_TEST_SUITE_REGISTRATION(MediaFileInfoTests)