FFix

Hex.pm Documentation CI License Elixir

FFix is an Elixir library for building, inspecting, and running FFmpeg commands by composing ordinary Elixir functions. Extract an audio track with a short pipeline, or combine inputs, reuse filtergraphs, and produce several outputs in one run. The same building blocks support both simple conversions and complex media processing.

A simple conversion

Extract the first audio track from an interview and save it as a WAV file:

command =
FFix.input("interview.mp4")
|> FFix.audio(0)
|> FFix.output("interview.wav")
|> FFix.command()
FFix.run!(command)

audio(0) selects the first audio track. The filename lets FFmpeg choose the WAV format and its default encoder; no filter is needed. An output describes what to write and where. A command assembles the inputs and outputs; run! starts FFmpeg.

Multiple outputs from one graph

Create a main video and a two-second preview, both with audio, plus a contact sheet. Split the video, process each branch, then declare the outputs:

alias FFix.{Encoder, Filter, Muxer}
input = FFix.input("interview.mp4")
[main, preview, sheet] =
input
|> FFix.video(0)
|> Filter.split(outputs: 3)
# -2 preserves the aspect ratio with an even height.
main_video =
main
|> Filter.scale(w: 640, h: -2)
|> Encoder.libx264()
preview_video =
preview
|> Filter.scale(w: 320, h: -2)
|> Encoder.libx264()
# Sample once per second and arrange the first four frames into one image.
contact_sheet =
sheet
|> Filter.fps(fps: 1)
|> Filter.scale(w: 160, h: -2)
|> Filter.tile(layout: "2x2")
|> Encoder.png()
# Unfiltered input audio can be reused; each MP4 gets its own AAC encode.
audio =
input
|> FFix.audio(0)
|> Encoder.aac()
main_output =
[main_video, audio]
|> Muxer.mp4("main.mp4")
preview_output =
[preview_video, audio]
|> Muxer.mp4("preview.mp4", output_options: [t: 2])
# Write one PNG file rather than a numbered image sequence.
sheet_output =
contact_sheet
|> Muxer.image2("contact-sheet.png", update: true, output_options: ["frames:v": 1])
command = FFix.command([main_output, preview_output, sheet_output])
FFix.run!(command)

Encoders control compression; muxers package the tracks. The preview's t: 2 limits both video and audio without shortening the main output. Each filtered branch is mapped once; use split whenever it needs multiple consumers.

You can also inspect either command without running it:

FFix.to_shell_string(command)
FFix.to_argv(command)

Use the argument list with your own process runner if you prefer.

Beyond the examples

Generated helpers cover hundreds of filters and selected codecs and formats. Generic functions accept literal FFmpeg names when you need to go beyond them.

Installation

Add FFix to your dependencies:

def deps do
[{:ffix, "~> 0.2.0"}]
end

FFix requires Elixir 1.16 or later. To run commands, install FFmpeg and make ffmpeg available on your PATH. You can also choose an executable with FFMPEG_BIN or the runner's ffmpeg: option. The multi-output example uses libx264, aac, and png.

Explore further