Skip to content

ext-ffmpeg

ext-ffmpeg is an independent, pre-release project built on FFmpeg — not affiliated with or endorsed by the FFmpeg project. Support FFmpeg.

FFmpeg language bindings for PHP

By Artisan Build

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

or ♥ sponsor the project · support FFmpeg

Built against FFmpeg 7.1.1 behind 8.1.1
ext v0.1.0-dev · 5f52291 php 8.4 · 8.5 os Linux · macOS
ext-ffmpeg

Open → probe → filter → compose → transcode → save

The whole pipeline, in PHP.

  1. 01

    open

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

  2. 02

    generate

    Synthesize a stream from nothing — solid colors, test patterns, tones, silence — then filter and encode it like any other.

  3. 03

    probe

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

  4. 04

    filter

    Build a filter graph in PHP — scale, crop, overlay, normalize, even per-frame logic.

  5. 05

    compose

    Assemble an output from stream views — map a video and audio stream into one container.

  6. 06

    transcode

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

  7. 07

    remux

    Stream-copy without re-encoding — change container at packet speed, no quality loss.

  8. 08

    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.

Typed filter catalog

Every FFmpeg filter as a typed, final PHP class — axis-checked apply()/generate(), with runnable examples beside the equivalent CLI.

Roadmap

Where this is going.

The destination is frame-level media work at the language level: PHP — and the native CV/ML ecosystem — operating on real frames, with real access to what FFmpeg knows.

Subtitles & multi-track muxing

Map more than one video or audio track — plus subtitle streams — into a single output container.

Frame-level access

Reach individual decoded frames from PHP — work on them in raw PHP, or hand them to ImageMagick, OpenCV, and MediaPipe (sibling extensions) with no serialization.

PHP inside the filter

The constants FFmpeg gives filter expressions (t, n, w, h, text_w…) handed to your PHP callables as live runtime values — not pre-baked expression strings.

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, 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.

And none of this exists without FFmpeg — please support FFmpeg too.

Ready to read the docs?

An Artisan Build project.

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