Получение метаданных для видео MOV

У меня есть видео .MOV, отправленное приложением для обмена сообщениями на телефоне. Могу ли я получить реальные данные о создании файла и авторе? Я пробовал с ffprobe, mediainfo и подобными инструментами, но дал мне только дату, когда я его загрузил.


person Manuel Castro    schedule 25.01.2014    source источник
comment
Готовы ли вы копаться в двоичном файле программно? Если да, то на каком языке? Не уверен в инструменте, который это сделает, так как вы уже пробовали обычные подозреваемые.   -  person Multimedia Mike    schedule 26.01.2014
comment
Я не пробовал это делать. Не могли бы вы объяснить мне, как я могу?   -  person Manuel Castro    schedule 26.01.2014
comment
Нет необходимости в каком-то скрипте pythoh, вы можете напрямую извлечь его с помощью exiftools: exiftool -time:all vid.mov   -  person jeanggi90    schedule 05.02.2021


Ответы (4)


Я написал быстрый скрипт Python 2, который может получить временные метки создания и модификации, поскольку их легко найти. Найти автора немного сложнее, потому что его можно сохранить несколькими способами. Пример использования:

$ ./mov-timestamps.py file.mov
creation date: 2013-03-29 16:14:01
modification date: 2013-03-29 16:14:13

Иногда можно увидеть дату 01.01.1904. Это означает, что отметка времени равна 0. Если вы видите дату 01.01.1970, файл, вероятно, был сгенерирован FFmpeg, который не хранит эти метаданные из соображений безопасности.

#!/usr/bin/python

import datetime
import struct
import sys

ATOM_HEADER_SIZE = 8
# difference between Unix epoch and QuickTime epoch, in seconds
EPOCH_ADJUSTER = 2082844800

if len(sys.argv) < 2:
    print "USAGE: mov-length.py <file.mov>"
    sys.exit(1)

# open file and search for moov item
f = open(sys.argv[1], "rb")
while 1:
    atom_header = f.read(ATOM_HEADER_SIZE)
    if atom_header[4:8] == 'moov':
        break
    else:
        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] == 'cmov':
    print "moov atom is compressed"
elif atom_header[4:8] != 'mvhd':
    print "expected to find 'mvhd' header"
else:
    f.seek(4, 1)
    creation_date = struct.unpack(">I", f.read(4))[0]
    modification_date = struct.unpack(">I", f.read(4))[0]
    print "creation date:",
    print datetime.datetime.utcfromtimestamp(creation_date - EPOCH_ADJUSTER)
    print "modification date:",
    print datetime.datetime.utcfromtimestamp(modification_date - EPOCH_ADJUSTER)
person Multimedia Mike    schedule 28.01.2014
comment
Спасибо за сценарий. Я запускаю его, но он дает мне дату, когда я загрузил его на компьютер. Поэтому я думаю, что метаданные были перезаписаны. - person Manuel Castro; 28.01.2014
comment
Если вы играете, вы можете расширить сценарий, чтобы он копался немного глубже в файле и находил время создания/модификации атомов trak. - person Multimedia Mike; 29.01.2014
comment
Я не знаю, как это сделать. Можете ли вы дать мне ссылку (учебник, руководство)? - person Manuel Castro; 29.01.2014
comment
create_date становится равным 0 при запуске скрипта. Я искал двоичный код и не нашел moov. Так что не верьте, что этот скрипт сработает. Но спасибо за попытку помочь мне. - person Norfeldt; 30.01.2014
comment
@Norfeldt Файл QuickTime / MP4 обязательно должен иметь элементы «moov» и «mdat». Если какой-либо из них отсутствует, это недействительный файл. - person Multimedia Mike; 30.01.2014
comment
@MultimediaMike Я сделал ошибку, просто открыв его с помощью блокнота ++ и выполнив поиск moov, а затем закрыв его. Явно не правильный способ сделать это. - person Norfeldt; 31.01.2014
comment
Истинный. Используйте программу, называемую шестнадцатеричным просмотрщиком или шестнадцатеричным редактором. - person Multimedia Mike; 31.01.2014
comment
@MultimediaMike Я попробовал это, и это сработало для моих файлов mov, но для файла mp4 указано, что дата создания - 1946 год. Должно быть 2012. Я делаю что-то не так? Мой файл находится здесь: dropbox.com /s/6abygjx0dikiqf4/2012-04-16%2020.44.38.mp4?dl=0 - person b-ryce; 20.09.2014
comment
@MultimediaMike, ваш скрипт отлично работает для видео, снятых с помощью GoPro, но я пробую его с видео .mov с iPhone, и похоже, что даты хранятся в часовом поясе UTC. Это выглядит странно, потому что, когда я смотрю на живую фотографию яблока (изображение + небольшое видео), я вижу дату для фотографии, хранящуюся в местном времени, но дата для фильма хранится в формате UTC. Подумал, может быть, Apple хранит дату в местном часовом поясе где-то еще (не в mvhd)? - person Serafim Suhenky; 28.08.2016

Итак, я обновил код MMM до Python3 и кое-что улучшил.

def get_mov_timestamps(filename):
    ''' Get the creation and modification date-time from .mov metadata.

        Returns None if a value is not available.
    '''
    from datetime import datetime as DateTime
    import struct

    ATOM_HEADER_SIZE = 8
    # difference between Unix epoch and QuickTime epoch, in seconds
    EPOCH_ADJUSTER = 2082844800

    creation_time = modification_time = None

    # search for moov item
    with open(filename, "rb") as f:
        while True:
            atom_header = f.read(ATOM_HEADER_SIZE)
            #~ print('atom header:', atom_header)  # debug purposes
            if atom_header[4:8] == b'moov':
                break  # found
            else:
                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 RuntimeError('moov atom is compressed')
        elif atom_header[4:8] != b'mvhd':
            raise RuntimeError('expected to find "mvhd" header.')
        else:
            f.seek(4, 1)
            creation_time = struct.unpack('>I', f.read(4))[0] - EPOCH_ADJUSTER
            creation_time = DateTime.fromtimestamp(creation_time)
            if creation_time.year < 1990:  # invalid or censored data
                creation_time = None

            modification_time = struct.unpack('>I', f.read(4))[0] - EPOCH_ADJUSTER
            modification_time = DateTime.fromtimestamp(modification_time)
            if modification_time.year < 1990:  # invalid or censored data
                modification_time = None

    return creation_time, modification_time

а также...

Разве вы не знаете, как только я закончил, я нашел, как это сделать с помощью exiftool, который я использую для аналогичных задач с файлами .jpg. :-/

⏵ exiftool -time:all img_3904.mov
person Gringo Suave    schedule 14.02.2019

Вот версия, которая не является чистым python, но вместо этого требует libmediainfo, которая является частью инструмента mediainfo.

import pymediainfo
import sys

media_info = pymediainfo.MediaInfo.parse(sys.argv[1])

#For the first track - otherwise iterate over each track
print(' Encoded date {}'.format(track[0].encoded_date))
print(' Tagged date {}'.format(track[0].tagged_date))
person Lars Nordin    schedule 26.04.2020

Пробовали ли вы использовать hachoir? Установите его с помощью pip install hachoir, а затем в командной строке:

$ hachoir-metadata IMG_9395.MOV

который возвращает, например.

Metadata:
- Duration: 2 sec 220 ms
- Image width: 1440 pixels
- Image height: 1080 pixels
- Creation date: 2020-04-15 20:22:57
- Last modification: 2020-04-15 20:22:58
- Comment: Play speed: 100.0%
- Comment: User volume: 100.0%
- MIME type: video/quicktime
- Endianness: Big endian

Вы также можете использовать его в Python, если хотите:

from hachoir.parser import createParser
from hachoir.metadata import extractMetadata


def creation_date(filename):
    parser = createParser(filename)
    metadata = extractMetadata(parser)
    return metadata.get('creation_date')
person Marc Wouts    schedule 11.05.2020