2018-03-06 23:09:15 +01:00
|
|
|
#ifndef TAG_PARSER_MP4TAG_H
|
|
|
|
#define TAG_PARSER_MP4TAG_H
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2015-09-06 19:57:33 +02:00
|
|
|
#include "./mp4tagfield.h"
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2015-09-06 19:57:33 +02:00
|
|
|
#include "../fieldbasedtag.h"
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2018-03-07 01:17:50 +01:00
|
|
|
namespace TagParser {
|
2015-04-22 19:22:01 +02:00
|
|
|
|
|
|
|
class Mp4Atom;
|
2015-12-10 13:50:46 +01:00
|
|
|
class Mp4Tag;
|
|
|
|
|
2018-03-07 01:17:50 +01:00
|
|
|
struct TAG_PARSER_EXPORT Mp4ExtendedFieldId {
|
2021-01-30 21:53:06 +01:00
|
|
|
Mp4ExtendedFieldId(std::string_view mean, std::string_view name, bool updateOnly = false);
|
2016-11-14 22:59:19 +01:00
|
|
|
Mp4ExtendedFieldId(KnownField field);
|
|
|
|
|
|
|
|
operator bool() const;
|
|
|
|
bool matches(const Mp4TagField &field) const;
|
|
|
|
|
|
|
|
/// \brief mean parameter, usually Mp4TagExtendedMeanIds::iTunes
|
2021-01-30 21:53:06 +01:00
|
|
|
std::string_view mean;
|
2016-11-14 22:59:19 +01:00
|
|
|
/// \brief name parameter
|
2021-01-30 21:53:06 +01:00
|
|
|
std::string_view name;
|
2016-11-14 22:59:19 +01:00
|
|
|
/// \brief Whether only existing fields should be updated but *no* new extended field should be created
|
2021-01-30 21:53:06 +01:00
|
|
|
bool updateOnly = false;
|
2016-11-14 22:59:19 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Constructs a new instance with the specified parameter.
|
|
|
|
*/
|
2021-01-30 21:53:06 +01:00
|
|
|
inline Mp4ExtendedFieldId::Mp4ExtendedFieldId(std::string_view mean, std::string_view name, bool updateOnly)
|
2018-03-07 01:17:50 +01:00
|
|
|
: mean(mean)
|
|
|
|
, name(name)
|
|
|
|
, updateOnly(updateOnly)
|
|
|
|
{
|
|
|
|
}
|
2016-11-14 22:59:19 +01:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Returns whether valid parameter are assigned.
|
|
|
|
*/
|
|
|
|
inline Mp4ExtendedFieldId::operator bool() const
|
|
|
|
{
|
2021-01-30 21:53:06 +01:00
|
|
|
return !mean.empty() && !name.empty();
|
2016-11-14 22:59:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Returns whether the current parameter match the specified \a field.
|
|
|
|
*/
|
|
|
|
inline bool Mp4ExtendedFieldId::matches(const Mp4TagField &field) const
|
|
|
|
{
|
|
|
|
return field.mean() == mean && field.name() == name;
|
|
|
|
}
|
|
|
|
|
2018-03-07 01:17:50 +01:00
|
|
|
class TAG_PARSER_EXPORT Mp4TagMaker {
|
2015-12-10 13:50:46 +01:00
|
|
|
friend class Mp4Tag;
|
|
|
|
|
|
|
|
public:
|
2018-03-05 17:49:29 +01:00
|
|
|
void make(std::ostream &stream, Diagnostics &diag);
|
2015-12-10 13:50:46 +01:00
|
|
|
const Mp4Tag &tag() const;
|
2019-03-13 19:06:42 +01:00
|
|
|
std::uint64_t requiredSize() const;
|
2015-12-10 13:50:46 +01:00
|
|
|
|
|
|
|
private:
|
2018-03-05 17:49:29 +01:00
|
|
|
Mp4TagMaker(Mp4Tag &tag, Diagnostics &diag);
|
2015-12-10 13:50:46 +01:00
|
|
|
|
|
|
|
Mp4Tag &m_tag;
|
2015-12-22 23:54:35 +01:00
|
|
|
std::vector<Mp4TagFieldMaker> m_maker;
|
2019-03-13 19:06:42 +01:00
|
|
|
std::uint64_t m_metaSize;
|
|
|
|
std::uint64_t m_ilstSize;
|
2015-12-10 13:50:46 +01:00
|
|
|
bool m_omitPreDefinedGenre;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Returns the associated tag.
|
|
|
|
*/
|
|
|
|
inline const Mp4Tag &Mp4TagMaker::tag() const
|
|
|
|
{
|
|
|
|
return m_tag;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Returns the number of bytes which will be written when making the tag.
|
|
|
|
*/
|
2019-03-13 19:06:42 +01:00
|
|
|
inline std::uint64_t Mp4TagMaker::requiredSize() const
|
2015-12-10 13:50:46 +01:00
|
|
|
{
|
|
|
|
return m_metaSize;
|
|
|
|
}
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2017-03-07 00:02:59 +01:00
|
|
|
/*!
|
|
|
|
* \brief Defines traits for the TagField implementation of the Mp4Tag class.
|
|
|
|
*/
|
2018-03-07 01:17:50 +01:00
|
|
|
template <> class TAG_PARSER_EXPORT FieldMapBasedTagTraits<Mp4Tag> {
|
2017-03-07 00:02:59 +01:00
|
|
|
public:
|
2018-07-11 13:19:43 +02:00
|
|
|
using FieldType = Mp4TagField;
|
|
|
|
using Compare = std::less<typename FieldType::IdentifierType>;
|
2017-03-07 00:02:59 +01:00
|
|
|
};
|
|
|
|
|
2020-12-18 21:13:52 +01:00
|
|
|
class TAG_PARSER_EXPORT Mp4Tag final : public FieldMapBasedTag<Mp4Tag> {
|
2017-03-07 01:52:26 +01:00
|
|
|
friend class FieldMapBasedTag<Mp4Tag>;
|
|
|
|
|
2015-04-22 19:22:01 +02:00
|
|
|
public:
|
|
|
|
Mp4Tag();
|
|
|
|
|
2017-01-23 00:25:53 +01:00
|
|
|
static constexpr TagType tagType = TagType::Mp4Tag;
|
2021-01-30 21:53:06 +01:00
|
|
|
static constexpr std::string_view tagName = "MP4/iTunes tag";
|
2017-03-07 00:02:59 +01:00
|
|
|
static constexpr TagTextEncoding defaultTextEncoding = TagTextEncoding::Utf8;
|
2018-03-07 01:11:42 +01:00
|
|
|
bool canEncodingBeUsed(TagTextEncoding encoding) const override;
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2018-03-07 01:11:42 +01:00
|
|
|
bool supportsField(KnownField field) const override;
|
2017-03-07 00:02:59 +01:00
|
|
|
using FieldMapBasedTag<Mp4Tag>::value;
|
2018-03-07 01:11:42 +01:00
|
|
|
const TagValue &value(KnownField value) const override;
|
2017-03-07 00:02:59 +01:00
|
|
|
using FieldMapBasedTag<Mp4Tag>::values;
|
2018-03-07 01:11:42 +01:00
|
|
|
std::vector<const TagValue *> values(KnownField field) const override;
|
2021-01-30 21:53:06 +01:00
|
|
|
const TagValue &value(std::string_view mean, std::string_view name) const;
|
2017-03-07 00:02:59 +01:00
|
|
|
using FieldMapBasedTag<Mp4Tag>::setValue;
|
2018-03-07 01:11:42 +01:00
|
|
|
bool setValue(KnownField field, const TagValue &value) override;
|
2017-03-07 00:02:59 +01:00
|
|
|
using FieldMapBasedTag<Mp4Tag>::setValues;
|
2018-03-07 01:11:42 +01:00
|
|
|
bool setValues(KnownField field, const std::vector<TagValue> &values) override;
|
2021-01-30 21:53:06 +01:00
|
|
|
bool setValue(std::string_view mean, std::string_view name, const TagValue &value);
|
2017-03-07 00:02:59 +01:00
|
|
|
using FieldMapBasedTag<Mp4Tag>::hasField;
|
2018-03-07 01:11:42 +01:00
|
|
|
bool hasField(KnownField value) const override;
|
2018-07-13 12:25:00 +02:00
|
|
|
bool supportsMultipleValues(KnownField) const override;
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2018-03-05 17:49:29 +01:00
|
|
|
void parse(Mp4Atom &metaAtom, Diagnostics &diag);
|
|
|
|
Mp4TagMaker prepareMaking(Diagnostics &diag);
|
|
|
|
void make(std::ostream &stream, Diagnostics &diag);
|
2017-03-07 01:52:26 +01:00
|
|
|
|
|
|
|
protected:
|
2017-03-07 17:16:17 +01:00
|
|
|
IdentifierType internallyGetFieldId(KnownField field) const;
|
|
|
|
KnownField internallyGetKnownField(const IdentifierType &id) const;
|
2021-01-30 19:18:29 +01:00
|
|
|
void internallyGetValuesFromField(const FieldType &field, std::vector<const TagValue *> &values) const;
|
2015-04-22 19:22:01 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Constructs a new tag.
|
|
|
|
*/
|
|
|
|
inline Mp4Tag::Mp4Tag()
|
2018-03-07 01:17:50 +01:00
|
|
|
{
|
|
|
|
}
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2016-11-19 22:03:47 +01:00
|
|
|
inline bool Mp4Tag::supportsField(KnownField field) const
|
|
|
|
{
|
2018-03-07 01:17:50 +01:00
|
|
|
switch (field) {
|
2016-11-19 22:03:47 +01:00
|
|
|
case KnownField::EncoderSettings:
|
|
|
|
return true;
|
|
|
|
default:
|
2017-03-07 00:02:59 +01:00
|
|
|
return FieldMapBasedTag<Mp4Tag>::supportsField(field);
|
2016-11-19 22:03:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-13 12:25:00 +02:00
|
|
|
/*!
|
|
|
|
* \brief Returns false for all fields (for now).
|
|
|
|
* \remarks Not sure whether iTunes-style MP4 tags allow this. Let's return false for now.
|
|
|
|
* \todo Do some research whether it is supported or not.
|
|
|
|
*/
|
|
|
|
inline bool Mp4Tag::supportsMultipleValues(KnownField) const
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-03-07 01:17:50 +01:00
|
|
|
} // namespace TagParser
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2018-03-06 23:09:15 +01:00
|
|
|
#endif // TAG_PARSER_MP4TAG_H
|