Невозможно получить правильные данные Exif из видеофайла, используя Python - PullRequest
1 голос
/ 12 января 2020

Я не могу найти способ получить свойство Exif " DateEncoded " из видеофайла, используя Python.

Я пробовал несколько инструментов EXIF, но это указ c mp4 файл (записанный с использованием приложения Android FilmicPro) представляется особым случаем.

Windows Explorer отображает правильную дату в свойстве «Дата создания» (см. Изображение) , который на самом деле является ключом QuickTime exif " Media_DateEncoded ".

Правильная дата в Windows Explorer

Adobe Media Encoder также, похоже, возвращает правильную дату:

Панель метаданных MediaEncoder

Однако ни один из пяти методов, которые я попробовал, не может программно получить правильную дату: 6 января 2019 года. Она всегда возвращает 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")

Python 3.7.3 (v3.7.3: ef4ec6ed12) [MS C v.1916 64 бит (AMD64)] вкл win32

ОС: Windows 10 Версия 10.0.18362 Сборка 18362

1 Ответ

0 голосов
/ 12 января 2020

Вы не учитываете тот факт, что метки времени QuickTime метаданных сохраняются как UT C, а не как местное время. Вам необходимо отрегулировать сохраненное время по вашему часовому поясу. Windows понимает это и отображает скорректированное время соответственно, хотя не все программы это делают.

При извлечении метки времени с помощью exiftool вы можете добавить опцию -api QuickTimeUTC , и exiftool сделает Автоматическая настройка на текущий часовой пояс компьютера.

...