Live Photos (or Motion Photos) may display incorrectly when there's a discrepancy in aspect ratios between the still image and video portions #5398

Open
opened 2026-02-05 11:25:22 +03:00 by OVERLORD · 6 comments
Owner

Originally created by @Coooolfan on GitHub (Feb 15, 2025).

The bug

Some devices capture photos with outer frame watermarks, which causes the photo to be wider than the sensor's recording area. Consequently, Live Photos captured by these devices will have different aspect ratios for the still image and video (typically, the video portion is narrower as it lacks the watermark).

In mobile applications, the video portion of Live Photos is often not rendered according to its true aspect ratio. Instead, the app mistakenly applies the aspect ratio of the still image. This results in the video playback being stretched and distorted."

The OS that Immich Server is running on

Linux 6.8.0-51-generic #52-Ubuntu SMP PREEMPT_DYNAMIC Thu Dec 5 13:09:44 UTC 2024 x86_64 x86_64 x86_64 GNU/Li

Version of Immich Server

v1.126.1

Version of Immich Mobile App

v1.126.1 build.184

Platform with the issue

  • Server
  • Web
  • Mobile

Your docker-compose.yml content

name: immich

services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    extends:
      file: hwaccel.transcoding.yml
      service: quicksync # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
    volumes:
      # Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro
      - ./XiaomiAlbumSyncer/download:/mnt/xiaomi-album-syncer:ro
      - ./geodata:/build/geodata
      - ./i18n-iso-countries/langs:/usr/src/app/node_modules/i18n-iso-countries/langs
    env_file:
      - .env
    ports:
      - 2283:2283
    depends_on:
      - redis
      - database
    restart: unless-stopped

  immich-machine-learning:
    container_name: immich_machine_learning
    # For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag.
    # Example tag: ${IMMICH_VERSION:-release}-cuda
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
    # extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration
    #   file: hwaccel.ml.yml
    #   service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable
    volumes:
      - model-cache:/cache
    env_file:
      - .env
    restart: unless-stopped

  redis:
    container_name: immich_redis
    image: docker.io/redis:6.2-alpine@sha256:e3b17ba9479deec4b7d1eeec1548a253acc5374d68d3b27937fcfe4df8d18c7e
    healthcheck:
      test: redis-cli ping || exit 1
    restart: unless-stopped

  database:
    container_name: immich_postgres
    image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: '--data-checksums'
    volumes:
      # Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    healthcheck:
      test: pg_isready --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' || exit 1; Chksum="$$(psql --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' --tuples-only --no-align --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')"; echo "checksum failure count is $$Chksum"; [ "$$Chksum" = '0' ] || exit 1
      interval: 5m
      start_interval: 30s
      start_period: 5m
    command: ["postgres", "-c" ,"shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"]
    restart: unless-stopped

volumes:
  model-cache:

Your .env content

UPLOAD_LOCATION=./library
DB_DATA_LOCATION=./postgres

TZ=Asia/Shanghai

IMMICH_VERSION=release

DB_PASSWORD=

DB_USERNAME=postgres
DB_DATABASE_NAME=immich

Reproduction steps

  1. Upload a Live Photo (or Motion Photo) where the video and photo portions have different aspect ratios.
  2. View the video portion of this Live Photo on a mobile device.

Relevant log output


Additional information

Two files are provided for testing: a Live Photo (or Motion Photo) in JPG format, and a screen recording.

The screen recording is divided into two parts: the first part shows the Immich app, and the second part shows the content from the device's native photo album application.

(You can observe the stretching effect, which is clearly demonstrated by the position of the record cover.)

Image

https://drive.google.com/file/d/1-aVjQIpGB3QwcLMTV8sp4MAIp1JkVIRn/view?usp=sharing

https://github.com/user-attachments/assets/617a1ebe-9cbc-44bc-9949-892e390d4184

Originally created by @Coooolfan on GitHub (Feb 15, 2025). ### The bug Some devices capture photos with outer frame watermarks, which causes the photo to be wider than the sensor's recording area. Consequently, Live Photos captured by these devices will have different aspect ratios for the still image and video (typically, the video portion is narrower as it lacks the watermark). In mobile applications, the video portion of Live Photos is often not rendered according to its true aspect ratio. Instead, the app mistakenly applies the aspect ratio of the still image. This results in the video playback being stretched and distorted." ### The OS that Immich Server is running on Linux 6.8.0-51-generic #52-Ubuntu SMP PREEMPT_DYNAMIC Thu Dec 5 13:09:44 UTC 2024 x86_64 x86_64 x86_64 GNU/Li ### Version of Immich Server v1.126.1 ### Version of Immich Mobile App v1.126.1 build.184 ### Platform with the issue - [ ] Server - [ ] Web - [x] Mobile ### Your docker-compose.yml content ```YAML name: immich services: immich-server: container_name: immich_server image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release} extends: file: hwaccel.transcoding.yml service: quicksync # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding volumes: # Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file - ${UPLOAD_LOCATION}:/usr/src/app/upload - /etc/localtime:/etc/localtime:ro - ./XiaomiAlbumSyncer/download:/mnt/xiaomi-album-syncer:ro - ./geodata:/build/geodata - ./i18n-iso-countries/langs:/usr/src/app/node_modules/i18n-iso-countries/langs env_file: - .env ports: - 2283:2283 depends_on: - redis - database restart: unless-stopped immich-machine-learning: container_name: immich_machine_learning # For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag. # Example tag: ${IMMICH_VERSION:-release}-cuda image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release} # extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration # file: hwaccel.ml.yml # service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable volumes: - model-cache:/cache env_file: - .env restart: unless-stopped redis: container_name: immich_redis image: docker.io/redis:6.2-alpine@sha256:e3b17ba9479deec4b7d1eeec1548a253acc5374d68d3b27937fcfe4df8d18c7e healthcheck: test: redis-cli ping || exit 1 restart: unless-stopped database: container_name: immich_postgres image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0 environment: POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_USER: ${DB_USERNAME} POSTGRES_DB: ${DB_DATABASE_NAME} POSTGRES_INITDB_ARGS: '--data-checksums' volumes: # Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file - ${DB_DATA_LOCATION}:/var/lib/postgresql/data healthcheck: test: pg_isready --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' || exit 1; Chksum="$$(psql --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' --tuples-only --no-align --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')"; echo "checksum failure count is $$Chksum"; [ "$$Chksum" = '0' ] || exit 1 interval: 5m start_interval: 30s start_period: 5m command: ["postgres", "-c" ,"shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"] restart: unless-stopped volumes: model-cache: ``` ### Your .env content ```Shell UPLOAD_LOCATION=./library DB_DATA_LOCATION=./postgres TZ=Asia/Shanghai IMMICH_VERSION=release DB_PASSWORD= DB_USERNAME=postgres DB_DATABASE_NAME=immich ``` ### Reproduction steps 1. Upload a Live Photo (or Motion Photo) where the video and photo portions have different aspect ratios. 2. View the video portion of this Live Photo on a mobile device. ### Relevant log output ```shell ``` ### Additional information Two files are provided for testing: a Live Photo (or Motion Photo) in JPG format, and a screen recording. The screen recording is divided into two parts: the first part shows the Immich app, and the second part shows the content from the device's native photo album application. (You can observe the stretching effect, which is clearly demonstrated by the position of the record cover.) ![Image](https://github.com/user-attachments/assets/27a2ba16-74ce-479d-89cc-833684c93f11) https://drive.google.com/file/d/1-aVjQIpGB3QwcLMTV8sp4MAIp1JkVIRn/view?usp=sharing https://github.com/user-attachments/assets/617a1ebe-9cbc-44bc-9949-892e390d4184
OVERLORD added the 📱mobile label 2026-02-05 11:25:22 +03:00
Author
Owner

@heichaowo commented on GitHub (Feb 17, 2025):

same issue

@heichaowo commented on GitHub (Feb 17, 2025): same issue
Author
Owner

@Coooolfan commented on GitHub (Feb 20, 2025):

Hey! Is anyone working on this issue? I'm currently looking into it and wanted to check to avoid any duplicate work.

@Coooolfan commented on GitHub (Feb 20, 2025): Hey! Is anyone working on this issue? I'm currently looking into it and wanted to check to avoid any duplicate work.
Author
Owner

@bo0tzz commented on GitHub (Feb 20, 2025):

I don't believe anyone is working on this, so go for it. Thank you!

@bo0tzz commented on GitHub (Feb 20, 2025): I don't believe anyone is working on this, so go for it. Thank you!
Author
Owner

@potat-dev commented on GitHub (Nov 24, 2025):

The issue still persists for me on Immich Android app and server both v2.3.1.

The video stretches to the photo's aspect ratio, which noticeably distorts it.

Demo:
https://github.com/user-attachments/assets/f5034199-7c15-41f4-a2a0-b1a0c980ac5f

Demo file:
https://github.com/user-attachments/assets/39c293b8-bec8-4657-ad06-9c9a9f461f50

@potat-dev commented on GitHub (Nov 24, 2025): The issue still persists for me on Immich Android app and server both v2.3.1. The video stretches to the photo's aspect ratio, which noticeably distorts it. Demo: https://github.com/user-attachments/assets/f5034199-7c15-41f4-a2a0-b1a0c980ac5f Demo file: https://github.com/user-attachments/assets/39c293b8-bec8-4657-ad06-9c9a9f461f50
Author
Owner

@Coooolfan commented on GitHub (Nov 24, 2025):

Time flies. I tried to fix this bug half a year ago but didn’t succeed in the end. I remember the main issue was that the video part of the live photo inherited the image’s aspect ratio. My PR attempted to use the video’s aspect ratio when switching to the video state of the live photo. However, the playback widget often failed to obtain the video’s aspect ratio before the video started playing, and the issue was hard to reproduce consistently.

I also vaguely remember that this video playback widget was forked from another project, and the upstream had reported a similar issue. I’m not sure whether it has been fixed in the latest version.

I’m not particularly skilled with Flutter, especially since this video component also interacts with native code. If anyone is interested in fixing this bug, please be careful not to repeat the same pitfalls — good luck!

@Coooolfan commented on GitHub (Nov 24, 2025): Time flies. I tried to fix this bug half a year ago but didn’t succeed in the end. I remember the main issue was that the video part of the live photo inherited the image’s aspect ratio. My PR attempted to use the video’s aspect ratio when switching to the video state of the live photo. However, the playback widget often failed to obtain the video’s aspect ratio before the video started playing, and the issue was hard to reproduce consistently. I also vaguely remember that this video playback widget was forked from another project, and the upstream had reported a similar issue. I’m not sure whether it has been fixed in the latest version. I’m not particularly skilled with Flutter, especially since this video component also interacts with native code. If anyone is interested in fixing this bug, please be careful not to repeat the same pitfalls — good luck!
Author
Owner

@potat-dev commented on GitHub (Dec 4, 2025):

Is anyone planning to work on this problem?

@potat-dev commented on GitHub (Dec 4, 2025): Is anyone planning to work on this problem?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: immich-app/immich#5398