mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-11 16:24:11 +01: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.
Context & Constraints
- Relies on the system
ffmpegbinary; defaults toFFmpegBinbut callers may overrideOptions.Bin. - Inputs are internal filenames and option structs (not user input); exec invocations are annotated with
#nosec G204. - Downstream jobs may run concurrently, so
TranscodeCmdreturns auseMutexhint to serialize expensive work. - Remux and extract commands honor
Forceand 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 optionalOptions.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);RemuxCmdcan handle otherfs.Typevalues when provided. - Streaming flags:
encode.MovFlagsdefaults touse_metadata_tags+faststartto 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 intestdata/).ffmpeg.go— package logger hook.
Related Packages & Entry Points
internal/thumbcalls these builders for video previews and thumbnails.internal/commandsand workers select encoders based on configuration options and reuseencode.Options.pkg/fssupplies path helpers, existence checks, and file-mode constants referenced by remux/extract logic.
Configuration & Safety Notes
- Clamp size and quality via
NewVideoOptionsto[1, 15360]pixels and the defined quality bounds. - Remuxing respects
Options.Force; without it existing outputs are preserved. - Metadata copying uses
-map_metadataandcleansanitizers; 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_ENCODERguidance inAGENTS.md).
Testing
- Run unit tests:
go test ./internal/ffmpeg/... - Hardware-specific tests assume the encoder is available; keep runs gated via config when adding new cases.
Operational Tips
- Prefer
TranscodeCmdover manualexec.Commandto keep logging, metadata, and mutex hints consistent. - Use
RemuxFileto convert containers without re-encoding; it creates a temp file and swaps atomically. - For preview frames, pass
encode.OptionswithSeekOffsetandTimeOffsetcomputed from video duration (seeNewPreviewImageOptions).