FFmpeg Media for Drupal

This project is not covered by Drupal’s security advisory policy.

FFmpeg Media converts the videos in Drupal Media with FFmpeg 8 or 9. Uploads stay in Drupal's own Media workflows: Media Library, Media forms and any entity form that embeds a media or file field. After a Media item is saved, queued conversions produce progressive files, HLS and DASH streams, thumbnails and other derived assets, and a player or your own formatter serves them.

The current release is 1.0.0-beta1, a pre-release. It is not covered by Drupal's security advisory policy, and the modules are marked experimental: configuration, admin UI and storage layout may still change. The extension API named in ffmpeg_media.api.php is the exception and keeps its compatibility promise for all of 1.x.

Features

  • Queue-based conversion on Advanced Queue, with a standard and a large-file queue, retry with backoff, a dead-letter list, stuck-process recovery and recovery of conversions whose worker was lost.
  • Conversion profiles as config entities (ffmpeg_media.profile.*): containers, codecs, quality and processors, validated on save and on configuration import. Twelve profiles ship, four of them adaptive with the streaming submodule.
  • Per-field configuration in Manage Display: each video field chooses its own profile and whether new uploads convert automatically. Single Media items can also be converted on demand.
  • 8 codecs: H.264, HEVC, AV1, VP9, VVC (experimental), Apple ProRes, FFV1 and JPEG XL.
  • 7 outputs: MP4, WebM, MKV, FLV and a JPEG XL still of one representative frame; HLS and DASH with the streaming submodule. Live streaming (RTP, WHIP) is not supported.
  • 13 processors: video metadata, audio normalization, multi-language audio tracks and manifests in the base module; thumbnails, GIFs, segment thumbnails and segment GIFs in the image submodule; HDR passthrough or tone mapping to SDR, watermarks, subtitle burn-in and soundtrack normalization in the advanced submodule; Whisper transcription in the Whisper submodule.
  • Hardware acceleration with auto-detection of NVENC, VAAPI, QSV, VideoToolbox, AMF and Vulkan, a circuit breaker, and software fallback that a profile can forbid.
  • Private delivery: outputs under private:// are served only after Drupal checks view access on the owning Media item. Every HLS and DASH playlist, segment and subtitle request is authorized the same way.
  • Subtitles and audio: multi-language WebVTT tracks for HLS and DASH, one embedded HLS subtitle track, and multi-language audio renditions.
  • Third-party players: converted sources and posters are injected into the Video.js and Plyr formatters. Custom formatters use VideoSourceResolverInterface.
  • Operations: status-report checks for FFmpeg, FFprobe, queues, workers and storage; liveness and readiness probes that can require a token; metrics in Prometheus and JSON format; progress endpoints; conversion lifecycle events; 24 Drush commands.

Submodules

Enable only what you need. The base module converts and stores outputs on its own.

  • ffmpeg_media_streaming: HLS and DASH outputs, representation ladders, optional per-title bitrate analysis and GOP alignment.
  • ffmpeg_media_player: a Vidstack player for MP4, WebM, HLS and DASH. Its local mode serves Vidstack, HLS.js and DASH.js from the module without third-party asset requests.
  • ffmpeg_media_ui: admin dashboard, conversion actions, poster selection, progress display and the dead-letter list. Requires ffmpeg_media_image.
  • ffmpeg_media_image: thumbnail, animated GIF, segment-thumbnail and segment-GIF processors.
  • ffmpeg_media_advanced: HDR, two-pass encoding, watermark, subtitle burn-in and normalization processors.
  • ffmpeg_media_whisper: VTT and SRT transcripts with the whisper.cpp CLI (whisper-cli). Transcription runs on your own host; no audio or transcript is sent to an external service. The CLI and model are not bundled.
  • ffmpeg_media_cdn: upload of converted outputs to AWS S3 or an S3-compatible provider, CDN URL rewriting, CloudFront invalidation and remote cleanup. Credentials are read from environment variables, a Key module reference or Drupal's State storage, never from exported configuration.

Requirements

Drupal 11.3 and later 11.x. Drupal 12 is experimental.
PHP 8.5 or later.
FFmpeg FFmpeg and FFprobe 8.x or 9.x on every web, cron and queue-worker host. Not bundled. The shipped software AV1 profiles need an FFmpeg build with libsvtav1.
Database Any database Drupal core supports. Production use is tested on MariaDB and MySQL only.
Advanced Queue 1.7 (~1.7.0), installed by Composer. Always needs the patch that ships in the module's patches/ directory.
Other patches Robo on Drush-based projects; Plyr and Video.js only on sites that run them. Drupal 12 also needs composer-drupal-lenient and a core patch for Symfony 8.1.
Security advisories Not covered. Beta 1 is a pre-release.

Installation

Configure Composer Patches in your root project before requiring the module: Composer applies the Advanced Queue patch while it installs Advanced Queue, so the patch file has to be in your project first. The installation guide has the composer.json entries, the download commands and the SHA-256 checksums of all five patches. Then:

composer require 'drupal/ffmpeg_media:^1.0@beta'
composer patches-relock
composer reinstall drupal/core drupal/advancedqueue --prefer-dist
drush en ffmpeg_media -y
drush cr
drush ffmpeg:status

Check /admin/reports/status afterwards. It reports FFmpeg, FFprobe, queue workers and storage.

Quick start

Two recipes create a ready video media type with auto-conversion and the Vidstack player:

drush recipe web/modules/contrib/ffmpeg_media/recipes/ffmpeg_media_quickstart
drush recipe web/modules/contrib/ffmpeg_media/recipes/ffmpeg_media_streaming_quickstart

The second one also enables HLS streaming. To set up an existing media type instead: choose the Converted Video formatter for its video field in the Default view display, pick a profile and enable auto-convert. Profiles are managed at /admin/config/media/ffmpeg-media/profiles, settings at /admin/config/media/ffmpeg-media.

Conversions run during cron by default. For production, switch queue processing to worker mode and run one supervised drush advancedqueue:queue:process worker per conversion queue; see queue processing.

Updating from an alpha release

Upgrading from an alpha release: update to 1.0.0-beta1 first and run all database updates, then update to the current release. From 1.0.0-beta2 on, the update hooks of the alpha releases are no longer included.

Every published alpha updates directly to Beta 1. Read the upgrade guide first. In short:

  1. Let every FFmpeg Media queue empty, stop cron and the queue workers, and back up the database and output storage.
  2. Configure the patches as above, update the code with Composer, and run drush updb -y.
  3. Restart workers only when drush ffmpeg:output-key-status reports a complete run and an open runtime fence.
  4. Run drush ffmpeg:convert-all. Alphas did not record which conversion produced an output, so the update holds every alpha output and no player serves it until the Media item is converted again. The held files stay on disk.
  5. If the alpha delivered to a CDN, enable ffmpeg_media_cdn; it adopts the existing configuration and queue.
  6. If you manage configuration in git, export it, including core.extension: the update installs Advanced Queue.

Known limitations

  • Hardware encoding was tested with NVIDIA NVENC only.
  • CDN delivery was tested against MinIO only.
  • PostgreSQL and SQLite are untested for production use.
  • The player offers only the formats of the display's profile. MKV, FLV and JPEG XL are stored but not offered for browser playback.
  • Transcriptions run from a Drupal core queue; run it in a supervised worker for long recordings.

The complete list is in the changelog.

Documentation

FFmpeg and codec licensing

The module runs an external FFmpeg binary and bundles no codec. The license of an FFmpeg build and any codec patent obligations depend on that build and on your use; review them for your deployment.

Project information

Releases