首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何批量修改MP4视频文件上的时间戳元数据

如何批量修改MP4视频文件上的时间戳元数据
EN

Stack Overflow用户
提问于 2012-12-23 15:28:08
回答 2查看 3.3K关注 0票数 3

我最近发现,我的一台相机的内部时钟设置得比实际日期/时间晚了近两年,这打乱了我的图书馆时间轴中照片和视频的顺序。我很快就发现了exiftooldate/time shift feature出色的批量更新功能,但不幸的是,它还不支持修改MP4视频文件:

代码语言:javascript
运行
复制
$ exiftool -AllDates+="0:0:729 3:17:0" test.mp4
Error: Writing of MP4 files is not yet supported - test.mp4
    0 image files updated
    1 files weren't updated due to errors

如何对MP4视频文件执行类似的批量日期转换功能?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-23 15:28:08

QuickTime File Format Specification的基础上,我整理了一个概念验证Python脚本,用于粗略地移动时间戳,以暂时解决这个问题:

代码语言:javascript
运行
复制
#!/usr/bin/env python
import datetime
import sys

def int_bytes(raw):
    value = 0
    for byte in raw:
        value <<= 8
        value += ord(byte)
    return value

def bytes_int(value, size=4):
    raw = []
    for byte in range(size):
        raw.append(chr((value >> 8*byte) % 256))
    return ''.join(reversed(raw))


ATOM_FORMAT = (
    ('atom_size', 4, int_bytes),
    ('type', 4, str),
    ('version', 1, int_bytes),
    ('flags', 3, int_bytes),
    ('creation_time', 4, int_bytes),
    ('modification_time', 4, int_bytes),
    # that's all I need for now, and is common
    # between tkhd, mvhd and mdhd
    # ...
)

ATOM_TYPES = ('tkhd', 'mvhd', 'mdhd')

TIMESTAMP_EPOCH = datetime.datetime(1904, 1, 1, 0, 0)

def from_timestamp(timestamp):
    return TIMESTAMP_EPOCH + datetime.timedelta(0, timestamp)

def to_timestamp(datetime_obj):
    return int((datetime_obj - TIMESTAMP_EPOCH).total_seconds())

def shift_dates(mp4, atom_type, delta):
    # TODO: refactor
    mp4.seek(0)
    data = mp4.read() # TODO: don't load whole file
    type_index = -1
    while True:
        try:
            type_index = data.index(atom_type, type_index+1)
        except ValueError:
            if type_index < 0:
                raise RuntimeError('Cannot find atom: {}'.format(atom_type))
            else:
                break
        else:
            sys.stdout.write(
                '  Found {} at {}\n'.format(atom_type, type_index))
        offset = type_index - ATOM_FORMAT[0][1]

        header_data = {}
        offsets = {}
        for field, size, convert in ATOM_FORMAT:
            offsets[field] = offset
            offset += size
            header_data[field] = convert(data[offsets[field]:][:size])

        for field in ('creation_time', 'modification_time'):
            original = from_timestamp(header_data[field])
            shifted = original + delta
            mp4.seek(offsets[field])
            mp4.write(bytes_int(to_timestamp(shifted)))
            sys.stdout.write(
                '    {}: {} -> {}\n'.format(field, original, shifted))


if __name__ == '__main__':
    try:
        filename = sys.argv[1]
        days, seconds = map(int, sys.argv[2:])
    except (IndexError, TypeError, ValueError):
        sys.stderr.write(
            "USAGE: {} mp4_file days seconds\n".format(
                sys.argv[0]
            )
        )
        sys.exit(1)

    try:
        f = open(filename, 'rwb+')
    except IOError:
        sys.stderr.write("ERROR: cannot open {}\n".format(filename))
        sys.exit(1)
    else:
        delta = datetime.timedelta(days, seconds)
        sys.stdout.write(
            'Shifting timestamps of {} by {!r}:\n'.format(filename, delta))
        for atom_type in ATOM_TYPES:
            shift_dates(f, atom_type, delta)
        f.close()
        sys.stdout.write('Done.\n')
票数 1
EN

Stack Overflow用户

发布于 2019-12-14 04:10:38

ExifTool现在可以编辑MP4/MOV视频文件中的时间戳和许多其他标签。但是,由于AllDates标签仅编辑三个特定标签,其中两个标签不经常出现在视频文件中,因此上述命令可能只会编辑视频文件中的一个标签(请参阅关于Shortcut Tag Names page上的AllDates的说明)。

要编辑所有与时间相关的标记,可以使用以下命令:

exiftool -Time:All+="0:0:729 3:17:0" test.mp4

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14009389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档