mirror of
https://github.com/taglib/taglib.git
synced 2026-02-08 00:10:15 -05:00
Include doc type and version in properties
This commit is contained in:
@ -76,5 +76,15 @@ int main(int argc, char *argv[])
|
||||
else
|
||||
printf("File has no attachments\n");
|
||||
|
||||
if(auto properties = dynamic_cast<const TagLib::Matroska::Properties *>(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;
|
||||
}
|
||||
|
||||
@ -62,6 +62,8 @@ std::unique_ptr<EBML::Element> EBML::Element::factory(File &file)
|
||||
auto id = static_cast<Id>(uintId);
|
||||
switch(id) {
|
||||
RETURN_ELEMENT_FOR_CASE(Id::EBMLHeader);
|
||||
RETURN_ELEMENT_FOR_CASE(Id::DocType);
|
||||
RETURN_ELEMENT_FOR_CASE(Id::DocTypeVersion);
|
||||
RETURN_ELEMENT_FOR_CASE(Id::MkSegment);
|
||||
RETURN_ELEMENT_FOR_CASE(Id::MkInfo);
|
||||
RETURN_ELEMENT_FOR_CASE(Id::MkTracks);
|
||||
|
||||
@ -34,6 +34,8 @@ namespace TagLib::EBML {
|
||||
enum class Id : unsigned int
|
||||
{
|
||||
EBMLHeader = 0x1A45DFA3,
|
||||
DocType = 0x4282,
|
||||
DocTypeVersion = 0x4287,
|
||||
VoidElement = 0xEC,
|
||||
MkSegment = 0x18538067,
|
||||
MkTags = 0x1254C367,
|
||||
@ -143,7 +145,9 @@ namespace TagLib::EBML {
|
||||
template <Element::Id ID>
|
||||
struct GetElementTypeById;
|
||||
|
||||
template <> struct GetElementTypeById<Element::Id::EBMLHeader> { using type = Element; };
|
||||
template <> struct GetElementTypeById<Element::Id::EBMLHeader> { using type = MasterElement; };
|
||||
template <> struct GetElementTypeById<Element::Id::DocType> { using type = Latin1StringElement; };
|
||||
template <> struct GetElementTypeById<Element::Id::DocTypeVersion> { using type = UIntElement; };
|
||||
template <> struct GetElementTypeById<Element::Id::MkSegment> { using type = MkSegment; };
|
||||
template <> struct GetElementTypeById<Element::Id::MkInfo> { using type = MkInfo; };
|
||||
template <> struct GetElementTypeById<Element::Id::MkTracks> { using type = MkTracks; };
|
||||
|
||||
@ -27,6 +27,8 @@
|
||||
#include "matroskasegment.h"
|
||||
#include "ebmlutils.h"
|
||||
#include "ebmlelement.h"
|
||||
#include "ebmlstringelement.h"
|
||||
#include "ebmluintelement.h"
|
||||
#include "ebmlmksegment.h"
|
||||
#include "tlist.h"
|
||||
#include "tdebug.h"
|
||||
@ -96,7 +98,7 @@ Matroska::File::File(IOStream *stream, bool readProperties,
|
||||
|
||||
Matroska::File::~File() = default;
|
||||
|
||||
AudioProperties *Matroska::File::audioProperties() const
|
||||
Matroska::Properties *Matroska::File::audioProperties() const
|
||||
{
|
||||
return d->properties.get();
|
||||
}
|
||||
@ -271,13 +273,19 @@ void Matroska::File::read(bool readProperties, Properties::ReadStyle readStyle)
|
||||
offset_t fileLength = length();
|
||||
|
||||
// Find the EBML Header
|
||||
std::unique_ptr<EBML::Element> head(EBML::Element::factory(*this));
|
||||
auto head = EBML::element_cast<EBML::Element::Id::EBMLHeader>(
|
||||
EBML::Element::factory(*this));
|
||||
if(!head || head->getId() != EBML::Element::Id::EBMLHeader) {
|
||||
debug("Failed to find EBML head");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
head->skipData(*this);
|
||||
if(readProperties) {
|
||||
head->read(*this);
|
||||
}
|
||||
else {
|
||||
head->skipData(*this);
|
||||
}
|
||||
|
||||
// Find the Matroska segment in the file
|
||||
std::unique_ptr<EBML::MkSegment> segment(
|
||||
@ -307,6 +315,19 @@ void Matroska::File::read(bool readProperties, Properties::ReadStyle readStyle)
|
||||
|
||||
if(readProperties) {
|
||||
d->properties = std::make_unique<Properties>(this);
|
||||
|
||||
for(const auto &element : *head) {
|
||||
auto id = element->getId();
|
||||
if (id == EBML::Element::Id::DocType) {
|
||||
d->properties->setDocType(
|
||||
EBML::element_cast<EBML::Element::Id::DocType>(element)->getValue());
|
||||
}
|
||||
else if (id == EBML::Element::Id::DocTypeVersion) {
|
||||
d->properties->setDocTypeVersion(static_cast<int>(
|
||||
EBML::element_cast<EBML::Element::Id::DocTypeVersion>(element)->getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
segment->parseInfo(d->properties.get());
|
||||
segment->parseTracks(d->properties.get());
|
||||
if(d->tag) {
|
||||
|
||||
@ -134,7 +134,7 @@ namespace TagLib::Matroska {
|
||||
* Returns the Matroska::Properties for this file. If no audio properties
|
||||
* were read then this will return a null pointer.
|
||||
*/
|
||||
AudioProperties *audioProperties() const override;
|
||||
Properties *audioProperties() const override;
|
||||
|
||||
/*!
|
||||
* Save the file.
|
||||
|
||||
@ -41,6 +41,8 @@ public:
|
||||
File *file;
|
||||
String codecName;
|
||||
String title;
|
||||
String docType;
|
||||
int docTypeVersion { 0 };
|
||||
int length { 0 };
|
||||
int bitrate { -1 };
|
||||
int sampleRate { 0 };
|
||||
@ -88,6 +90,16 @@ int Matroska::Properties::bitsPerSample() const
|
||||
return d->bitsPerSample;
|
||||
}
|
||||
|
||||
String Matroska::Properties::docType() const
|
||||
{
|
||||
return d->docType;
|
||||
}
|
||||
|
||||
int Matroska::Properties::docTypeVersion() const
|
||||
{
|
||||
return d->docTypeVersion;
|
||||
}
|
||||
|
||||
String Matroska::Properties::codecName() const
|
||||
{
|
||||
return d->codecName;
|
||||
@ -107,11 +119,6 @@ void Matroska::Properties::setLengthInMilliseconds(int length)
|
||||
d->length = length;
|
||||
}
|
||||
|
||||
void Matroska::Properties::setBitrate(int bitrate)
|
||||
{
|
||||
d->bitrate = bitrate;
|
||||
}
|
||||
|
||||
void Matroska::Properties::setSampleRate(int sampleRate)
|
||||
{
|
||||
d->sampleRate = sampleRate;
|
||||
@ -127,6 +134,16 @@ void Matroska::Properties::setBitsPerSample(int bitsPerSample)
|
||||
d->bitsPerSample = bitsPerSample;
|
||||
}
|
||||
|
||||
void Matroska::Properties::setDocType(const String &docType)
|
||||
{
|
||||
d->docType = docType;
|
||||
}
|
||||
|
||||
void Matroska::Properties::setDocTypeVersion(int docTypeVersion)
|
||||
{
|
||||
d->docTypeVersion = docTypeVersion;
|
||||
}
|
||||
|
||||
void Matroska::Properties::setCodecName(const String &codecName)
|
||||
{
|
||||
d->codecName = codecName;
|
||||
|
||||
@ -80,6 +80,16 @@ namespace TagLib::Matroska {
|
||||
*/
|
||||
int bitsPerSample() const;
|
||||
|
||||
/*!
|
||||
* Returns the EBML doc type, "matroska" or "webm".
|
||||
*/
|
||||
String docType() const;
|
||||
|
||||
/*!
|
||||
* Returns the EBML doc type version, typical values are 2 or 4.
|
||||
*/
|
||||
int docTypeVersion() const;
|
||||
|
||||
/*!
|
||||
* Returns the concrete codec name, for example "A_MPEG/L3"
|
||||
* used in the file if available, otherwise an empty string.
|
||||
@ -97,12 +107,14 @@ namespace TagLib::Matroska {
|
||||
class PropertiesPrivate;
|
||||
friend class EBML::MkInfo;
|
||||
friend class EBML::MkTracks;
|
||||
friend class File;
|
||||
|
||||
void setLengthInMilliseconds(int length);
|
||||
void setBitrate(int bitrate);
|
||||
void setSampleRate(int sampleRate);
|
||||
void setChannels(int channels);
|
||||
void setBitsPerSample(int bitsPerSample);
|
||||
void setDocType(const String &docType);
|
||||
void setDocTypeVersion(int docTypeVersion);
|
||||
void setCodecName(const String &codecName);
|
||||
void setTitle(const String &title);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user