Skip to content

feat: add @libre.graph.livePhoto facet to driveItem#50

Open
dschmidt wants to merge 3 commits into
mainfrom
live-photo-facet
Open

feat: add @libre.graph.livePhoto facet to driveItem#50
dschmidt wants to merge 3 commits into
mainfrom
live-photo-facet

Conversation

@dschmidt

@dschmidt dschmidt commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Description

What are Live Photos?

Apple Live Photos are a pair of files: a still image (HEIC or JPEG) and a
short QuickTime video, captured together and linked by a shared content
identifier (a UUID). On the image it is stored in the Apple maker note,
on the video as com.apple.quicktime.content.identifier. Unlike Google
Motion Photos (#36) there is no single embedded file, the two halves are
separate driveItems.

There is no public file format specification; the metadata keys are
documented as AVFoundation metadata identifiers:
https://developer.apple.com/documentation/avfoundation/avmetadataidentifier

What this PR adds

A new read-only @libre.graph.livePhoto facet on driveItem, following the
@libre.graph.motionPhoto pattern. Facet presence means the item was
captured as part of a Live Photo; the counterpart is the driveItem whose
facet carries the same contentId.

Property Type Description
contentId string (required) UUID shared by both halves, used for pairing. Required: facet presence means the identifier was found.
stillImageTimeUs integer (int64) Time in microseconds within the video at which the still was captured. Comes from the video file only; absent until the extraction side supports it (see below).
auto boolean Auto Live Photo mode flag (video half only).
vitalityScore number (double) 0..1 score of how interesting the clip is, used for autoplay decisions (video half only).
vitalityScoringVersion integer (int64) Version of the scoring algorithm (video half only).

Example response

{
  "@libre.graph.livePhoto": {
    "contentId": "CD28D161-D5EC-4CDE-8B60-DACCC1363B6B",
    "stillImageTimeUs": 1233333,
    "auto": true,
    "vitalityScore": 0.9398496,
    "vitalityScoringVersion": 4
  }
}

Validated with openapi-generator-cli v7.13.0 (validate plus a go client
generation smoke test; the generated model and driveItem wiring look as
expected).

Metadata extraction prerequisites on the server side: the video-side keys
are covered by apache/tika#2935, the image-side
Live Photo video index additionally needs
drewnoakes/metadata-extractor#739 (tracked in
https://issues.apache.org/jira/browse/TIKA-4776). stillImageTimeUs is
specified now but will stay absent until the extraction side can parse
the com.apple.quicktime.still-image-time timed metadata track (mebx)
of the video. The image side offers no reliable source: the Apple maker
note tag 0x0017, historically documented as a derivable video index,
does not encode a usable time on current iOS versions.

@dschmidt dschmidt force-pushed the live-photo-facet branch from 7738de5 to 2c63279 Compare July 9, 2026 09:06
@dschmidt dschmidt marked this pull request as ready for review July 9, 2026 09:08
Apple Live Photos are a pair of files (HEIC/JPEG still plus QuickTime
video) sharing one content identifier, stored in the Apple maker note
on the image and as com.apple.quicktime.* metadata keys on the video.
Unlike Google Motion Photos there is no single embedded file, so the
facet carries the shared contentId for pairing, plus the video-side
properties auto, vitalityScore, vitalityScoringVersion and
fullFrameRatePlaybackIntent.

Validated with openapi-generator-cli v7.13.0 (validate plus a go
client generation smoke test).
@dschmidt dschmidt force-pushed the live-photo-facet branch from 2c63279 to 602e5d9 Compare July 9, 2026 09:36
The key is undocumented by Apple (known only from an ExifTool forum
find) and not consumed anywhere, not even Apple's own LivePhotosKit JS
player references it. No point in specifying a value nobody can act on.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new read-only @libre.graph.livePhoto facet to the driveItem schema to expose Apple Live Photo pairing metadata (via a shared contentId), mirroring the existing @libre.graph.motionPhoto extension approach.

Changes:

  • Add @libre.graph.livePhoto facet to driveItem referencing a new livePhoto schema.
  • Introduce components.schemas.livePhoto with contentId plus optional video-half metadata fields (stillImageTimeUs, auto, vitalityScore, vitalityScoringVersion).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +5293 to +5296
vitalityScore:
type: number
format: float
description: |
The rest of the spec consistently uses double for number properties
(e.g. photo.fNumber, video.frameRate); float was an unintended
inconsistency. Flagged by the Copilot review.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants