Skip to content

Instantly share code, notes, and snippets.

@lclibardi
Last active April 8, 2023 11:30
Show Gist options
  • Save lclibardi/382292b2ddd786159dfa16d93955eea1 to your computer and use it in GitHub Desktop.
Save lclibardi/382292b2ddd786159dfa16d93955eea1 to your computer and use it in GitHub Desktop.
Get Quicktime Media DateEncoded Exif data
'''
These are 5 different methods that attempt to retrieve the Quicktime property metadata "Media DateEncoded" from an 'mp4' file.
'''
import os
import re
import struct
import subprocess as sub
from datetime import datetime
from hachoir.parser import createParser
from hachoir.metadata import extractMetadata
from win32com.propsys import propsys, pscon
# Download ExifTool from https://exiftool.org/
EXIF_TOOL = "exiftool.exe"
def method_1(fpath):
# On Windows ctime means "Creation time", on Linux "Changed time"
ctime = os.path.getctime(fpath)
dtime = datetime.fromtimestamp(ctime)
return dtime.strftime("%Y:%m:%d %H:%M:%S")
def method_2(fpath):
'''
Requires Hachoir installed. For Python3 run:
>> pip3 install hachoir==3.1.1
>> pip3 install hachoir-parser
The property key 'Creation date' is a filesystem metadata, but
it was the only one returned by Hachoir. What I really need is
the Quicktime key 'Media_DateEncoded', which Windows Explorer
calls "Media Created"
'''
parser = createParser(fpath)
with parser:
metadata = extractMetadata(parser)
exif_dict = metadata.exportDictionary()['Metadata']
return exif_dict['Creation date']
def method_3(fpath):
'''
Runs this shell comand:
>> exiftool.exe -h VID_20190106_162804.mp4
...which returns an HTML like string from stdout.
So using regular expression, we look for this section:
"Media Create Date</td><td>2019:01:07 00:28:08</td></tr>"
'''
p = sub.Popen(
[EXIF_TOOL, '-h',fpath],
stdout=sub.PIPE,
encoding='utf8')
res, err = p.communicate()
pattern = re.compile(
r'Media Create Date\</td\>\<td\>(\d{4}:\d{2}:\d{2}\s\d{2}:\d{2}:\d{2})'
)
match = re.findall(pattern, res)
if match:
return match[0]
def method_4(fpath):
'''
Here we look for the Quicktime property key: Media_DateEncoded, which
Windows Explorer calls "Media Created"
'''
fpath = fpath.replace('/', '\\') # Windows api does not work with posix paths
properties = propsys.SHGetPropertyStoreFromParsingName(fpath)
dtime = properties.GetValue(pscon.PKEY_Media_DateEncoded).GetValue()
return dtime.strftime("%Y:%m:%d %H:%M:%S")
def method_5(fpath):
ATOM_HEADER_SIZE = 8
# Difference between Unix epoch and QuickTime epoch, in seconds
EPOCH_ADJUSTER = 2082844800
# open file and search for moov item
f = open(fpath, "rb")
while 1:
atom_header = f.read(ATOM_HEADER_SIZE)
if atom_header[4:8] == b'moov':
break
atom_size = struct.unpack(">I", atom_header[0:4])[0]
f.seek(atom_size - 8, 1)
# found 'moov', look for 'mvhd' and timestamps
atom_header = f.read(ATOM_HEADER_SIZE)
if atom_header[4:8] == b'cmov':
raise Exception("moov atom is compressed")
elif atom_header[4:8] != b'mvhd':
raise Exception("expected to find 'mvhd' header")
else:
f.seek(4, 1)
creation_date = struct.unpack(">I", f.read(4))[0]
dtime = datetime.utcfromtimestamp(creation_date - EPOCH_ADJUSTER)
return dtime.strftime("%Y:%m:%d %H:%M:%S")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment