Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changes/unreleased/heic-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
kind: Added
body: Add HEIC/HEIF, GIF image and MOV video format support via FFmpeg
time: 2026-01-25T21:00:00Z
---

HEIC (High Efficiency Image Container), HEIF (High Efficiency Image Format), GIF, and MOV (QuickTime) files are now supported when FFmpeg is available. These formats, commonly used by iOS devices and other platforms, are decoded using FFmpeg. The extensions `.heic`, `.heif`, `.gif`, and `.mov` are now included in the default configuration, so Photofield will automatically index and display these files alongside your other media when FFmpeg is installed.
7 changes: 6 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@ RUN \
-o /build/photofield .

# Runtime stage
FROM alpine:3.22
FROM alpine:3.23

# Install runtime dependencies
# - exiftool: metadata extraction
# - ffmpeg: video thumbnails, HEIC/HEIF/MOV/GIF support (requires build with HEVC/H.265 decoder + libheif; v7.0+ recommended, see docs)
# - libjpeg-turbo-utils: fast JPEG decoding via djpeg
# - libwebp: WebP encoding support
RUN apk add --no-cache exiftool ffmpeg libjpeg-turbo-utils libwebp && \
ln -s /usr/lib/libwebp.so.7 /usr/lib/libwebp.so

Expand Down
9 changes: 4 additions & 5 deletions defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ media:

# File extensions to index on the file system
extensions: [
".jpg", ".jpeg", ".png", ".avif", ".bmp", ".pam", ".ppm", ".jxl", ".exr", ".cr2", ".dng",
".mp4",
".jpg", ".jpeg", ".png", ".avif", ".bmp", ".pam", ".ppm", ".jxl", ".exr", ".cr2", ".dng", ".heic", ".heif", ".gif",
".mp4", ".mov",
]

# Used to extract dates from file names as a heuristic in case of missing or
Expand All @@ -137,11 +137,10 @@ media:
date_formats: ["20060201_150405"]
images:
# Extensions to use to understand a file to be an image
# extensions: [".jpg", ".jpeg", ".png", ".gif"]
extensions: [".jpg", ".jpeg", ".png", ".avif", ".bmp", ".pam", ".ppm", ".jxl", ".exr", ".cr2", ".dng"]
extensions: [".jpg", ".jpeg", ".png", ".avif", ".bmp", ".pam", ".ppm", ".jxl", ".exr", ".cr2", ".dng", ".heic", ".heif", ".gif"]

videos:
extensions: [".mp4"]
extensions: [".mp4", ".mov"]

#
# Media source configuration
Expand Down
2 changes: 1 addition & 1 deletion docs/dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
These tools are not strictly required, but if they are installed in your system, Photofield will use them to improve performance, metadata extraction, thumbnail generation, and video previews.

- [ExifTool]: Extracts metadata from many more formats than the embedded [goexif].
- [FFmpeg]: Generates video thumbnails and previews and adds support for more image formats (even basic RAW).
- [FFmpeg]: Generates video thumbnails and previews and adds support for more image formats including HEIC/HEIF (iOS photos), MOV (QuickTime videos), and basic RAW formats. **(v7.0+ recommended)**
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

This adds a specific FFmpeg version recommendation, but the Dockerfile comment references a different version. Consider keeping version guidance consistent across the repo (or avoiding a specific version and instead documenting the required codec support for HEIC/HEIF/MOV).

Suggested change
- [FFmpeg]: Generates video thumbnails and previews and adds support for more image formats including HEIC/HEIF (iOS photos), MOV (QuickTime videos), and basic RAW formats. **(v7.0+ recommended)**
- [FFmpeg]: Generates video thumbnails and previews and adds support for more image formats including HEIC/HEIF (iOS photos), MOV (QuickTime videos), and basic RAW formats.

Copilot uses AI. Check for mistakes.
- [djpeg (libjpeg-turbo)]: Accelerates JPEG decoding of big images in cases where there are no other appropriate thumbnails available.
- [libwebp]: Enables high-performance WebP encoding via dynamic library loading. When available, the [go-libwebp] encoder can use the native libwebp dynamic shared library for faster encoding (`webp-jackdyn`) compared to pure Go implementations (`webp-jacktra`).

Expand Down
4 changes: 4 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2292,6 +2292,10 @@ func main() {
mime.AddExtensionType(".png", "image/png")
mime.AddExtensionType(".jpg", "image/jpg")
mime.AddExtensionType(".jpeg", "image/jpeg")
mime.AddExtensionType(".heic", "image/heic")
mime.AddExtensionType(".heif", "image/heif")
mime.AddExtensionType(".gif", "image/gif")
mime.AddExtensionType(".mov", "video/quicktime")
Comment on lines +2295 to +2298
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

These new MIME registrations are inside if apiPrefix != "/" (the UI+API mode). In apiPrefix == "/" (API-only) mode they won’t run, so http.ServeFile for originals (e.g., /files/{id}) may still respond with application/octet-stream for HEIC/HEIF/GIF/MOV. Consider moving the relevant mime.AddExtensionType calls outside this conditional (or duplicating them for API-only) so content-types are correct in both modes.

Copilot uses AI. Check for mistakes.
mime.AddExtensionType(".ico", "image/vnd.microsoft.icon")

uifs, err := fs.Sub(StaticFs, "ui/dist")
Expand Down
Loading