如何用Python获取MP4/M4A文件的「媒体创建时间」并同步为最后修改时间?(无法读取Windows显示的媒体创建时间问题排查)
如何用Python获取MP4/M4A文件的「媒体创建时间」并同步为最后修改时间?(无法读取Windows显示的媒体创建时间问题排查)
我完全懂你遇到的困扰——Windows右键查看文件属性时明明能看到正确的「媒体创建时间」,但用Python尝试读取时却总是拿不到,而且你还想把这个真实的创建时间同步成文件的最后修改时间,用来修复云存储自动篡改文件修改时间的问题对吧?别着急,我来给你一步步拆解问题和完整的解决方案。
为什么Windows能看到但Python直接读不到?
Windows显示的「媒体创建时间」并不是文件系统层面的属性,而是存储在MP4/M4A文件内部的多媒体元数据标签(属于ISO基础媒体格式或QuickTime的规范)。普通的os模块只能读取文件系统的创建/修改时间,没法直接解析这些多媒体元数据,所以必须用专门处理多媒体元数据的库,比如mutagen。
完整的解决方案代码
下面的代码不仅能正确读取Windows显示的「媒体创建时间」,还会自动把这个时间同步为文件的最后修改时间,完美解决云存储修改时间的问题:
from mutagen.mp4 import MP4, M4A from datetime import datetime import os def get_mp4_media_created_date(filepath): """ 从MP4或M4A文件中提取「媒体创建时间」 Args: filepath (str): MP4/M4A文件的路径 Returns: datetime或None: 解析后的datetime对象,未找到则返回None """ file_lower = filepath.lower() try: # 根据文件类型初始化媒体对象 if file_lower.endswith(".mp4"): media = MP4(filepath) elif file_lower.endswith(".m4a"): media = M4A(filepath) else: return None # 不是目标文件类型 found_date = None # 覆盖大部分MP4/M4A文件会用到的时间标签 date_tags_to_check = ['creation_time', 'com.apple.quicktime.creationdate'] for tag in date_tags_to_check: if tag in media: values = media[tag] # 统一转成列表处理,兼容单个值或多个值的情况 if not isinstance(values, list): values = [values] for value in values: # 处理直接存储为Python datetime对象的情况 if isinstance(value, datetime): found_date = value break # 处理存储为ISO格式字符串的情况(带Z时区标识) elif isinstance(value, str): try: # 把Z替换为+00:00,适配Python的fromisoformat found_date = datetime.fromisoformat(value.replace('Z', '+00:00')) break except ValueError: continue # 格式不对就跳过 if found_date: break # 找到有效时间就停止检查其他标签 return found_date except Exception as e: print(f"处理文件{filepath}时出错:{e}") return None def set_file_last_modified_time(filepath, target_datetime): """ 将文件的最后修改时间设置为指定的datetime Args: filepath (str): 目标文件路径 target_datetime (datetime): 要设置的时间对象 """ try: # 把datetime转成时间戳(秒级),os.utime需要时间戳元组(访问时间, 修改时间) timestamp = target_datetime.timestamp() os.utime(filepath, (timestamp, timestamp)) print(f"已成功将文件最后修改时间同步为:{target_datetime}") except Exception as e: print(f"设置文件时间时出错:{e}") if __name__ == "__main__": filepath = input("请输入MP4/M4A文件的路径:") if not os.path.exists(filepath): print("错误:指定的文件不存在!") else: media_created_date = get_mp4_media_created_date(filepath) if media_created_date: print(f"提取到的媒体创建时间:{media_created_date}") set_file_last_modified_time(filepath, media_created_date) else: print("未找到有效的媒体创建时间元数据。")
代码关键部分详解
元数据标签覆盖:
代码里检查了两个最常见的时间标签:creation_time:ISO基础媒体格式的标准标签com.apple.quicktime.creationdate:苹果QuickTime格式的标签(很多MP4/M4A文件会用这个)
确保覆盖了绝大多数主流的MP4/M4A文件情况。
时间格式兼容:
处理了两种常见的时间存储格式:- 直接存储为Python datetime对象的情况
- 存储为ISO 8601格式字符串的情况(比如
2023-10-05T14:48:00Z),代码会自动把Z替换为+00:00,适配Python的fromisoformat方法。
文件时间同步:
新增的set_file_last_modified_time函数用os.utime把文件的访问时间和最后修改时间都设置为提取到的媒体创建时间,完美解决云存储修改时间的问题。
常见问题排查
- 先安装依赖库:确保你已经安装了
mutagen,如果没有,执行pip install mutagen即可。 - 特殊格式的时间标签:如果某些文件的时间标签格式比较特殊,你可以在
date_tags_to_check列表里添加更多可能的标签(比如一些自定义的厂商标签)。 - 权限问题:修改文件时间需要你对目标文件有足够的读写权限,如果报错权限不足,检查文件的权限设置。
- 无元数据的文件:少数不规范的MP4/M4A文件可能没有存储媒体创建时间的元数据,这种情况代码会提示“未找到有效的媒体创建时间元数据”。
内容来源于stack exchange
相关产品推荐
相关产品推荐

