How to Configure FFmpeg Streams for Camera Input in Frigate NVR

Frigate NVR builds FFmpeg command lines through a three-layer system of global defaults, symbolic presets, and per-camera overrides defined in frigate/config/camera/ffmpeg.py and frigate/ffmpeg_presets.py.

Every camera stream in the blakeblackshear/frigate repository relies on FFmpeg for ingestion, decoding, and optional re-encoding. Understanding how Frigate assembles the final command line helps you optimize performance, enable hardware acceleration, and troubleshoot protocol-specific issues without verbose manual arguments.

The Three Layers of FFmpeg Configuration

Frigate constructs FFmpeg commands by merging three distinct configuration layers. This architecture keeps standard setups concise while allowing surgical overrides for problematic cameras.

Global Defaults

Every FFmpeg process starts with baseline arguments defined in frigate/config/camera/ffmpeg.py【^1†L19-L22】. The defaults suppress verbose output and limit thread usage:

global_args: -hide_banner -loglevel warning -threads 2

These arguments appear before any input definition in the final command line.

Presets System

Presets are symbolic names that expand to hardware-specific or protocol-specific argument lists. All preset definitions reside in frigate/ffmpeg_presets.py【^2†L84-L124】, with human-readable documentation in docs/docs/configuration/ffmpeg_presets.md【^3†L12-L50】.

The preset parser functions—parse_preset_hardware_acceleration_decode, parse_preset_input, and parse_preset_output_record—resolve symbolic names into concrete FFmpeg arguments at runtime【^2†L12-L61】.

Per-Camera Overrides

Individual cameras can replace any layer using the ffmpeg configuration block. The schema in frigate/config/camera/ffmpeg.py【^1†L64-L73】 supports hwaccel_args, input_args, global_args, and output_args at both the camera level and per-input stream level.

Available FFmpeg Presets

Selecting the correct preset eliminates manual tuning for GPU acceleration and transport protocols.

Hardware Acceleration Presets

Use these to enable GPU decoding and scaling:

  • preset-vaapi – Intel/AMD VA-API acceleration
  • preset-nvidia – NVIDIA CUDA (auto-detects codec)
  • preset-nvidia-h264 / preset-nvidia-h265 – Explicit NVIDIA codec selection
  • preset-rpi-64-h264 – Raspberry Pi V4L2 M2M decoder
  • preset-jetson-h264 / preset-jetson-h265 – Jetson NV MPI decoding

The auto value for hwaccel_args triggers automatic detection based on available hardware【^2†L23-L30】.

Input Presets

Match these to your camera's protocol and behavior:

  • preset-rtsp-generic – TCP transport RTSP (default)
  • preset-rtsp-udp – UDP-only RTSP for cameras that reject TCP
  • preset-http-reolink – HTTP-FLV streams for Reolink cameras behind restreams
  • preset-http-jpeg-generic / preset-http-mjpeg-generic – Static image or MJPEG HTTP feeds

Output Presets

Control recording behavior and audio handling:

  • preset-record-generic – Copy video stream, no audio
  • preset-record-generic-audio-aac – Copy video, re-encode audio to AAC (default)
  • preset-record-generic-audio-copy – Copy both video and audio (FFmpeg 6.x; falls back to AAC on FFmpeg 7.x)【^2†L36-L44】

Practical Configuration Examples

Minimal Setup with Auto-Detection

For standard RTSP cameras, Frigate can auto-select hardware acceleration:

cameras:
  front_door:
    ffmpeg:
      input_args: preset-rtsp-generic
    # Uses default detect and record roles

This relies on the default input_args value of preset-rtsp-generic defined in the FFmpeg configuration schema【^1†L64-L67】.

Explicit Hardware Acceleration

Force Intel VAAPI and UDP transport for a specific camera:

cameras:
  driveway:
    ffmpeg:
      hwaccel_args: preset-vaapi
      input_args: preset-rtsp-udp
    inputs:
      - path: rtsp://192.168.1.45/stream
        roles: [detect, record]
        global_args: ["-reorder_queue_size", "5"]

The hwaccel_args field accepts preset names that resolve through the parsing functions in frigate/ffmpeg_presets.py【^1†L59-L63】.

Mix HTTP-FLV for detection with RTSP for recording via go2rtc:

go2rtc:
  streams:
    reolink_front: http://192.168.1.99/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=admin&password=***

cameras:
  reolink_front:
    ffmpeg:
      inputs:
        - path: http://192.168.1.99/flv?port=1935&app=bcs&stream=channel0_ext.bcs&user=admin&password=***
          input_args: preset-http-reolink
          roles: [detect]
        - path: rtsp://127.0.0.1:8554/reolink_front
          input_args: preset-rtsp-generic
          roles: [record]

This pattern appears in the official documentation for handling Reolink-specific HTTP-FLV streams【^3†L78-L95】.

Apple Compatibility and Audio Copy

Force iOS-compatible HEVC tags and stream-copy audio:

cameras:
  garden:
    ffmpeg:
      apple_compatibility: true  # Adds hvc1 tag for H.265 recordings【^1†L80-L84】

      
  garage:
    ffmpeg:
      output_args:
        record: preset-record-generic-audio-copy

How Frigate Builds the FFmpeg Command

When loading a camera definition, Frigate executes the following merge strategy:

  1. Start with global defaults (-hide_banner, -loglevel warning, -threads 2)
  2. Merge camera-level global_args overrides
  3. Resolve the hardware acceleration preset via parse_preset_hardware_acceleration_decode (or scale/encode variants)
  4. For each input, expand the input preset using parse_preset_input and append role-specific output arguments
  5. Launch the asynchronous FFmpeg process with the assembled command line

The retry_interval parameter (default 10 seconds) governs reconnection attempts for failed streams. GPU selection logic for multi-GPU systems is handled by LibvaGpuSelector inside frigate/ffmpeg_presets.py【^2†L23-L70】.

Summary

  • Frigate assembles FFmpeg commands from global defaults, symbolic presets, and per-camera overrides defined in frigate/config/camera/ffmpeg.py.
  • Hardware presets like preset-vaapi and preset-nvidia automatically configure GPU-accelerated decoding.
  • Input presets handle protocol specifics, including preset-rtsp-udp for UDP-only cameras and preset-http-reolink for Reolink HTTP-FLV streams.
  • Output presets control recording quality and audio handling, with options for AAC re-encoding or direct stream copy.
  • Override any layer at the camera level or per-input stream level for fine-grained control without verbose argument lists.

Frequently Asked Questions

What preset should I use for Intel Quick Sync hardware acceleration?

Use preset-vaapi for Intel integrated graphics. Frigate's LibvaGpuSelector logic in frigate/ffmpeg_presets.py automatically selects the correct render device node (typically /dev/dri/renderD128) when multiple GPUs are present【^2†L23-L70】.

How do I configure FFmpeg for a UDP-only RTSP camera?

Set input_args: preset-rtsp-udp in the camera's ffmpeg configuration. This preset explicitly sets -rtsp_transport udp instead of the default TCP transport, which resolves connection issues with cameras that do not support TCP interleaved RTP【^2†L84-L124】.

Can I use different presets for detect and record roles on the same camera?

Yes. Define separate entries in the inputs list, each with distinct input_args presets and specific roles. For example, use preset-http-reolink with the detect role for a low-latency sub-stream, and preset-rtsp-generic with the record role for the high-quality main stream, as shown in the Reolink multi-protocol example.

Where are the FFmpeg presets defined in the Frigate source code?

All preset mappings reside in frigate/ffmpeg_presets.py, which contains the expansion logic for hardware acceleration, input handling, and output recording. The Pydantic models that validate these configurations are located in frigate/config/camera/ffmpeg.py【^1†L19-L73】.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →