supplemental-metadata.json 是什么?Takeout 文件名截断和 (1) 详解
Google 在 2024 年改了 Takeout 附属文件的名字,有些名字被截断,重复照片的 (1) 位置也变了。为什么旧脚本会漏掉这些文件。
你跑了一个以前修 Takeout 导出一直好用的脚本,这次却跳过了一半的照片。或者你翻看文件夹,看到一张照片旁边是 IMG_5512.HEIC.supplemental-metadata.json,另一张旁边却是 PXL_20240311_183022711.jpg.supplemental-m.json,不知道第二个是不是坏了。
都没坏。是 Google 改了附属文件的命名方式,而 2024 年之前写的大多数教程不知道这件事。
2024 年的改名
多年以来,IMG_5512.HEIC 的附属文件一直叫 IMG_5512.HEIC.json。照片名,加 .json,简单,所有脚本都按这个匹配。
2024 年的某个时候,Google 换成了 IMG_5512.HEIC.supplemental-metadata.json。内容一样,字段一样,名字更长。用意大概是让 supplemental-metadata(补充元数据)说明这个文件是什么,而不是留一个光秃秃的 .json,看起来像照片自己的数据。此后的导出都用新名字。如果你硬盘上有旧的导出,用的是旧名字,混在一起的文件夹里两种都有。
凡是按 <照片名>.json 找文件的工具,现在什么也找不到,然后就跳过去了。有的工具会对每个文件报「找不到附属文件」。有的则悄悄退回去用文件时间,也就是下载时间,于是照片日期全错,却没有任何报错。这种无声的失败,是网上很多「修了但没用」帖子的根源。
46 个字符的截断
第二个变化更早就有,但改名之后影响变大了。Google 会把整个附属文件名截断到 46 个字符。以前后缀短,很少碰到。加上 .supplemental-metadata.json 之后,照片名超过 19 个字符左右,后缀就会被切掉一截。
Pixel 手机的照片 PXL_20240311_183022711.jpg 有 26 个字符。加上 .supplemental-metadata.json 是 53 个。Google 切到 46 个:PXL_20240311_183022711.jpg.supplemental-m.json。三星的 20240311_183022.jpg 得到 20240311_183022.jpg.supplemental-metada.json。每个品牌的相机切出来的位置都略有不同,所以没有一个统一的后缀可以匹配。
可靠的规则是:附属文件名是 <照片名>.supplemental-metadata.json 的前缀。脚本得按这个规则检查,而不是比对一个固定字符串。很长的原始文件名,比如你自己打的名字,可能连照片名本身都被切掉一段,这也是为什么附属文件里的 title 字段值得读一下。
(1) 放在哪
Google 相册允许两个文件同名,而 Takeout 必须把它们放进同一个文件夹。于是它给第二个加上序号:IMG_5512.HEIC 和 IMG_5512(1).HEIC。
你会以为附属文件是 IMG_5512.HEIC.supplemental-metadata.json 和 IMG_5512(1).HEIC.supplemental-metadata.json。不是。序号被挪到了附属文件名的末尾,在 .json 之前:IMG_5512.HEIC.supplemental-metadata(1).json。旧格式则是 IMG_5512.HEIC(1).json。
所以工具得先把照片名里的 (1) 去掉,拼出附属文件名,再把 (1) 放回 .json 前面。再叠加截断,就会出现 PXL_20240311_183022711.jpg.supplemental-(1).json 这样的名字。真实的导出里确实有这些。
带序号的重复文件比想象中常见。同一张照片存进两个相册,编辑过而 Google 保留了两个版本,或者两部手机都把文件叫 IMG_0001.JPG,都会产生。
编辑过的副本
在 Google 相册里编辑过的照片会导出成两个文件:IMG_5512.HEIC 和 IMG_5512-edited.HEIC。通常只有一个附属文件,挂在原始文件名下。编辑过的副本没有自己的附属文件,简单的工具会让它没有日期。仔细的工具会去掉 -edited,复用原始文件的附属文件。详见Takeout 的重复照片和已编辑版本。
手动匹配
用 exiftool 的话,跑两遍,每种后缀一遍:
exiftool -r -d %s -tagsfromfile "%d/%F.supplemental-metadata.json" "-DateTimeOriginal<PhotoTakenTimeTimestamp" -ext jpg -ext heic -overwrite_original .
exiftool -r -d %s -tagsfromfile "%d/%F.json" "-DateTimeOriginal<PhotoTakenTimeTimestamp" -ext jpg -ext heic -overwrite_original .
然后用 exiftool -r -if 'not $DateTimeOriginal' -filename . 列出还没有日期的文件。剩下的就是截断和 (1) 那一批。最简单的办法是写个小脚本把这些附属文件改成完整的预期名字,再跑一遍 exiftool。免费社区工具 GooglePhotosTakeoutHelper 内置了这种匹配,习惯用终端的人通常会推荐它。它的版本更新有时跟不上 Google 的改动,如果某次运行漏了文件,去看看它的 issue 列表。
用软件
Takeout JSON Metadata Fixer 不需要任何配置就能处理以上所有情况,支持 Windows、Linux 和 Mac。
对每张照片,它依次尝试 2024 年的新名字、旧名字、挪过位置的 (1) 序号,最后是文件夹里任何名字是完整预期名前缀的 .json。编辑过的副本借用原始文件的附属文件。然后把日期和 GPS 写进文件。它会报告有多少照片匹配到了附属文件,多少退回用了 EXIF 或文件时间,这样在删除任何东西之前你就能知道配对是否成功。试运行模式只显示计划,不写入。前 1000 张照片免费。
常见问题
supplemental-metadata.json 的内容和旧的 .json 不一样吗?
一样。字段相同:title、photoTakenTime、creationTime、geoData、geoDataExif 等等。只是文件名变了。
我的照片完全没有附属文件,为什么?
实况照片的视频片段经常没有。很早以前上传的一些文件也没有。还有一种情况:附属文件被截断或者序号挪了位置,你的工具把它报告成「缺失」,其实文件在那里。自己去文件夹里看一眼。
能把附属文件改回旧格式的名字吗?
能,改回去之后旧脚本就又能用了。去掉 .supplemental-metadata,把 (1) 挪回照片名那部分,就够了。先在副本上试。
Google 还会再改名字吗?
有可能。对任何工具来说,稳妥的做法是按前缀和 title 字段匹配,而不是按固定后缀。