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
Open → probe → transcode → save
The v1 surface, end to end. Four steps, no surprises.
- 01
open
Eagerly probe a file — container, duration, and typed stream views in one call.
- 02
probe
Read dimensions, codecs, frame rate, sample rate — as real typed, readonly properties.
- 03
transcode
Re-encode or stream-copy, per stream, with codecs chosen as a typed enum.
- 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.
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.