karin-pluginkkk
功能特性

动态照片解析

动态照片无水印解析与跨平台兼容

插件在解析作品、动态或推送内容时,遇到 Live Photo / Motion Photo 资源,会按当前配置生成兼容的实况图文件,并可额外生成“仿 iPhone Live Photo”效果视频。

平台兼容性

平台存储方式插件支持说明
Google / Pixel单文件(JPEG + MP4)标准 Motion Photo 格式
小米 HyperOS单文件(JPEG + MP4)兼容 Google 标准 + 小米扩展
OPPO ColorOS单文件(JPEG + MP4)兼容 Google 标准 + OPPO 扩展
华为/荣耀单文件(JPEG + 标记)⚠️理论支持,未经实测验证
iPhone双文件(HEIC + MOV)独立存储,无法合成单文件
vivo OriginOS双文件(JPG + MP4)独立存储,无法合成单文件

当前默认组合是:

  • livePhotoMode: video_and_livephoto
  • livePhotoSystem: oppo

使用方式

动态照片解析是自动触发的,无需额外命令:

  1. 当解析到包含动态照片的作品/动态时
  2. 插件会自动提取封面图片和视频片段
  3. 根据 livePhotoMode 决定发送实况图、效果视频,或两者都发
  4. 根据 livePhotoSystem 生成兼容不同相册系统的单文件图片
  5. 最终通过合并转发消息发送
动态照片会以独立文件的形式出现在合并转发消息中,保存到相册后即可在支持的设备上播放。
重要提示:必须保存原图才能被设备正确识别为动态照片。如果保存压缩图,会丢失视频数据,只能看到静态图片。

配置选项

核心配置有两个:

  • Live Photo 处理和发送方式(livePhotoMode
  • Live Photo 静态图兼容系统(livePhotoSystem

配置方式

在配置文件 config/app.yaml 中修改:

# video_and_livephoto: 实况图 + 效果视频
# video_only: 仅效果视频
# livephoto_only: 仅实况图
livePhotoMode: video_and_livephoto

# 可选值:'google'、'xiaomi'、'oppo'、'huawei_honor'
livePhotoSystem: oppo

可选值说明

项目可选值说明
livePhotoModevideo_and_livephoto同时发送实况图和效果视频
livePhotoModevideo_only仅发送效果视频,适合只关心播放效果的场景
livePhotoModelivephoto_only仅发送单文件实况图,性能开销更小
livePhotoSystemgoogleGoogle 标准格式
livePhotoSystemxiaomi小米兼容格式
livePhotoSystemoppoOPPO / OnePlus / realme 兼容格式,当前默认推荐
livePhotoSystemhuawei_honor华为 / 荣耀兼容格式,仍建议自行实机验证
如果你不确定选哪个系统,先用默认的 oppo;如果你更在意“尽量标准”,可以改回 google

实现原理

文件结构

动态照片本质上是将视频数据附加到 JPEG 图片文件末尾,并在 JPEG 的 XMP 元数据中记录视频的位置和长度信息。

┌─────────────────────────────┐
│   JPEG 图片数据              │
│   (SOI 0xFFD8 开始)         │
├─────────────────────────────┤
│   XMP 元数据 (APP1 段)       │
│   - MotionPhoto 标记         │
│   - 视频长度                 │
│   - 时间戳                   │
├─────────────────────────────┤
│   MP4 视频数据               │
│   (完整的 MP4 文件)          │
└─────────────────────────────┘

关键技术

1. XMP 元数据注入

插件使用 XMP(Extensible Metadata Platform)标准在 JPEG 的 APP1 段中写入 Motion Photo 元数据:

<x:xmpmeta xmlns:x="adobe:ns:meta/">
  <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <rdf:Description
      xmlns:GCamera="http://ns.google.com/photos/1.0/camera/"
      xmlns:Container="http://ns.google.com/photos/1.0/container/"
      GCamera:MotionPhoto="1"
      GCamera:MotionPhotoVersion="1"
      GCamera:MotionPhotoPresentationTimestampUs="0">
      <Container:Directory>
        <rdf:Seq>
          <rdf:li>
            <Container:Item
              Item:Mime="image/jpeg"
              Item:Semantic="Primary"
              Item:Length="0" />
          </rdf:li>
          <rdf:li>
            <Container:Item
              Item:Mime="video/mp4"
              Item:Semantic="MotionPhoto"
              Item:Length="视频字节数" />
          </rdf:li>
        </rdf:Seq>
      </Container:Directory>
    </rdf:Description>
  </rdf:RDF>
</x:xmpmeta>

2. EXIF 信息补全

部分厂商(如小米、OPPO)要求 JPEG 必须包含特定的 EXIF 信息才能正确识别。插件会自动检测并补全必要的 EXIF 段:

  • 图片宽度和高度
  • 厂商特定标记(如 OPPO 的 OpCamera:MotionPhotoOwner

3. 厂商适配

不同厂商对 Motion Photo 的实现略有差异,插件提供了四种兼容模式:

4. 图片格式转换

如果原始封面不是 JPEG 格式(如 PNG、WebP),插件会自动使用 FFmpeg 转换为 JPEG:

ffmpeg -i input.png -frames:v 1 -q:v 2 output.jpg

技术参考

插件的动态照片实现参考了以下开源项目和技术文档:


常见问题

Last updated on