MpegFlowBlogBack to home
← Recipes·Multi-output encoding·tooling

Multi-output encoding with FFmpeg: tee muxer, split filter, and the right pattern

Encode one input into multiple outputs in a single FFmpeg invocation. Split filter, tee muxer, and the throughput math that decides when this beats per-output encoding.

ByMpegFlow Engineering Team·FFmpeg recipe
·3 variants·May 9, 2026

When to use this

You use multi-output encoding when you want one FFmpeg run to produce multiple outputs from the same input — typically an ABR ladder, simultaneous HLS + DASH packaging, or a single live encode fanned out to multiple destinations. The throughput advantage: only one decode pass and one filter pass for shared transformations. The trade-off: one output's failure can block the others, and per-output retry semantics get complicated. For production at scale, individual per-output encoding is usually the right pattern; multi-output is the right call for tightly-coupled outputs (an ABR ladder where all renditions must succeed together) or when decode cost dominates encode cost.

Command variants

Multiple outputs in one invocation
ffmpeg -i input.mp4 \
  -c:v libx264 -preset medium \
  -map 0:v -map 0:a -c:v libx264 -crf 22 -c:a aac -b:a 192k \
  output_high.mp4 \
  -map 0:v -map 0:a -c:v libx264 -crf 28 -vf scale=854:480 -c:a aac -b:a 96k \
  output_low.mp4

Two outputs from one input. Each output has its own -map, codec, and filter chain. Decoder runs once.

Tee muxer for live HLS + RTMP fanout
ffmpeg -i srt://encoder:9999 \
  -c:v libx264 -preset veryfast -tune zerolatency \
  -c:a aac -b:a 128k \
  -f tee "[f=hls:hls_time=2:hls_playlist_type=event]hls/stream.m3u8|[f=flv]rtmp://backup-cdn:1935/live/stream"

Single live encode, two simultaneous outputs (HLS file + RTMP push). Common for live streaming with primary + backup destinations.

Split filter for filter-graph fanout
ffmpeg -i input.mp4 \
  -filter_complex "[0:v]split=2[hi][lo];[hi]scale=1920:1080[hi_out];[lo]scale=854:480[lo_out]" \
  -map "[hi_out]" -map 0:a -c:v libx264 -crf 22 -c:a aac output_hi.mp4 \
  -map "[lo_out]" -map 0:a -c:v libx264 -crf 28 -c:a aac output_lo.mp4

Use when outputs share filter chain (scale, crop, etc). Saves duplicate filter passes.

What each parameter does

  • -map

    Selects which input streams go into each output. Multiple -map flags per output spec are common.

  • -f tee

    Tee muxer for fanning a single encoder output to multiple destinations (files, RTMP, HLS, etc).

  • split=N

    Filter that duplicates the input N times into N labeled outputs. Used inside filter_complex.

  • filter_complex

    Multi-input/multi-output filter graph. Required for split filter and complex routing.

  • -tune zerolatency

    libx264 tuning for live use cases. Disables b-frames and lookahead. Required for live multi-output.

What this outputs

Multiple output files (file targets) or active streams (live targets). With proper configuration, all outputs are produced from a single decode + encode pass per shared stage. The throughput advantage is most visible when decode is expensive (4K source) or when filters are expensive (complex scaling / color correction).

Pitfalls

  1. Per-output retry: if one output fails, FFmpeg may abort the entire run depending on the failure. Production-grade ABR ladder generation should use individual per-rendition encoding so failures retry independently.
  2. Tee muxer error handling is finicky: a network blip on one RTMP destination can stall all destinations. Always pair with separate retry logic.
  3. Memory usage compounds: each output adds buffer requirements. Multi-output runs can OOM on high-resolution sources where individual runs would succeed.
  4. Audio re-encoding per-output wastes compute: encode audio once at the highest quality, then stream-copy to each output where compatible.
  5. Filter graphs with split are powerful but hard to debug. Always test with -filter_complex_threads 1 first to rule out threading issues.
  6. NVENC multi-output with shared decode works but has known issues with concurrent encoding sessions per GPU. Verify on your specific driver version.

At production scale

At low scale (per-encode count), multi-output is ~10-30% faster than per-output runs because decode + filter passes are shared. At production scale, per-output runs win on operational flexibility (independent retry, per-rendition pool routing, deterministic failure boundaries) — and when decode is fast (H.264 source) the multi-output advantage shrinks. The right pattern: multi-output for tightly-coupled outputs (must-succeed-together ladder), per-output for loosely-coupled outputs (rendition fanout where each can retry independently).

How MpegFlow handles this

MpegFlow lets you choose multi-output vs per-output per stage in the DAG manifest. The platform handles the operational difference: multi-output stages have unified retry, per-output stages retry per-output. The choice is data-driven, not code-driven.

Topics
  • FFmpeg
  • multi-output
  • tee-muxer
  • split-filter
  • tooling
See also
  • Recipe
    Abr Ladder Generation
  • Engineering blog
    Video Pipelines Belong In A Dag
Running this at scale?

Get the orchestration layer for free.

The multi-output encoding command above is the easy part. The queue, retries, audit trail, encoder-version pinning, and multi-tenant security around it are what every video team rebuilds from scratch. We did the rebuild — design partners run it free during beta.

Apply More recipes
© 2026 MpegFlow, Inc. · Trust & complianceAll systems nominal·StatusPrivacy