尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Immich 支持的媒体格式全解:从 MIME 类型表到上传校验、库扫描与元数据提取的源码剖析

Immich 支持的媒体格式全解:从 MIME 类型表到上传校验、库扫描与元数据提取的源码剖析 Immich 支持的媒体格式全解从 MIME 类型表到上传校验、库扫描与元数据提取的源码剖析【免费下载链接】immichHigh performance self-hosted photo and video management solution.项目地址: https://gitcode.com/GitHub_Trending/im/immichImmich 对哪些文件算照片、哪些文件算视频、哪些文件会被自动索引的判定全部集中在一张服务端 MIME 类型表里。本文以官方文档列出的图片/视频支持清单为骨架结合 mime-types.ts 的完整定义、上传校验与库扫描的实现代码讲清楚每个格式在 Immich 中的实际处理路径——读完你可以准确回答某个相机 RAW 文件能否直接上传、HEIF 照片的方向信息从哪里来、为什么某些格式 Web 端不能直接预览这类问题。一、图片格式支持清单官方文档给出的图片格式支持情况如下完整清单以源码为准见 mime-types.ts格式扩展名支持备注AVIF.avif支持HEIF 家族可能含动画BMP.bmp支持GIF.gif支持可能含动画HEIC.heic支持HEIF 家族HEIF.heif支持HEIF 家族JPEG 2000.jp2支持JPEG.jpeg.jpg.jpe.insp支持.insp同样映射为image/jpegJPEG XL.jxl支持MPO.mpo支持Multi-Picture多张图片合并的格式MIME 类型按image/jpeg处理PNG.png支持可能含动画APNGPSD.psd支持Adobe PhotoshopRAW.raw支持RW2.rw2支持SVG.svg支持TIFF.tif.tiff支持WEBP.webp支持可能含动画源码中的完整图片清单比文档表格多出的部分文档表格只列出了常见格式而源码中的image映射由webSupportedImage、webUnsupportedImage与raw三张表合并而成实际上还包含30 种相机厂商 RAW 扩展名均映射为厂商专属或x-前缀的 MIME 类型例如.arw/.sr2/.srf索尼、.cr2/.cr3佳能、.nef/.nrw尼康、.dngAdobe、.x3f适马、.3fr/.fff哈苏等完整定义见 mime-types.ts#L4-L35。这意味着主流相机厂商的 RAW 文件都可以直接作为资产上传而不是仅支持文档表格中列出的.raw、.rw2两种.hif小米手机的 HEIF 变体同样被列入 HEIF 家族.vob对应的视频扩展名见下文视频章节文档表格中未列出。一个值得注意的细节文档标注为RAW的.raw在源码中对应image/raw与image/x-panasonic-raw两个 MIME 候选mime-types.ts#L28即它是松下Panasonic的 RAW 格式而索尼.arw、尼康.nef等各自独立登记。Web 浏览器能否直接预览webSupported 与 webUnsupported 的划分源码把图片显式分成两组mime-types.ts#L37-L70webSupportedImage.avif.bmp.gif.jpeg/.jpg.png.webp——浏览器原生可渲染Web 端可直接显示原图webUnsupportedImage所有 RAW 扩展名、.heic/.heif/.hif、.jp2.jxl.svg.tif/.tiff、.mpo、.insp等——浏览器无法直接解码。这解释了一个实际使用中的现象上传 HEIC/HEIF 或 RAW 照片后Web 界面展示的是服务端生成的 JPEG/WebP 预览图而非直接加载原文件。isWebSupportedImage()与isHeifImage()这两个导出方法就是围绕这两个集合构建的mime-types.ts#L157-L158。二、视频格式支持清单文档列出的视频格式如下格式扩展名支持3GPP.3gp.3gpp支持AVI.avi支持FLV.flv支持M4V.m4v支持MATROSKA.mkv支持MP2T.mts.m2ts.m2t.ts支持MP4.mp4.insv支持.insv映射为video/mp4MPEG.mpg.mpe.mpeg支持MXF.mxf支持QUICKTIME.mov支持WEBM.webm支持WMV.wmv支持源码中video映射与文档一致mime-types.ts#L106-L127并额外登记了.vobvideo/mpegDVD 光盘常见的 MPEG 程序流。两个与文档不同的实现细节值得留意.mxf的 MIME 类型是application/mxf而非video/前缀因此assetType()在判定资产类型时必须把它显式并入视频分支// server/src/utils/mime-types.ts if (contentType application/mxf || contentType.startsWith(video/)) { return AssetType.Video; }.avi登记了 4 个历史 MIME 候选video/avi、video/msvideo、video/vnd.avi、video/x-msvideo.mp4/.insv均归入video/mp4。lookup()始终取数组第一个候选作为规范 MIME 类型其余候选仅用于toExtension()的反向查找。XMP 侧车文件文档之外的重要第三类mime-types.ts中还定义了sidecar类别mime-types.ts#L129-L131const sidecar: Recordstring, string[] { .xmp: [application/xml, text/xml], };.xmp是 RAW 照片的 EXIF 侧车文件与图片本身同名同目录。Immich 把侧车文件作为独立的上传类别处理详见 XMP Sidecars 文档并在元数据提取时优先采用侧车中的日期信息。三、格式判定如何贯穿整个服务端mimeTypes模块导出的判定函数是格式体系的消费者理解它们就能理解 Immich 对文件类型的全部处理逻辑mime-types.ts#L147-L181方法作用isAsset(filename)是否为受支持资产图片或视频isImage/isVideo/isRaw单类别判定isWebSupportedImage浏览器能否直接渲染isHeifImage是否属于.avif/.heic/.heif/.hif家族isPossiblyAnimatedImage是否可能含动画帧.avif.gif.heic.heif.jxl.png.webpisProfile(filename)是否可作为头像.avif.dng.heic.heif.jpeg.jpg.png.svg.webpisSidecar(filename)是否.xmp侧车文件canBeTransparent(filename)格式是否具备透明通道能力.avif.bmp.gif.heic.heif.hif.jxl.png.svg.tif.tiff.webplookup(filename)文件名 → MIME 类型未识别时回退为application/octet-streamtoExtension(mimeType)MIME 类型 → 扩展名其中image/jpeg固定返回.jpg见extensionOverridesassetType(filename)归一为Image/Video/Other三类资产getSupportedFileExtensions()返回全部受支持扩展名列表供库扫描与存储过滤使用上传校验不支持的格式在入口即被拒绝上传接口按字段名区分三类上传内容并在canUploadFile()中做格式门禁asset-media.service.ts#L59-L89switch (fieldName) { case UploadFieldName.ASSET_DATA: { if (mimeTypes.isAsset(filename)) { return true; } break; } case UploadFieldName.SIDECAR_DATA: { if (mimeTypes.isSidecar(filename)) { return true; } break; } case UploadFieldName.PROFILE_DATA: { if (mimeTypes.isProfile(filename)) { return true; } break; } } this.logger.error(Unsupported file type ${filename}); throw new BadRequestException(Unsupported file type ${filename});也就是说资产上传必须命中图片或视频表.xmp只能通过侧车通道上传头像则受更严格的profile白名单限制——例如你不能用.tiff或.mpo设置头像。判定基于文件扩展名内部通过getFilenameExtension()取扩展名并转小写后查表而非嗅探文件头。库自动索引扩展名列表驱动文件监控当启用库Library的文件监控时Immich 用全部受支持扩展名动态构造 picomatch 匹配器library.service.ts#L103-L106const matcher picomatch(**/*{${mimeTypes.getSupportedFileExtensions().join(,)}}, { nocase: true, ignore: library.exclusionPatterns, });匹配成功的文件变更会入队LibrarySyncFiles任务进行索引未匹配的如.pdf、.txt则直接忽略同时库级排除模式exclusionPatterns仍优先生效。同理存储层查询也基于同一份扩展名列表构造过滤条件storage.repository.ts#L286。这保证了一个关键的一致性上传接口、库扫描、存储查询看到的受支持格式永远是同一张表不会各走各的。四、特殊格式的元数据提取逻辑格式清单定义了能不能进而进入之后不同格式还需要差异化处理。metadata.service.ts中有两处与格式直接相关的分支HEIF 家族的方向Orientation修正// dont use Exif Orientation for HEIF based images, its usually missing or invalid. // prefer irot (ExifTool QuickTime:Rotation) mapped to ExifOrientation. if (mimeTypes.isHeifImage(asset.originalPath)) { const orientation this.getHeifOrientation(mediaTags); ... }metadata.service.ts#L604-L613HEIC/HEIF/AVIF/HIF 照片的 ExifOrientation标签通常缺失或不可靠Immich 改从 QuickTime 的irot标签推导方向推导不出则直接删除该标签避免按错误方向渲染手机拍的照片。动画图像与时长Duration标签// prefer duration from video tags // dont save duration if asset is definitely not an animated image (see e.g. CR3 with Duration: 1s) if (videoResult || !mimeTypes.isPossiblyAnimatedImage(asset.originalPath)) { delete mediaTags.Duration; }metadata.service.ts#L595-L599视频资产的时长一律以容器探测结果为准对可能是动画的图片AVIF/GIF/HEIC 等保留 Exif 侧的时长而对.tiff、.cr3这类静态格式则丢弃Duration标签——注释中明确提到佳能 CR3 会带一个无意义的Duration: 1s。RAW 嵌入缩略图的提取RAW 文件内部通常嵌入了一张贴图用 JPEG。服务端通过管理端配置项image.extractEmbeddedExtract embedded见 config.dto.ts#L348控制是否对mimeTypes.isRaw(...)为真的资产执行嵌入 JPEG 提取media.service.ts#L259 与 media.service.ts#L412用于在无法解码 RAW 时仍有可显示的预览。五、测试如何锁定这张格式表mime-types.spec.ts 对上述实现做了系统性约束按排序的MIME 与扩展名映射表逐条断言lookup结果如{ mimetype: image/cr3, extension: .cr3 }、{ mimetype: video/mp2t, extension: .m2t }等约百条用例新增或改动格式必须同步更新测试断言image/video/sidecar/profile各表的键与值全部小写且video、sidecar表的键必须保持排序mime-types.spec.ts#L214-L217验证image/前缀纯度image表不允许混入非图片 MIME、canBeTransparent的正反例集合、isPossiblyAnimatedImage对动画/静态/视频三类输入的判定以及toExtension(image/jpeg)固定返回.jpg的覆盖规则。六、小结Immich 的格式支持可以用三层来概括单一事实来源mime-types.ts 中raw30 种厂商 RAW、webSupportedImage/webUnsupportedImage浏览器可渲染与否、video、sidecar四张表合并出全部判定依据统一消费上传门禁asset-media.service.ts、库文件监控与索引library.service.ts、存储过滤storage.repository.ts全部复用同一组mimeTypes.*方法差异化处理HEIF 家族的方向修正、动画图像的时长保留、RAW 嵌入 JPEG 提取均在元数据/媒体服务中按格式分支处理并有 mime-types.spec.ts 锁定行为。如果你需要确认某个扩展名是否受支持最快路径就是直接查mime-types.ts中的表——文档表格是其常见子集源码表才是完整清单。【免费下载链接】immichHigh performance self-hosted photo and video management solution.项目地址: https://gitcode.com/GitHub_Trending/im/immich创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表