Files
to-live-photo/docs/TECHSPEC_LivePhoto_App_V0.2_2025-12-13.md
empty 299415a530 feat: 初始化 Live Photo 项目结构
- 添加 PRD、技术规范、交互规范文档 (V0.2)
- 创建 Swift Package 和 Xcode 项目
- 实现 LivePhotoCore 基础模块
- 添加 HEIC MakerNote 元数据写入功能
- 创建项目结构文档和任务清单
- 添加 .gitignore 忽略规则
2025-12-14 16:21:20 +08:00

8.3 KiB
Raw Blame History

技术规格书Live Photo 制作与动态壁纸引导 AppV0.2-Tech

  • 适用平台iPhone / iPadiOS / iPadOS
  • 日期2025-12-13Asia/Manila
  • 用途:用于 AI 编码 / 架构落地 / 研发验收

1. 范围与目标

本技术规格书覆盖媒体导入、编辑、Live Photo 合成与写入、校验、壁纸引导、缓存与日志、埋点。

  • 目标:在不使用私有 API 的前提下,生成系统相册可识别的 Live Photo 资产,并通过引导帮助用户设置锁屏动态壁纸。
  • 非目标:不直接替用户设置系统壁纸;不做云端上传/存储(默认本地)。

2. 总体架构

2.1 模块分层

层级 模块 职责 关键技术
UI Home/Editor/Processing/Result/Guide 页面展示、交互、状态驱动 SwiftUI推荐/UIKit
Domain Workflows 导入-编辑-生成-保存-引导的业务编排 async/await, Combine(可选)
Service MediaImport / Builder / AlbumWriter / Validation 导入、合成、写相册、校验 PhotosUI, AVFoundation, Photos, ImageIO
Infra CacheManager / Logger / Analytics 缓存、日志、埋点、错误封装 FileManager, OSLog, 自研/第三方

2.2 目录结构建议Xcode

  • App/入口、DI、AppState
  • Features/Home, Features/Editor, Features/Processing, Features/Result, Features/Guide
  • Domain/ModelsWorkItem、ExportParams、Capability
  • Domain/UseCasesImportVideo、BuildLivePhoto、SaveToAlbum、Validate、GenerateGuideSteps
  • Services/MediaImport, Services/LivePhotoBuilder, Services/AlbumWriter, Services/Validation
  • Infra/Cache, Infra/Logging, Infra/Analytics, Infra/Errors
  • Resources/引导图、FAQ 文案、模板配置 JSON

3. 核心数据模型

3.1 WorkItem作品

字段 类型 说明
id UUID 作品唯一标识
createdAt Date 创建时间
sourceVideo SourceRef 来源引用PHAsset localIdentifier 或 fileURL
coverImage SourceRef? 可选封面图引用
exportParams ExportParams 比例/裁剪/关键帧等参数
status enum idle/editing/processing/success/failed
resultAssetId String? 写入相册后的 asset.localIdentifier
cacheDir URL 中间文件目录
error AppError? 失败信息(含可行动建议)

3.2 ExportParams导出参数

字段 类型 说明/规则
aspectRatio Preset/CGFloat 模板iPhoneLock、Full、4:3…
cropTransform scale + offset 编辑页输出的裁剪参数
trimStart Double 默认0
trimEnd Double 默认3限制1.5~5
keyFrameTime Double 在trim区间内
audioPolicy enum keep/remove默认keep
codecPolicy enum passthrough / fallbackH264
hdrPolicy enum keep / toneMapToSDR建议
maxDimension Int 上限,例如 1920 或自适应

4. 状态机与工作流

4.1 作品状态机(建议)

  • Idle未开始
  • → Importing导入中→ Editing编辑中
  • → Processing生成中Normalize → BuildPhoto → BuildVideo → Pairing → Validate
  • → Success成功可保存/已保存)
  • → Failed失败含可重试点与建议

处理阶段建议暴露为枚举(用于进度与日志):

  • normalize归一化裁剪/转码策略确定)
  • extractKeyFrame取关键帧/封面图)
  • writePhotoMetadata写图片侧元数据
  • writeVideoMetadata重封装并写视频侧元数据
  • saveToAlbum写入相册
  • validate校验 Live Photo 是否可识别)

4.2 并发与取消

  • 生成任务使用 TaskSwift Concurrency实现可被用户取消取消时清理未写入相册的中间文件。
  • 对 AVAssetReader/Writer 的写入任务采用串行队列/actor 封装,避免资源竞争。
  • 避免主线程阻塞:任何转码/重封装/写文件都在后台队列或 Task 中执行。

5. Live Photo 合成实现规范

5.1 输入约束与预处理Normalize

  • 时长:将 trim 区间限制在 1.5~5s默认 3s
  • 分辨率:按 maxDimension 缩放;优先保证主体清晰而不是极限画质。
  • 帧率:高帧率(>30fps可降至 30fps以提升兼容性与体积。
  • HDR若检测到 HDR/Dolby Vision优先提示并建议转 SDRtone mapping避免部分系统/场景识别异常。

5.2 绑定标识Identifier

  • 每次生成一个 assetIdentifierUUID string
  • 图片与视频必须共享同一 identifier否则系统不会将其识别为 Live Photo 对。

5.3 图片侧Photo输出规范

  • 优先输出 HEIC更现代且在较新系统上更稳定必要时支持 JPEG 作为降级。
  • 写入 Apple MakerNote/相关字段以携带 identifier实现时以可验证的字段集合为准
  • 封面图来源优先级:用户选封面照片 > 从视频 keyFrameTime 抽帧。

5.4 视频侧Paired Video输出规范

  • 容器MOV。
  • 写入 QuickTime metadatacontent identifier与照片一致
  • 写入 timed metadata trackstill-image-time标记关键照片时刻
  • 尽量 re-mux不重编码提升速度若写入失败或素材不兼容再降级到转码流程。

5.5 写入相册规范

  • 使用 PHAssetCreationRequest 同时 addResource.photo 与 .pairedVideo。
  • 在 performChanges 回调中记录成功/失败;成功后写入 resultAssetId失败需返回可行动错误。

5.6 校验Validation

  • 策略 A保存后用 resultAssetId 取回 PHAsset尝试请求 Live Photo或检查其资源类型/子资源)。
  • 策略 B若无法直接取 Live Photo 对象,则至少验证:相册中显示 Live 标识(人工/自动化截图对比可作为 QA 手段)。
  • 校验失败要区分:合成失败 vs 写相册失败 vs 系统未识别。

6. 错误码与可行动建议Error Taxonomy

错误码 阶段 用户可见文案(标题) 常见原因 建议动作App 提示)
LPB-001 Import 无法读取视频 权限不足/资源损坏 检查相册权限;换一个视频
LPB-101 Normalize 素材参数不兼容 HDR/超高分辨率/奇怪编码 开启“兼容模式”;降低分辨率/转 SDR
LPB-201 Photo 封面生成失败 抽帧失败/内存不足 缩短时长;降低分辨率;重试
LPB-301 Video 视频处理失败 重封装/转码失败 切换到 H.264 兼容导出;关闭音频
LPB-401 Album 保存到相册失败 无写入权限/相册忙 允许“添加到相册”;稍后重试
LPB-501 Validate 系统未识别为实况 元数据不完整/系统限制 重新生成;尝试更短视频;升级系统(如需壁纸动效)
LPB-901 Unknown 发生未知错误 不可预期异常 反馈日志;重启 App重试

7. 缓存、日志与诊断

7.1 缓存目录结构

  • Caches/LivePhotoBuilder/{workId}/source.mov(可选)
  • Caches/LivePhotoBuilder/{workId}/normalized.mov(归一化输出)
  • Caches/LivePhotoBuilder/{workId}/photo.heic(封面图)
  • Caches/LivePhotoBuilder/{workId}/paired.mov(写入元数据后的成品视频)
  • Caches/LivePhotoBuilder/{workId}/builder.log(阶段日志,供反馈)

7.2 清理策略

  • 成功:保留 photo/paired 的短期缓存(例如 24h以支持“再次保存/分享”;随后自动清理。
  • 失败:保留日志与关键中间文件(例如 24h方便用户一键反馈随后清理。
  • 用户手动“清理缓存”:立即删除所有 workId 目录,但不影响系统相册成品。

8. 安全与隐私

  • 默认全程本地处理,不上传用户素材。
  • 日志默认不包含媒体内容本身;仅记录参数与错误码;用户反馈前需二次确认。
  • 权限请求延迟到使用时,并提供用途说明与拒绝后的替代路径。

9. AI 编码提示(可直接复制给 AI

  • 按模块创建 Swift Package 或 App 内分组;对 LivePhotoBuilder 使用 actor 管理状态与文件路径。
  • UseCase 层提供 async 函数:importVideo(), buildLivePhoto(), saveToAlbum(), validate().
  • UI 层采用单一 source of truthWorkItemViewState;所有副作用通过 UseCase 注入。
  • 为每个阶段输出结构化日志与 progress (0~1) + stage enum