繁体   English   中英

无法使用 Python 从视频文件中获取正确的 Exif 数据

[英]Unable to get correct Exif data from video file using Python

我找不到使用 Python 从视频文件中获取 Exif 属性“ DateEncoded ”的方法。

我尝试了几个 exif 工具,但是这个特定的 mp4 文件(使用 Android 应用程序 FilmicPro 录制)似乎是一个特例。

Windows 资源管理器在“创建日期”属性下显示正确的日期(见图),它实际上是 QuickTime exif 键“ Media_DateEncoded ”。

Windows 资源管理器上的正确日期

Adobe Media Encoder 似乎也检索到了正确的日期:

MediaEncoder 元数据面板

但是,我尝试的五种方法都不能以编程方式检索正确的日期: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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM