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