photoprism/internal/ffmpeg
2026-06-24 17:20:30 +02:00
..
apple Links: Use canonical trailing-slash form for website URLs 2026-06-24 17:20:30 +02:00
encode Links: Use canonical trailing-slash form for website URLs 2026-06-24 17:20:30 +02:00
intel Links: Use canonical trailing-slash form for website URLs 2026-06-24 17:20:30 +02:00
nvidia Links: Use canonical trailing-slash form for website URLs 2026-06-24 17:20:30 +02:00
testdata FFmpeg: Fix Intel Quick Sync Video (QSV) hardware transcoding #4382 2025-03-28 16:31:20 +01:00
v4l Links: Use canonical trailing-slash form for website URLs 2026-06-24 17:20:30 +02:00
vaapi Links: Use canonical trailing-slash form for website URLs 2026-06-24 17:20:30 +02:00
vulkan Links: Use canonical trailing-slash form for website URLs 2026-06-24 17:20:30 +02:00
exclude.go Video: Recognize MagicYUV in the probe and exclude the VFW wrapper #5617 2026-05-30 21:29:12 +00:00
exclude_test.go Video: Recognize MagicYUV in the probe and exclude the VFW wrapper #5617 2026-05-30 21:29:12 +00:00
extract_image_cmd.go CI: Apply Go linter recommendations to "internal/ffmpeg" package #5330 2025-11-22 12:58:11 +01:00
extract_image_cmd_test.go FFmpeg: Remove unstable "directory is unwritable" tests 2025-09-27 11:46:27 +02:00
ffmpeg.go Links: Use canonical trailing-slash form for website URLs 2026-06-24 17:20:30 +02:00
ffmpeg_test.go FFmpeg: Use PHOTOPRISM_FFMPEG_TEST_ENCODER to opt into HW tests #5630 2026-05-30 19:02:16 +00:00
README.md FFmpeg: Use PHOTOPRISM_FFMPEG_TEST_ENCODER to opt into HW tests #5630 2026-05-30 19:02:16 +00:00
remux.go Video: Tag HEVC remux output hvc1 and unify MP4 chunk scans #5593 2026-05-20 17:57:40 +02:00
remux_test.go Video: Tag HEVC remux output hvc1 and unify MP4 chunk scans #5593 2026-05-20 17:57:40 +02:00
test.go CI: Apply Go linter recommendations to "internal/ffmpeg" package #5330 2025-11-22 12:58:11 +01:00
transcode_cmd.go FFmpeg: Add h264_vulkan video transcoding support #5592 2026-05-21 09:44:41 +00:00
transcode_cmd_test.go FFmpeg: Fix duplicate hwupload in Vulkan transcoding command #5631 2026-05-30 20:14:14 +00:00

PhotoPrism — FFmpeg Integration

Last Updated: November 22, 2025

Overview

internal/ffmpeg wraps the ffmpeg CLI to transcode videos to AVC/H.264, remux containers, and extract preview frames in a predictable, testable way. Command builders share option structs so CLI tools, workers, and tests can select software or hardware encoders without duplicating flag logic.

Constraints

  • Relies on the system ffmpeg binary; defaults to FFmpegBin but callers may override Options.Bin.
  • Inputs are internal filenames and option structs (not user input); exec invocations are annotated with #nosec G204.
  • Downstream jobs may run concurrently, so TranscodeCmd returns a useMutex hint to serialize expensive work.
  • Remux and extract commands honor Force and reuse shared map flags; metadata copying is limited to safe defaults.

Goals

  • Provide consistent command lines for software and hardware AVC encoders.
  • Keep remuxing and preview extraction lightweight while preserving metadata where possible.
  • Centralize quality and size clamping logic so UIs/CLI can pass user preferences safely.

Non-Goals

  • Full coverage of every FFmpeg codec or container; the package focuses on MP4/H.264 paths required by PhotoPrism.
  • Direct management of FFmpeg installation or GPU availability.

Encoders, Containers, & Hardware

  • Software AVC: encode.TranscodeToAvcCmd (x264 or default encoder).
  • Intel Quick Sync: internal/ffmpeg/intel (h264_qsv) with optional Options.Device.
  • NVIDIA NVENC: internal/ffmpeg/nvidia (h264_nvenc).
  • Apple VideoToolbox: internal/ffmpeg/apple (h264_videotoolbox).
  • VA-API: internal/ffmpeg/vaapi (h264_vaapi) supporting optional device paths.
  • V4L2 M2M: internal/ffmpeg/v4l (h264_v4l2m2m) for ARM/embedded targets.
  • Containers: MP4 is the primary target (fs.VideoMp4); RemuxCmd can handle other fs.Type values when provided.
  • Streaming flags: encode.MovFlags defaults to use_metadata_tags+faststart to keep outputs stream-friendly.

Package Layout (Code Map)

  • encode/ — shared option structs, quality helpers, default map/metadata flags, software AVC command builder.
  • apple/, intel/, nvidia/, vaapi/, v4l/ — hardware-specific AVC command builders.
  • remux.go — container-only transfers with metadata copy and temp-file safety.
  • transcode_cmd.go — selects encoder, handles animated image inputs, and signals mutex usage.
  • extract_image_cmd.go — JPEG/PNG preview frame extraction with color-space presets.
  • test.go & *_test.go — reusable command runner and smoke tests (use fixtures in testdata/).
  • ffmpeg.go — package logger hook.

Related Packages & Entry Points

  • internal/thumb calls these builders for video previews and thumbnails.
  • internal/commands and workers select encoders based on configuration options and reuse encode.Options.
  • pkg/fs supplies path helpers, existence checks, and file-mode constants referenced by remux/extract logic.

Configuration & Safety Notes

  • Clamp size and quality via NewVideoOptions to [1, 15360] pixels and the defined quality bounds.
  • Remuxing respects Options.Force; without it existing outputs are preserved.
  • Metadata copying uses -map_metadata and clean sanitizers; only safe string fields (title, description, comment, author, creation_time) are added when set.
  • Hardware helpers expect the matching FFmpeg build and devices; callers should gate selection via config or environment (see PHOTOPRISM_FFMPEG_ENCODER guidance in AGENTS.md).

Testing

  • Run unit tests: go test ./internal/ffmpeg/...
  • By default the transcode tests only assert the generated command strings. To additionally run a real hardware transcode, set PHOTOPRISM_FFMPEG_TEST_ENCODER to the encoder under test (e.g. vaapi, intel, or nvidia) on a host with the matching device. The runtime PHOTOPRISM_FFMPEG_ENCODER is intentionally ignored so a development-environment value can't trigger hardware runs by accident.
  • Hardware-specific tests assume the encoder is available; keep runs gated via this opt-in variable when adding new cases.

Operational Tips

  • Prefer TranscodeCmd over manual exec.Command to keep logging, metadata, and mutex hints consistent.
  • Use RemuxFile to convert containers without re-encoding; it creates a temp file and swaps atomically.
  • For preview frames, pass encode.Options with SeekOffset and TimeOffset computed from video duration (see NewPreviewImageOptions).