xmon/sonata-media-provider-video-bundle
Integrates a video media provider with Sonata Media, letting you upload, store, and manage video files alongside images in Sonata Admin. It plugs into the existing Sonata Media workflow so video media can be configured, rendered, and handled like other media types.
This bundle predates Symfony Flex and modern Sonata versions, so start by reading its composer.json and README.md to confirm the supported Symfony/Sonata/PHP matrix before installing anything. In most cases you'll be pulling it into a Symfony 2.8/3.x project that already runs sonata-project/media-bundle.
Install alongside Sonata Media:
composer require xmon/sonata-media-provider-video-bundle
The bundle declares a dependency on sonata-project/media-bundle; pin the Sonata version to whatever the bundle's composer.json allows.
Register the bundle (old-style, no Flex recipe):
// app/AppKernel.php
new Xmon\Bundle\SonataMediaProviderVideoBundle\XmonSonataMediaProviderVideoBundle(),
Confirm the exact bundle class name from src/ — naming conventions vary across versions of this bundle.
Configure in Sonata Media — add a video provider block in sonata_media.providers, reusing the file provider's filesystem/CDN/generator/thumbnail services but overriding the class and allowed extensions/mime types (video/mp4, video/quicktime, video/x-msvideo, etc.).
Point at FFmpeg — the bundle reads the FFmpeg binary path (usually from bundle-level config, e.g. ffmpeg_binary: /usr/bin/ffmpeg). Verify the exact key by grepping the bundle for %ffmpeg% or ffmpeg in the Configuration.php and DI extension files.
First use case: create a Media with providerName = 'video' in the Sonata admin, upload an .mp4, and confirm a poster-frame thumbnail appears in the media list. If that works, FFmpeg extraction is wired correctly and you can move on to rendering.
If the bundle doesn't install cleanly on your Symfony version, expect to spend an hour or two forking it — there are no dependents and the last commit is likely several years old.
Extending the file provider. This bundle's core is a subclass of sonata.media.provider.file. Register its service (usually named something like sonata.media.provider.video) in sonata_media.providers.video. Reuse Sonata's filesystem, cdn, generator, and thumbnail services, then override $extensions and $mimeTypes on the provider class.
Poster-frame via FFmpeg. The provider typically runs ffmpeg -i <file> -ss <seconds> -vframes 1 <thumb.jpg> to build the preview thumbnail that Sonata displays in the admin and uses as the media thumbnail. Control the capture second via the provider's thumbnail context option (sonata.media.thumbnail.format accepts a format like reference and context args). Test with a short clip first — long videos slow the admin noticeably.
Metadata extraction. Look for a service or method that shells out to ffprobe (or parses FFmpeg stderr) to populate width, height, duration, codec. These land in the media's provider_metadata JSON, so you can surface them in templates via media.providerMetadata.
Custom Twig formatter. Override or add a formatter that renders an HTML5 <video> tag instead of an <img>:
{% set media = sonata_media_get('video', mediaId) %}
<video controls preload="metadata"
poster="{{ sonata_path(media, 'reference') }}"
src="{{ sonata_path(media, 'reference') }}">
</video>
Register the formatter service and reference it in sonata_media.format so sonata_media_* helpers pick it up for the video provider.
Async processing. FFmpeg calls block the request. For anything beyond toy uploads, push the thumbnail generation into a queue (Sonata NotificationBundle, Enqueue, RabbitMQ, whatever you already run) and let the provider's updateMetadata or a custom listener run out-of-band. This is the biggest deviation from the bundle's defaults and worth doing early.
Admin integration. Use Sonata's default MediaAdmin — the provider appears as an option in the provider dropdown once registered. No admin changes needed, but you'll want to add video/mp4 to the sonata_media bundle-wide allowed_extensions too, otherwise the uploader rejects the file before the provider sees it.
CDN and storage. Because the provider extends the file provider, it inherits the filesystem and CDN choices for free. For S3-backed storage, ensure your Sonata config uses sonata.media.filesystem.s3 and that the CDN service's getPath handles non-public buckets (signed URLs).
which ffmpeg on the running FPM/cron user — not your shell. Missing FFmpeg is the most common "uploads work but no thumbnail" cause. Wrap the exec call and log stderr; the bundle may fail silently.client_max_body_size, PHP upload_max_filesize, post_max_size, max_execution_time, and memory_limit all need to allow the video size you actually accept. Bump them together — Sonata won't show a clear error, just an empty media list..mov or .avi plays in a browser. Do not trust mime-type detection alone — browsers may refuse H.264 vs HEVC vs VP9 differently. If user-facing playback matters, transcode to MP4/H.264/AAC on upload; the bundle does not do this for you, only the poster frame.composer.json (don't rely on dev-master), and be ready to fork and vendor it. Diff against sonata.media.provider.file when things break — you'll often find the upstream class moved and the subclass is silently no-op..file → .file under a new namespace, generator vs. thumbnail service split). If registration fails, run debug:container | grep sonata.media.provider and align the bundle's service names to what's actually registered.Configuration.php is the only source of truth for the FFmpeg path key and any thumbnail defaults. Read it before writing YAML — the README is likely stale.ffprobe -show_format output is stable; parsing human-readable FFmpeg stderr is not. If you fork, replace stderr parsing with ffprobe JSON.(mediaId, format). If you reconfigure the poster frame second, existing thumbnails won't regenerate — clear sonata_media.cache / regenerate via sonata:media:sync-thumbnails (or a manual rm -rf of the thumbnail dir in dev).getCdnPath (signed URLs), a custom formatter for <video> attributes (poster, preload, controls), and a custom ThumbnailInterface when you want HLS/DASH segment thumbnails instead of single-frame posters..mp4 fixture for functional tests. FFmpeg startup cost makes larger fixtures painfully slow in CI, and a missing FFmpeg in the CI image is the fastest way to find out your pipeline depends on it.How can I help you explore Laravel packages today?