The ffmpeg-php extension is dead. What to use on PHP 8.4 instead

The ffmpeg-php extension does not build on PHP 8, and no newer version of it exists to try: the last release was 0.6.3 in March 2009, and the libavcodec struct members its C code reads were deprecated and then deleted upstream. If you landed on the SourceForge page or a phpize && make install walkthrough, here is what to do instead on PHP 8.4.
- Replace
ffmpeg_moviemetadata calls (getDuration(),getFrameWidth(),getFrameRate()) withffprobe -print_format json, or with one POST to a hosted ffprobe endpoint if you have no binary. - Replace
$movie->getFrame()and theffmpeg_frameclass with a single-frame extraction (ffmpeg -ss T -frames:v 1) or a thumbnail job. - Use char0n/ffmpeg-php if you want the old class names back in pure PHP, knowing it shells out and still needs
ffmpeg/ffprobeon PATH. - Use PHP-FFMpeg if you're rewriting the calls anyway and can install both binaries on the box.
- Call an HTTP video API from PHP if
execandshell_execare indisable_functions, which is the default on most cPanel and Plesk shared hosting.
Where the extension actually died, and it was two places at once
ffmpeg-php stopped working for two independent reasons, which is why no amount of --with-ffmpeg= flag tuning rescues it. Both have to be true for the extension to compile, and neither is anymore.
The FFmpeg side is the harder wall. The extension reads AVCodecContext->codec_name and sub_id and calls av_free_packet() and av_picture_copy(). Building it against a current FFmpeg fails with error: 'AVCodecContext' has no member named 'codec_name', which is issue #25 on the tony2001 fork that most install guides tell you to clone. Those members and the old encode/decode entry points were deprecated for years and then removed from libavcodec in a 2021 patch series. There is no header to point at that still has them unless you keep a 2015-era FFmpeg around, which puts you on an unpatched media decoder on purpose.
The PHP side is simpler. SourceForge's release listing shows 0.6.0 in 2008 and 0.6.3 in March 2009, written against the PHP 5 internals API. PHP 8.4 shipped on 21 November 2024, and even PHP 8.1 went end of life on 31 December 2025. You are not one upgrade away from this extension working. You are four major versions and seventeen years away.
Control-panel hosts never offered a way out either. The standing answer on Plesk's own forum is that there is no ffmpeg PHP extension to enable and you should install the system ffmpeg tools and widen open_basedir instead, discussed here in the Plesk community. Meanwhile cPanel admins were still being walked through rebuilding the extension per PHP version on WebHostingTalk years after upstream had gone quiet. The forum threads treat it as a configuration problem. It's a dependency problem.
pecl install ffmpeg isn't a command you should be reaching for either
The channel every one of those guides points at is itself on the way out. The PHP RFC "Recommend PIE and deprecate PECL" passed 36 ayes, 0 nays, 5 abstentions, with the vote opening in early September 2025, after a discussion thread on php.internals dated 20 August 2025. PECL's tooling and website keep working and now carry deprecation messaging; PIE is the recommended installer for non-bundled extensions going forward.
PIE does not give you an escape hatch here. It's a Composer-style PHAR that needs PHP 8.1+ to run, installs extensions by Composer package name (pie install vendor/ext), and can target another installed PHP with --with-php-config. There is no pie install ffmpeg, because nobody packaged a replacement for an extension that can't compile. The migration path for pecl install ffmpeg is "stop installing an extension."
Your old calls, line by line, and what to run instead
Every ffmpeg_movie method in the original API docs maps onto something ffprobe already returns, which is why this port is mechanical rather than a redesign. The one real change in shape is that you get a JSON document back once instead of calling a method per field.
| Old ffmpeg-php call | What it gave you | Replacement on PHP 8.4 |
|---|---|---|
| `new ffmpeg_movie($path)` | A handle to probe | One `ffprobe -print_format json -show_format -show_streams` run, or one `POST /v1/ffprobe` |
| `getDuration()` | Seconds, float | `format.duration` |
| `getFrameWidth()` / `getFrameHeight()` | Pixels | `streams[].width` / `streams[].height` on the video stream |
| `getFrameRate()` | FPS | `streams[].r_frame_rate`, a rational like `"30/1"`, so divide it |
| `getFrameCount()` | Integer | `streams[].nb_frames`, which some containers omit; fall back to duration times frame rate |
| `getVideoCodec()` / `getAudioCodec()` | Codec string | `streams[].codec_name` (`h264`, `aac`) |
| `getFrame($n)` returning `ffmpeg_frame` | A decoded frame | `ffmpeg -ss T -i in.mp4 -frames:v 1 -q:v 2 out.jpg`, or a thumbnail job |
| `$frame->toGDImage()` | A GD resource | `imagecreatefromjpeg()` on the extracted still |
On a server where you control the binaries, the metadata half is one command:
ffprobe -v error -print_format json -show_format -show_streams input.mp4
Where exec() is blocked or the binary isn't there, the same read is an HTTP request, and the response has the same streams and format keys you just mapped against:
$ch = curl_init('https://api.ffmpeg-micro.com/v1/ffprobe');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('FFMPEG_MICRO_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'media_url' => 'https://cdn.example.com/input.mp4',
]),
]);
$probe = json_decode(curl_exec($ch), true);
$video = current(array_filter(
$probe['streams'],
fn ($s) => $s['codec_type'] === 'video'
));
$duration = (float) $probe['format']['duration']; // was getDuration()
$width = (int) $video['width']; // was getFrameWidth()
[$num, $den] = explode('/', $video['r_frame_rate']);
$fps = $num / max(1, (int) $den); // was getFrameRate()
That's the shape the ffprobe API reference documents, and there's a first-party PHP package on Packagist (ffmpeg-micro/ffmpeg-micro-php, PHP 8.1+) if you'd rather composer require it than hand-roll curl. The reason this matters for PHP specifically: transcodes are submitted as a job and polled, so a four-minute encode doesn't have to survive a 60-second PHP-FPM request. We walked through that pattern for hosts that disable process functions in shell_exec has been disabled. Run FFmpeg jobs from PHP anyway.
Pick a wrapper instead if you own the box. char0n's FFmpegPHP is a PSR-4 pure-PHP port that keeps Movie, getDuration() and frame extraction intact and calls the original extension unmaintained and obsolete in its own README; it needs PHP 7 or newer plus gd, mbstring and xml, documents support up to PHP 8.0.x, and still requires ffmpeg or ffprobe on the machine. PHP-FFMpeg is the better-maintained choice (PHP 8.0+, with recent releases adding PHP 8.4 and 8.5 and Symfony 8) and autodetects both binaries, but it is a different API, so you're rewriting the calls either way. Neither is the right answer if your host blocks exec, and neither answers the question of who patches your FFmpeg build when a CVE ships without a release, which is a live problem right now: see FFmpeg CVE October 2026: no patch exists. Contain them instead..
What each route actually costs you
The three options have very different bills, and only one of them has a number you can read off a page before you start. Here's the breakdown for the common case, a PHP app that needs duration, dimensions and a poster frame per upload.
Compiling the extension: unbounded, and the ceiling is zero. You'll spend an evening on php-devel, gcc, phpize and FFmpeg headers before you reach has no member named 'codec_name', and then a second evening deciding whether to pin an ancient FFmpeg. Multiply by every PHP minor version you upgrade through, which is what the cPanel threads are documenting.
A wrapper plus your own binaries: roughly an hour to install, then ongoing. You own an FFmpeg build, a writable temp path, a queue worker that can outlive a web request, an open_basedir exception, and a patch cadence that isn't yours to set. Two of our recent posts exist only because that cadence moves: FFmpeg 9.1: what to re-test before you upgrade is the short version.
The API: $0 to start and metered per second after. A new account gets 200 tokens with no card, API access, unlimited API keys and unlimited storage. One token buys 10 seconds of input video, metered per second with no rounding up to the minute, so 200 tokens is about 33 minutes of video. A 90-second clip costs 9 tokens. Trim 30 seconds out of an hour-long recording and you're billed for 30 seconds, not the hour. Checking job status, listing jobs and downloading outputs cost nothing, and failed jobs are never billed. If you outgrow the free grant, Starter is $19.99 a month for 2,500 tokens and Pro is $49.99 for 7,000, with top-ups at 500 tokens for $5 on any plan including Free.
Where the API is the wrong call: if you need in-process pixel access on every frame, if you're running air-gapped, or if you already maintain a build server and a media queue for other reasons, keep PHP-FFMpeg and the binaries. The trade you're making by calling out is a network hop and an upload per file.
FAQ
Can I install ffmpeg-php on PHP 8.4 at all?
No version of ffmpeg-php installs on PHP 8.4. The extension's last release was 0.6.3 in March 2009 against the PHP 5 internals API, and its C code references libavcodec struct members that FFmpeg removed in 2021, so the build fails before it reaches a PHP compatibility problem.
Is char0n/ffmpeg-php a true drop-in replacement for the extension?
char0n/ffmpeg-php is a drop-in at the class level and not at the dependency level. It keeps the Movie and frame-extraction shape in pure PHP so your call sites mostly survive, but it shells out to ffmpeg and ffprobe, which means you still need both binaries installed and a PHP that is allowed to run exec().
Why can't cPanel or Plesk just enable an ffmpeg PHP extension for me?
Control-panel hosts have no ffmpeg PHP extension to enable, because the only one that ever existed is a dead PECL package that will not compile against current FFmpeg or current PHP. Plesk's own forum advice is to install the system ffmpeg command-line tools and adjust open_basedir, not to look for an extension.
What replaces $movie->getFrame() for generating thumbnails?
Single-frame extraction replaces $movie->getFrame() and the ffmpeg_frame class. On a server with the binary, ffmpeg -ss 5 -i input.mp4 -frames:v 1 -q:v 2 thumb.jpg writes the frame at five seconds; from PHP without a binary, submit a thumbnail job and download the JPEG when the job reports completed.
Does pecl install ffmpeg still work?
pecl install ffmpeg does not produce a working extension, and PECL itself is now deprecated: the RFC recommending PIE and deprecating PECL passed 36 to 0 with 5 abstentions in September 2025. PIE installs extensions by Composer package name, and there is no ffmpeg extension published for it.
Seventeen years of phpize threads is a long time to spend on a dependency that deleted its own API. Going from a dead .so to a working key takes one sign-up: the quickstart creates a temporary API key in the dashboard and runs presigned upload, transcode, poll and download for you, with the matching request and response shown at each step. Sign up free and the 200 tokens, about 33 minutes of video, are enough to port your getDuration() and getFrame() calls and still have budget left: no servers to run, no FFmpeg to install, callable from your PHP code, from n8n, Make and Zapier, or from your AI agents.
About Javid Jamae
Founder & CEO at FFmpeg Micro
Javid is a software engineer, author, and entrepreneur with over 25 years of professional software development experience across enterprise, startup, and consulting environments. He founded FFmpeg Micro to make video processing accessible to developers through a simple, automation-first REST API.
You might also like

shell_exec has been disabled. Run FFmpeg jobs from PHP anyway
shell_exec has been disabled for security reasons? Why removing one entry won't help, why PHP-FFMpeg fails, and how to encode video from PHP with no shell.

The FFmpeg Brotli CVE has no patch. Block it at ingest instead.
The ffmpeg Brotli CVE (CVE-2026-111497) reaches FFmpeg through libjxl and JPEG XL brob boxes. How to check your build and what to block at ingest right now.

FFmpeg CVE October 2026: no patch exists. Contain them instead.
FFmpeg CVE October 2026: CVE-2026-107676 and CVE-2026-107678 fire on the uploaded file, and no patched release exists. The mitigations that work today.
Ready to process videos at scale?
Start using FFmpeg Micro's simple API today. No infrastructure required.
Get Started Free