Adding parsing mvhd-atom to taglib.
Константин Шабаловский
shabalovskikn at gmail.com
Wed Apr 7 22:15:11 BST 2021
Ok. I have decided not to create parsing mvhd on MP4::Properties side.
<https://mail.google.com/mail/u/0?ui=2&ik=556daee67b&attid=0.1&permmsgid=msg-a:r107904676252198472&view=att&disp=safe&realattid=f_kn7y82y50>
Created the functionality at MP4::Tag side.
>From 29167ac13205445afb9abace0247ce93905e8824 Mon Sep 17 00:00:00 2001
From: Konstantin_BY <shabalovskikn at gmail.com>
Date: Wed, 7 Apr 2021 19:46:14 +0300
Subject: [PATCH] Added parsing duration and time creation from mvhd atom of
mp4 file
---
taglib/mp4/mp4item.cpp | 12 +++++++++++
taglib/mp4/mp4item.h | 2 ++
taglib/mp4/mp4tag.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++
taglib/mp4/mp4tag.h | 1 +
4 files changed, 62 insertions(+)
diff --git a/taglib/mp4/mp4item.cpp b/taglib/mp4/mp4item.cpp
index 787ed45..ff49981 100644
--- a/taglib/mp4/mp4item.cpp
+++ b/taglib/mp4/mp4item.cpp
@@ -47,6 +47,7 @@ public:
unsigned char m_byte;
unsigned int m_uint;
long long m_longlong;
+ double m_double;
};
StringList m_stringList;
ByteVectorList m_byteVectorList;
@@ -116,6 +117,11 @@ MP4::Item::Item(long long value) :
d->m_longlong = value;
}
+MP4::Item::Item(double value) :
+ d(new ItemPrivate())
+{
+ d->m_double = value;
+}
MP4::Item::Item(int value1, int value2) :
d(new ItemPrivate())
{
@@ -181,6 +187,12 @@ MP4::Item::toLongLong() const
return d->m_longlong;
}
+double
+MP4::Item::toDouble() const
+{
+ return d->m_double;
+}
+
MP4::Item::IntPair
MP4::Item::toIntPair() const
{
diff --git a/taglib/mp4/mp4item.h b/taglib/mp4/mp4item.h
index 3821135..fd135b8 100644
--- a/taglib/mp4/mp4item.h
+++ b/taglib/mp4/mp4item.h
@@ -65,6 +65,7 @@ namespace TagLib {
Item(const StringList &value);
Item(const ByteVectorList &value);
Item(const CoverArtList &value);
+ Item(double value);
void setAtomDataType(AtomDataType type);
AtomDataType atomDataType() const;
@@ -74,6 +75,7 @@ namespace TagLib {
unsigned int toUInt() const;
long long toLongLong() const;
bool toBool() const;
+ double toDouble() const;
IntPair toIntPair() const;
StringList toStringList() const;
ByteVectorList toByteVectorList() const;
diff --git a/taglib/mp4/mp4tag.cpp b/taglib/mp4/mp4tag.cpp
index a8e2e7d..cbb6136 100644
--- a/taglib/mp4/mp4tag.cpp
+++ b/taglib/mp4/mp4tag.cpp
@@ -30,6 +30,13 @@
#include "mp4tag.h"
#include "id3v1genres.h"
+/* For converting qt creation times to unix epoch times */
+#define QTDEMUX_SECONDS_PER_DAY (60 * 60 * 24)
+#define QTDEMUX_LEAP_YEARS_FROM_1904_TO_1970 17
+#define QTDEMUX_SECONDS_FROM_1904_TO_1970 (((1970 - 1904) * (uint64_t) 365
+ \
+ QTDEMUX_LEAP_YEARS_FROM_1904_TO_1970) * QTDEMUX_SECONDS_PER_DAY)
+
+
using namespace TagLib;
class MP4::Tag::TagPrivate
@@ -97,6 +104,11 @@ MP4::Tag::Tag(TagLib::File *file, MP4::Atoms *atoms) :
parseText(atom);
}
}
+ MP4::Atom *mvhd = atoms->find("moov","mvhd");
+ if(mvhd) {
+ parseMvhd(mvhd);
+ }
+
}
MP4::Tag::~Tag()
@@ -313,6 +325,40 @@ MP4::Tag::parseCovr(const MP4::Atom *atom)
addItem(atom->name, value);
}
+void
+MP4::Tag::parseMvhd(const MP4::Atom *atom)
+{
+ d->file->seek(atom->offset);
+ ByteVector dataMvhd = d->file->readBlock(atom->length);
+ const unsigned int version = dataMvhd[8];
+
+ long long timeCreation;
+ long long duration;
+ long long timescale;
+
+ if(version == 1) {
+ timeCreation = dataMvhd.toLongLong(12U);
+ timescale = dataMvhd.toUInt(28U);
+ duration = dataMvhd.toLongLong(32U);
+ }
+ else {
+ timeCreation = dataMvhd.toUInt(12U);
+ timescale = dataMvhd.toUInt(20U);
+ duration = dataMvhd.toUInt(24U);
+ }
+
+ if (timeCreation != 0) {
+ if ((uint64_t)timeCreation >= QTDEMUX_SECONDS_FROM_1904_TO_1970) {
+ timeCreation -= QTDEMUX_SECONDS_FROM_1904_TO_1970;
+ }
+ // ADD time here
+ addItem("crdt", timeCreation);
+ }
+
+ addItem("durt", duration/static_cast<double>(timescale) );
+
+}
+
ByteVector
MP4::Tag::padIlst(const ByteVector &data, int length) const
{
@@ -869,6 +915,7 @@ namespace
{ "----:com.apple.iTunes:LANGUAGE", "LANGUAGE" },
{ "----:com.apple.iTunes:LICENSE", "LICENSE" },
{ "----:com.apple.iTunes:MEDIA", "MEDIA" },
+ { "crdt", "CREATION_DATE" },
};
const size_t keyTranslationSize = sizeof(keyTranslation) /
sizeof(keyTranslation[0]);
diff --git a/taglib/mp4/mp4tag.h b/taglib/mp4/mp4tag.h
index d477a86..54e9989 100644
--- a/taglib/mp4/mp4tag.h
+++ b/taglib/mp4/mp4tag.h
@@ -121,6 +121,7 @@ namespace TagLib {
void parseIntPair(const Atom *atom);
void parseBool(const Atom *atom);
void parseCovr(const Atom *atom);
+ void parseMvhd(const MP4::Atom *atom);
ByteVector padIlst(const ByteVector &data, int length = -1) const;
ByteVector renderAtom(const ByteVector &name, const ByteVector
&data) const;
вт, 6 апр. 2021 г. в 20:16, Константин Шабаловский <shabalovskikn at gmail.com
>:
> Hi there.
>
> I use your project to get preview from an mp4 file. (Only mp4)
> And I would like to have functions to extract some other data like:
> - duration
> - time creation
> Is it ok if I add the possibility(parsing mvhd) to the project? I can add
> it to the function
> void
> MP4::Properties::read(File *file, Atoms *atoms)
> I think to use adapted code from
> gstreamer1.0-plugins-good git/gst/isomp4/qtdemux.c
> Best regards
> Kanstantin Shabalovsky
>
> --
> Best regards. Konstantin.
>
--
Best regards. Konstantin.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.kde.org/pipermail/taglib-devel/attachments/20210408/f14c5f3e/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Added-parsing-duration-and-time-creation-from-mvhd-a.patch
Type: text/x-patch
Size: 4694 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/taglib-devel/attachments/20210408/f14c5f3e/attachment.bin>
More information about the taglib-devel
mailing list