<div dir="ltr"><a class="gmail-dO" id="gmail-:9lr" href="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" target="_blank"><div class="gmail-vI"><span style="color:rgb(34,34,34)">Ok. I have decided not to create parsing mvhd on MP4::Properties side. </span></div></a><div class="gmail_default" style="font-size:small">Created the functionality at MP4::Tag side.</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">From 29167ac13205445afb9abace0247ce93905e8824 Mon Sep 17 00:00:00 2001<br>From: Konstantin_BY <<a href="mailto:shabalovskikn@gmail.com">shabalovskikn@gmail.com</a>><br>Date: Wed, 7 Apr 2021 19:46:14 +0300<br>Subject: [PATCH] Added parsing duration and time creation from mvhd atom of<br> mp4 file<br><br>---<br> taglib/mp4/mp4item.cpp | 12 +++++++++++<br> taglib/mp4/mp4item.h | 2 ++<br> taglib/mp4/mp4tag.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++<br> taglib/mp4/mp4tag.h | 1 +<br> 4 files changed, 62 insertions(+)<br><br>diff --git a/taglib/mp4/mp4item.cpp b/taglib/mp4/mp4item.cpp<br>index 787ed45..ff49981 100644<br>--- a/taglib/mp4/mp4item.cpp<br>+++ b/taglib/mp4/mp4item.cpp<br>@@ -47,6 +47,7 @@ public:<br> unsigned char m_byte;<br> unsigned int m_uint;<br> long long m_longlong;<br>+ double m_double;<br> };<br> StringList m_stringList;<br> ByteVectorList m_byteVectorList;<br>@@ -116,6 +117,11 @@ MP4::Item::Item(long long value) :<br> d->m_longlong = value;<br> }<br> <br>+MP4::Item::Item(double value) :<br>+ d(new ItemPrivate())<br>+{<br>+ d->m_double = value;<br>+}<br> MP4::Item::Item(int value1, int value2) :<br> d(new ItemPrivate())<br> {<br>@@ -181,6 +187,12 @@ MP4::Item::toLongLong() const<br> return d->m_longlong;<br> }<br> <br>+double<br>+MP4::Item::toDouble() const<br>+{<br>+ return d->m_double;<br>+}<br>+<br> MP4::Item::IntPair<br> MP4::Item::toIntPair() const<br> {<br>diff --git a/taglib/mp4/mp4item.h b/taglib/mp4/mp4item.h<br>index 3821135..fd135b8 100644<br>--- a/taglib/mp4/mp4item.h<br>+++ b/taglib/mp4/mp4item.h<br>@@ -65,6 +65,7 @@ namespace TagLib {<br> Item(const StringList &value);<br> Item(const ByteVectorList &value);<br> Item(const CoverArtList &value);<br>+ Item(double value);<br> <br> void setAtomDataType(AtomDataType type);<br> AtomDataType atomDataType() const;<br>@@ -74,6 +75,7 @@ namespace TagLib {<br> unsigned int toUInt() const;<br> long long toLongLong() const;<br> bool toBool() const;<br>+ double toDouble() const;<br> IntPair toIntPair() const;<br> StringList toStringList() const;<br> ByteVectorList toByteVectorList() const;<br>diff --git a/taglib/mp4/mp4tag.cpp b/taglib/mp4/mp4tag.cpp<br>index a8e2e7d..cbb6136 100644<br>--- a/taglib/mp4/mp4tag.cpp<br>+++ b/taglib/mp4/mp4tag.cpp<br>@@ -30,6 +30,13 @@<br> #include "mp4tag.h"<br> #include "id3v1genres.h"<br> <br>+/* For converting qt creation times to unix epoch times */<br>+#define QTDEMUX_SECONDS_PER_DAY (60 * 60 * 24)<br>+#define QTDEMUX_LEAP_YEARS_FROM_1904_TO_1970 17<br>+#define QTDEMUX_SECONDS_FROM_1904_TO_1970 (((1970 - 1904) * (uint64_t) 365 + \<br>+ QTDEMUX_LEAP_YEARS_FROM_1904_TO_1970) * QTDEMUX_SECONDS_PER_DAY)<br>+<br>+<br> using namespace TagLib;<br> <br> class MP4::Tag::TagPrivate<br>@@ -97,6 +104,11 @@ MP4::Tag::Tag(TagLib::File *file, MP4::Atoms *atoms) :<br> parseText(atom);<br> }<br> }<br>+ MP4::Atom *mvhd = atoms->find("moov","mvhd");<br>+ if(mvhd) {<br>+ parseMvhd(mvhd);<br>+ }<br>+<br> }<br> <br> MP4::Tag::~Tag()<br>@@ -313,6 +325,40 @@ MP4::Tag::parseCovr(const MP4::Atom *atom)<br> addItem(atom->name, value);<br> }<br> <br>+void<br>+MP4::Tag::parseMvhd(const MP4::Atom *atom)<br>+{<br>+ d->file->seek(atom->offset);<br>+ ByteVector dataMvhd = d->file->readBlock(atom->length);<br>+ const unsigned int version = dataMvhd[8];<br>+<br>+ long long timeCreation;<br>+ long long duration;<br>+ long long timescale;<br>+<br>+ if(version == 1) {<br>+ timeCreation = dataMvhd.toLongLong(12U);<br>+ timescale = dataMvhd.toUInt(28U); <br>+ duration = dataMvhd.toLongLong(32U); <br>+ } <br>+ else {<br>+ timeCreation = dataMvhd.toUInt(12U); <br>+ timescale = dataMvhd.toUInt(20U); <br>+ duration = dataMvhd.toUInt(24U); <br>+ }<br>+<br>+ if (timeCreation != 0) {<br>+ if ((uint64_t)timeCreation >= QTDEMUX_SECONDS_FROM_1904_TO_1970) {<br>+ timeCreation -= QTDEMUX_SECONDS_FROM_1904_TO_1970;<br>+ }<br>+ // ADD time here<br>+ addItem("crdt", timeCreation);<br>+ }<br>+ <br>+ addItem("durt", duration/static_cast<double>(timescale) );<br>+<br>+}<br>+<br> ByteVector<br> MP4::Tag::padIlst(const ByteVector &data, int length) const<br> {<br>@@ -869,6 +915,7 @@ namespace<br> { "----:com.apple.iTunes:LANGUAGE", "LANGUAGE" },<br> { "----:com.apple.iTunes:LICENSE", "LICENSE" },<br> { "----:com.apple.iTunes:MEDIA", "MEDIA" },<br>+ { "crdt", "CREATION_DATE" },<br> };<br> const size_t keyTranslationSize = sizeof(keyTranslation) / sizeof(keyTranslation[0]);<br> <br>diff --git a/taglib/mp4/mp4tag.h b/taglib/mp4/mp4tag.h<br>index d477a86..54e9989 100644<br>--- a/taglib/mp4/mp4tag.h<br>+++ b/taglib/mp4/mp4tag.h<br>@@ -121,6 +121,7 @@ namespace TagLib {<br> void parseIntPair(const Atom *atom);<br> void parseBool(const Atom *atom);<br> void parseCovr(const Atom *atom);<br>+ void parseMvhd(const MP4::Atom *atom);<br> <br> ByteVector padIlst(const ByteVector &data, int length = -1) const;<br> ByteVector renderAtom(const ByteVector &name, const ByteVector &data) const;<br></div><div class="gmail_default" style="font-size:small"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">вт, 6 апр. 2021 г. в 20:16, Константин Шабаловский <<a href="mailto:shabalovskikn@gmail.com">shabalovskikn@gmail.com</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_default" style="font-size:small"><div style="color:rgb(51,51,51);font-family:Arial,Tahoma,Verdana,sans-serif;font-size:15px">Hi there.</div><div style="color:rgb(51,51,51);font-family:Arial,Tahoma,Verdana,sans-serif;font-size:15px"> </div><div style="color:rgb(51,51,51);font-family:Arial,Tahoma,Verdana,sans-serif;font-size:15px">I use your project to get preview from an mp4 file. (Only mp4)</div><div style="color:rgb(51,51,51);font-family:Arial,Tahoma,Verdana,sans-serif;font-size:15px">And I would like to have functions to extract some other data like:</div><div style="color:rgb(51,51,51);font-family:Arial,Tahoma,Verdana,sans-serif;font-size:15px">- duration</div><div style="color:rgb(51,51,51);font-family:Arial,Tahoma,Verdana,sans-serif;font-size:15px">- time creation</div><div style="color:rgb(51,51,51);font-family:Arial,Tahoma,Verdana,sans-serif;font-size:15px">Is it ok if I add the possibility(parsing mvhd) to the project? I can add it to the function </div><div style="color:rgb(51,51,51);font-family:Arial,Tahoma,Verdana,sans-serif;font-size:15px"><div style="background-color:rgb(30,30,30);color:rgb(212,212,212);font-family:"Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";font-size:14px;line-height:19px;white-space:pre-wrap"><div><span style="color:rgb(86,156,214)">void</span></div><div><span style="color:rgb(78,201,176)">MP4</span>::<span style="color:rgb(78,201,176)">Properties</span>::<span style="color:rgb(220,220,170)">read</span>(<span style="color:rgb(78,201,176)">File</span> *<span style="color:rgb(156,220,254)">file</span>, <span style="color:rgb(78,201,176)">Atoms</span> *<span style="color:rgb(156,220,254)">atoms</span>)</div></div>I think to use adapted code from gstreamer1.0-plugins-good git/gst/isomp4/qtdemux.c</div><div style="color:rgb(51,51,51);font-family:Arial,Tahoma,Verdana,sans-serif;font-size:15px"><div><div>Best regards<br>Kanstantin Shabalovsky</div></div></div></div><div><br></div>-- <br><div dir="ltr"><div dir="ltr">Best regards. Konstantin.</div></div></div>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr">Best regards. Konstantin.</div></div>