簡體   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