[英]Unable to get correct Exif data from video file using Python
我找不到使用 Python 从视频文件中获取 Exif 属性“ DateEncoded ”的方法。
我尝试了几个 exif 工具,但是这个特定的 mp4 文件(使用 Android 应用程序 FilmicPro 录制)似乎是一个特例。
Windows 资源管理器在“创建日期”属性下显示正确的日期(见图),它实际上是 QuickTime exif 键“ Media_DateEncoded ”。
Adobe Media Encoder 似乎也检索到了正确的日期:
但是,我尝试的五种方法都不能以编程方式检索正确的日期:2019 年 1 月 6 日。它总是返回 1 月 7 日!
有没有人能够解释为什么/如何?
这是代码:
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):
'''
This 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):
'''
This executes 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")
Win32 上的 Python 3.7.3 (v3.7.3:ef4ec6ed12) [MSC v.1916 64 位 (AMD64)]
操作系统:Windows 10 版本 10.0.18362 内部版本 18362
您没有考虑到的事实是 Quicktime 元数据时间戳保存为 UTC,而不是本地时间。 您需要根据您的时区调整存储的时间。 Windows 理解这一点并相应地显示更正的时间,尽管并非所有程序都这样做。
使用exiftool 提取时间戳时,可以添加-api QuickTimeUTC
选项,exiftool 会自动调整到计算机的当前时区。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.