Skip to content

ext-ffmpeg

An Artisan Build project

Native FFmpeg,
the PHP way.

A PHP extension that binds the FFmpeg libraries directly — in pure C against the Zend API. Open, probe, and transcode media with a real object model and real typed exceptions. No shell_exec. No string-building. No FFI.

Sponsored by Tighten

ext-ffmpeg

Open → probe → transcode → save

The v1 surface, end to end. Four steps, no surprises.

  1. 01

    open

    Eagerly probe a file — container, duration, and typed stream views in one call.

  2. 02

    probe

    Read dimensions, codecs, frame rate, sample rate — as real typed, readonly properties.

  3. 03

    transcode

    Re-encode or stream-copy, per stream, with codecs chosen as a typed enum.

  4. 04

    save

    Write straight to the target via avio. Stateless, re-runnable, leak-free.

A few lines, not a shell script.

Compose an output from stream views, choose codecs as a typed enum, and write it. save() builds the output context, transcodes, and tears it down — within the call.

MediaEncoder reference →
transcode.php
use FFmpeg\Media;
use FFmpeg\MediaEncoder;
use FFmpeg\Codec\VideoCodec;
use FFmpeg\Codec\AudioCodec;

$media = Media::open('input.mov');

// Re-encode the video to H.264, stream-copy the audio, write straight to disk.
(new MediaEncoder())
    ->addVideo($media->videoStream(), VideoCodec::H264)
    ->addAudio($media->audioStream(), AudioCodec::Copy)
    ->save('output.mp4');

Why a native extension?

No shell_exec

No CLI string-building, no escaping, no parsing stderr. You call methods; FFmpeg runs in-process.

Typed exceptions

Every failure is a FFmpeg\Exception\* carrying ->operation and ->avError. No bare false.

GC-tied lifecycle

Native resources hang off PHP objects and free on garbage collection. No manual cleanup.

OO-first

Media, streams, MediaEncoder — a real object model. No av_* soup in the global namespace.

Pure C / Zend API

Not FFI, not a wrapper around the binary. A native extension compiled against the libraries.

Filters (soon)

A first-class filter graph API is the next wave — with docs good enough to replace the manual.

Support the work

Native extensions take real time.

Binding FFmpeg in C — getting the object model, the lifecycle, and the docs right — is slow, careful work. Tighten sponsors it, and sponsorship is what keeps it moving toward filters and beyond. If ext-ffmpeg saves you from shelling out to a binary, consider chipping in.

Ready to read the docs?

An Artisan Build project.

Built on FFmpeg — an independent binding, not affiliated with or endorsed by the FFmpeg project.

Proudly sponsored by Tighten.