PHPackages                             buesing/craft-streaming-video - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Image &amp; Media](/categories/media)
4. /
5. buesing/craft-streaming-video

ActiveCraft-plugin[Image &amp; Media](/categories/media)

buesing/craft-streaming-video
=============================

Create and view streaming videos using HLS

1.0.4(5mo ago)2241proprietaryPHPPHP &gt;=8.2

Since Aug 20Pushed 5mo ago1 watchersCompare

[ Source](https://github.com/buesing/craft-streaming-video)[ Packagist](https://packagist.org/packages/buesing/craft-streaming-video)[ RSS](/packages/buesing-craft-streaming-video/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (2)Versions (6)Used By (0)

Craft Streaming Video Plugin
============================

[](#craft-streaming-video-plugin)

A Craft CMS plugin that automatically generates HLS (HTTP Live Streaming) variants for video assets, enabling adaptive streaming with multiple quality levels.

The plugin handles generating the variants, and includes a basic template that renders the video using [hls.js](https://github.com/video-dev/hls.js/). It doesn't apply any styling to the video, that is left up to the developer. You can also use GraphQL to handle the entire frontend yourself.

This plugin is useful for websites hosting longer videos, which don't want to use video services to embed videos due to privacy or design concerns.

Features
--------

[](#features)

- 🎥 **Automatic HLS Generation**: Converts uploaded videos to HLS format with multiple quality variants
- 📱 **Adaptive Streaming**: Automatically switches quality based on viewer's bandwidth and device
- 🎛️ **Multiple Quality Levels**: Generates 1080p, 720p, 480p, 240p, and 144p variants (plus source quality)
- 📐 **Aspect Ratio Preservation**: Maintains original video proportions for any format (not just 16:9)
- 🔧 **Smart Resolution Detection**: Only generates variants at or below the source video resolution
- 🌐 **Cross-Platform Storage**: Works with local storage, AWS S3, and other Craft volume types
- 🎮 **Frontend Integration**: Includes Twig template and GraphQL support

Requirements
------------

[](#requirements)

- Craft CMS 5.0 or later
- PHP 8.2 or later
- FFmpeg installed on the server

Installation
------------

[](#installation)

### 1. Install the Plugin

[](#1-install-the-plugin)

```
# Via Composer
composer require buesing/craft-streaming-video

# Install via Craft CLI
php craft plugin/install streaming-video
```

### 2. Install FFmpeg

[](#2-install-ffmpeg)

The plugin requires FFmpeg to be installed on your server.

#### DDEV

[](#ddev)

Add to your `.ddev/config.yaml`:

```
webimage_extra_packages:
  - ffmpeg
```

Then restart DDEV:

```
ddev restart
```

#### Other Environments

[](#other-environments)

- **Ubuntu/Debian**: `sudo apt-get install ffmpeg`
- **CentOS/RHEL**: `sudo yum install ffmpeg`
- **macOS**: `brew install ffmpeg`
- **Docker**: Include FFmpeg in your container image

### 3. Make sure CORS is enabled

[](#3-make-sure-cors-is-enabled)

If assets are hosted on another origin than the main site, ensure CORS access is properly configured for HLS streaming to work.

How It Works
------------

[](#how-it-works)

1. **Upload Detection**: When a video asset is uploaded or saved, the plugin automatically detects it
2. **Queue Processing**: An HLS preparation job is queued to avoid blocking the upload
3. **Quality Generation**: FFmpeg generates multiple quality variants based on the source resolution. During generation, the template falls back to the normal video file. hlsPlaylistUrl will return `null` during that time.
4. **File Storage**: HLS files are stored in a separate `__hls__/{asset-uid}/` folder in the same volume
5. **Cleanup**: When an asset is deleted, all associated HLS files are automatically removed

Usage
-----

[](#usage)

### Frontend Templates

[](#frontend-templates)

#### Basic Video Player

[](#basic-video-player)

```
{% set video = entry.video.one() %}
{% if video and video.hlsPlaylistUrl %}
    {% include '_streamingvideo/player.twig' with { asset: video } %}
{% else %}

{% endif %}
```

#### All Player Options

[](#all-player-options)

The player template supports the following options:

OptionTypeDefaultDescription`asset`Asset—The Craft Asset element (required)`controls`booltrueShow the video controls`autoplay`boolfalseAutoplay the video`muted`boolfalseMute the video`loop`boolfalseLoop the video`playsinline`boolfalsePlay inline on mobile devices`poster`Asset or stringnullCraft Asset (uses its URL) or a URL string for the poster image`classname`string''CSS class(es) for the video element`disablepictureinpicture`boolfalseDisable Picture-in-Picture button`id`stringrandomThe video element's ID (random if not provided)**Example:**

```
{# Using a Craft Asset as poster #}
{% include '_streamingvideo/player.twig' with {
  asset: entry.video.one(),
  poster: entry.posterImage.one(),
  autoplay: true,
  muted: true,
  loop: false,
  playsinline: true,
  classname: 'rounded shadow',
  disablepictureinpicture: true,
  id: 'my-custom-video-player'
} %}

{# Using a URL as poster #}
{% include '_streamingvideo/player.twig' with {
  asset: entry.video.one(),
  poster: 'https://example.com/poster.jpg'
} %}
```

### Template

[](#template)

If you need more customization, you can copy paste this simple template as a starting point:

```
{% set asset = entry.video.one() %}

  {% if asset.hlsPlaylistUrl %}

  {% else %}

  {% endif %}
  Your browser does not support the video tag.

{% if asset.hlsPlaylistUrl %}

{% endif %}

  {% if asset.hlsPlaylistUrl %}
    document.addEventListener('DOMContentLoaded', function() {
      var video = document.getElementById('video');
      if (video.canPlayType('application/vnd.apple.mpegurl')) {
        // HLS is natively supported (Safari)
        video.src = "{{ asset.hlsPlaylistUrl }}";
      } else if (window.Hls && Hls.isSupported()) {
        // HLS.js is supported
        var hls = new Hls();
        hls.loadSource("{{ asset.hlsPlaylistUrl }}");
        hls.attachMedia(video);
      } else {
        console.error('HLS is not supported in this browser');
      }
    });
  {% else %}
    // Video hasn't finished rendering
  {% endif %}

```

### GraphQL

[](#graphql)

The plugin adds an `hlsPlaylistUrl` field to the Asset GraphQL type:

```
query {
  entries {
    ... on MySection {
      videoField {
        url
        hlsPlaylistUrl
        title
      }
    }
  }
}
```

The field will only be available once all variants have finished rendering. Until then, you can show a fallback or the original video.

### Checking Stream Availability

[](#checking-stream-availability)

```
{% set video = entry.video.one() %}
{% if video.canStreamVideo %}
    This video supports streaming
    {% if video.hlsPlaylistUrl %}
        HLS streaming is available
    {% else %}
        HLS encoding in progress...
    {% endif %}
{% endif %}
```

Configuration
-------------

[](#configuration)

### Quality Variants

[](#quality-variants)

The plugin generates the following quality variants by default:

QualityResolutionVideo BitrateAudio BitrateSourceOriginal8000k192k1080p1920×10805000k128k720p1280×7203000k128k480p854×4801500k96k240p~427×240800k64k144p~256×144400k64k*Note: Only variants with resolution ≤ source video are generated*

### Processing Existing Videos

[](#processing-existing-videos)

If you're adding this plugin to an existing site with video assets, you'll need to resave all existing video assets to trigger HLS conversion:

```
# Standard Craft installation
php craft resave/assets

# Using DDEV
ddev craft resave/assets
```

This will process all existing video assets and generate HLS streaming variants in the background.

Warning

Depending on how many videos you have saved, and how long they are, this can take a long time and use a lot of hard drive space. Make sure to monitor your hard drive when resaving assets.

Troubleshooting
---------------

[](#troubleshooting)

### FFmpeg Not Found

[](#ffmpeg-not-found)

**Error**: `ffmpeg: not found`

**Solution**: Install FFmpeg on your server (see Installation section above)

### Permission Issues

[](#permission-issues)

**Error**: `Failed to create temp directory`

**Solution**: Ensure the web server has write permissions to Craft's temp directory

### Large File Processing

[](#large-file-processing)

For very large video files, you may need to:

1. Increase PHP memory limit: `ini_set('memory_limit', '1G')`
2. Increase max execution time: `ini_set('max_execution_time', 0)`
3. Configure your queue system for long-running jobs

### Debug Information

[](#debug-information)

Check Craft's logs at `storage/logs/queue.log` for detailed processing information:

```
# Follow logs in real-time
tail -f storage/logs/* | grep streamingvideo
```

License
-------

[](#license)

This plugin is licensed under the Craft License.

Support
-------

[](#support)

For issues and feature requests, please use the GitHub issue tracker.

###  Health Score

40

—

FairBetter than 87% of packages

Maintenance77

Regular maintenance activity

Popularity13

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~26 days

Total

5

Last Release

158d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/440541de88044f7ff988d8ac378e6454ad5cdf6be463dd0ffa20c0227017e829?d=identicon)[mbus](/maintainers/mbus)

---

Top Contributors

[![buesing](https://avatars.githubusercontent.com/u/1181371?v=4)](https://github.com/buesing "buesing (25 commits)")

---

Tags

streamingvideooptimizationhls

### Embed Badge

![Health badge](/badges/buesing-craft-streaming-video/health.svg)

```
[![Health](https://phpackages.com/badges/buesing-craft-streaming-video/health.svg)](https://phpackages.com/packages/buesing-craft-streaming-video)
```

###  Alternatives

[happyworm/jplayer

jPlayer allows you to create a media player with a consistent interface and experience across all browsers.

4.6k114.2k1](/packages/happyworm-jplayer)[opentok/opentok

OpenTok is a platform for creating real time streaming video applications, created by TokBox.

1413.0M10](/packages/opentok-opentok)[aminyazdanpanah/php-ffmpeg-video-streaming

📼 PHP FFMpeg - Video Streaming - DASH, HLS http://video.aminyazdanpanah.com

542275.0k8](/packages/aminyazdanpanah-php-ffmpeg-video-streaming)[mostafaznv/nova-video

Video Field for Laravel Nova

22398.0k1](/packages/mostafaznv-nova-video)[aminyazdanpanah/php-shaka

Shaka PHP is a library that uses Shaka Packager for DASH and HLS packaging and encryption, supporting Common Encryption for Widevine and other DRM Systems.

939.0k1](/packages/aminyazdanpanah-php-shaka)[mehrdad-dadkhah/hls-video-generater

PHP library for generating video m3u8 playlist

241.4k](/packages/mehrdad-dadkhah-hls-video-generater)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
