Skip to content

SuoxingTech/MotionPhotoLab

Repository files navigation

MotionPhoto

Developer-oriented Android Motion Photo playground and reference library.

This repository is built for developers who want to understand, prototype, and verify Motion Photo features on Android. It is not just a demo app for clicking around. The main goal is to help you learn the file structure, inspect metadata, test compatibility, and try implementation ideas before building Motion Photo into your own product.

AI-generated project notice

This repository is entirely generated with the assistance of AI tools.

The code is provided primarily for learning, exploration, and reference purposes. It is not recommended to use this project directly as a production-ready library or dependency.

Due to the nature of AI-generated code:

  • Design decisions may lack consistency or long-term maintainability
  • Edge cases and robustness may not be fully considered
  • Hidden bugs or unintended behaviors may exist

If you choose to use any part of this code, please review, test, and adapt it carefully to your own needs.

Contributions and improvements are welcome, especially those that enhance clarity, correctness, and maintainability.

Who This Is For

  • Android developers exploring Motion Photo support for the first time
  • Engineers validating JPEG + MP4/MOV packaging strategies
  • Developers debugging XMP metadata, container offsets, or GainMap behavior
  • Teams who want a small reference implementation instead of reverse-engineering everything from scratch

What This Repo Helps You Do

This project focuses on the technical workflow behind Android Motion Photo:

  • Compose a Motion Photo from one still image and one video
  • Parse an existing Motion Photo and extract the still image, embedded video, and optional GainMap
  • Inspect XMP metadata, container directory items, offsets, MIME types, and binary layout
  • Verify generated output by re-parsing the composed file
  • Test compatibility-oriented metadata rewriting paths for Android ecosystems and vendor-specific behaviors
  • Experiment with turning iOS Live Photo style MOV input into Android-recognizable Motion Photo output

If you are trying to build Motion Photo creation or inspection into your app, this repo is meant to shorten the experimentation cycle.

Repository Structure

  • motionphoto Android library module with the reusable Motion Photo API
  • sample-app Developer demo app for manual testing, inspection, and experimentation

Demo App Focus

The sample app is intentionally built as a developer tool, not a polished consumer feature.

Create

Use the Create flow to:

  • pick one still image and one video
  • generate a Motion Photo file
  • inspect the generated file size and processing path
  • verify the output immediately by parsing it again
  • save the result into the system gallery

This is useful when you want to answer questions like:

  • Can this JPEG + MP4 pair be packaged successfully?
  • Was the source video reused or rewritten?
  • Did the output keep GainMap-related metadata?
  • Does the generated file parse cleanly after composition?

Inspect

Use the Inspect flow to:

  • open an existing Motion Photo
  • extract the primary image
  • extract the embedded video
  • extract the GainMap when present
  • inspect metadata source, offsets, XMP fields, and container directory items

This is useful when you want to understand how a device-generated Motion Photo is structured, or when you are comparing your own output against files from Google Photos, OEM camera apps, or other pipelines.

Public Library API

The library keeps a small public surface:

  • MotionPhotoComposer.compose(context, imageUri, videoUri)
  • MotionPhotoComposer.saveToGallery(context, composeResult)
  • MotionPhotoParser.parse(context, sourceUri)

Public models are defined in motionphoto/src/main/java/dev/suoxing/motionphoto/MotionPhotoModels.kt.

Example:

val composeResult = MotionPhotoComposer.compose(
    context = context,
    imageUri = imageUri,
    videoUri = videoUri,
)

val galleryUri = MotionPhotoComposer.saveToGallery(context, composeResult)

val parseResult = MotionPhotoParser.parse(context, galleryUri)

Internal Design

The library is structured as a stable facade plus internal domain modules, so format-specific logic does not collapse into one large file.

  • internal/compose still image preparation, video preparation, packaging, JPEG post-processing
  • internal/parse XMP lookup, binary segment extraction, GainMap parsing, extraction output
  • internal/format binary utilities, MIME sniffing, BMFF/QuickTime rewrite helpers
  • internal/xmp XMP parsing and vendor-aligned XMP generation
  • internal/io temp file management and gallery persistence

This structure is meant to be readable for developers studying the implementation, and maintainable for future experimentation.

Current Technical Scope

The current implementation is aimed at practical Android Motion Photo experimentation:

  • primary still image output is JPEG-based
  • video input currently targets BMFF containers such as MP4 and MOV, including compatibility-oriented handling for iOS Live Photo style MOV sources
  • parser supports Motion Photo metadata discovery through container directory items and legacy MicroVideoOffset
  • optional GainMap extraction is supported when present in the file

This repo should be treated as a strong reference base for Motion Photo work, not as a claim that every OEM-specific variant is fully covered.

Running The Demo

Build the sample app:

./gradlew :sample-app:assembleDebug

Run unit tests for the library:

./gradlew :motionphoto:testDebugUnitTest

Build the library and sample together:

./gradlew :motionphoto:testDebugUnitTest :sample-app:assembleDebug

Android Requirements

  • minSdk = 28
  • Java 11 bytecode target
  • Android library module under motionphoto
  • Sample app under sample-app

Some HDR / GainMap behavior depends on the source file and platform capabilities, so results can vary by device and Android version.

Suggested Ways To Use This Repo

If you are implementing Motion Photo in a real app, a useful workflow is:

  1. Use the sample app to inspect real Motion Photo files from target devices.
  2. Compare their metadata and offsets against files generated by your own pipeline.
  3. Use the library API as a starting point for composition and parsing.
  4. Extend or replace internal modules as your compatibility requirements become clearer.

Verification Status

The current project is verified with:

  • ./gradlew :motionphoto:testDebugUnitTest
  • ./gradlew :sample-app:assembleDebug

Notes

  • The sample app is best treated as a Motion Photo lab for developers.
  • The library favors clarity and inspectability over hiding format details.
  • If your goal is broad device compatibility, use this repo to learn and validate, then test with real files from your target camera and gallery apps.

License

MIT License, Copyright (c) 2026 Suoxing Tech. See LICENSE.

About

An Android Motion Photo playground and reference library for composing, parsing, inspecting, and validating Motion Photos.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages