PHPackages                             jonasfeige/kirby-bunny-stream - 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. jonasfeige/kirby-bunny-stream

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

jonasfeige/kirby-bunny-stream
=============================

Kirby CMS plugin for Bunny Stream video hosting

1.1.1(1mo ago)03↓50%MITPHPPHP &gt;=8.1

Since Jun 12Pushed 5d agoCompare

[ Source](https://github.com/jonasfeige/kirby-bunny-stream)[ Packagist](https://packagist.org/packages/jonasfeige/kirby-bunny-stream)[ Docs](https://github.com/jonasfeige/kirby-bunny-stream)[ RSS](/packages/jonasfeige-kirby-bunny-stream/feed)WikiDiscussions main Synced 1w ago

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

Kirby Bunny Stream
==================

[](#kirby-bunny-stream)

A Kirby CMS plugin for seamless video hosting via [Bunny Stream](https://bunny.net/stream/).

Features
--------

[](#features)

- **Automatic upload** – Videos are uploaded to Bunny Stream when added to the Panel
- **Direct upload** – Optional browser-to-Bunny uploads via TUS protocol for large files (bypasses PHP limits)
- **Panel preview** – Custom file preview shows embedded player when ready, processing status otherwise
- **Lazy status polling** – Automatically checks encoding status without requiring webhooks
- **HLS streaming** – Serve adaptive bitrate video via Bunny's global CDN
- **Custom thumbnails** – Override auto-generated thumbnails with your own images
- **Extensible blueprints** – Add custom fields while keeping core functionality

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

[](#requirements)

- Kirby 5.0+
- PHP 8.1+

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

[](#installation)

### Composer (recommended)

[](#composer-recommended)

```
composer require jonasfeige/kirby-bunny-stream
```

### Manual

[](#manual)

Download and extract to `site/plugins/kirby-bunny-stream`.

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

[](#configuration)

Add to your `site/config/config.php`:

```
return [
    'jonasfeige.kirby-bunny-stream' => [
        'apiKey' => 'your-bunny-api-key',       // Required
        'libraryId' => 'your-library-id',        // Required
        'cdnHostname' => 'vz-xxx.b-cdn.net',     // Required: from Bunny dashboard
        'webhookSecret' => null,                 // Optional
        'collection' => 'site',                  // 'site' or 'page'
    ],
];
```

### Options

[](#options)

OptionTypeDefaultDescription`apiKey`string`null`Bunny Stream API key (required)`libraryId`string`null`Video library ID (required)`cdnHostname`string`null`CDN hostname from Bunny dashboard (required)`webhookSecret`string`null`Webhook signature verification secret`collection`string`'site'`Video organization: `'site'` or `'page'`Bunny Security Settings
-----------------------

[](#bunny-security-settings)

The plugin fetches video thumbnails directly from Bunny's CDN. Depending on your Bunny library's security settings, you may need to configure access.

### Recommended Setup

[](#recommended-setup)

In your Bunny Stream dashboard, go to your library settings and configure:

#### Option 1: Disable direct URL blocking (simplest)

[](#option-1-disable-direct-url-blocking-simplest)

- Set **"Block direct url file access"** to **OFF**

This allows thumbnails to load from any source. Videos are still protected by Bunny's standard security.

#### Option 2: Allow your domains (more restrictive)

[](#option-2-allow-your-domains-more-restrictive)

- Keep **"Block direct url file access"** **ON**
- Add your domains to **"Allowed domains"**:
    - `yourdomain.com` (production)
    - `*.yourdomain.com` (subdomains)
    - `localhost` (local development)

This restricts thumbnail access to requests originating from your domains.

### Not Supported

[](#not-supported)

The plugin does **not** currently support:

- **CDN token authentication** (signed URLs)
- **Embed view token authentication**

If you enable these features in Bunny, thumbnails will not load in the Panel or on your frontend.

Usage
-----

[](#usage)

### Adding Videos

[](#adding-videos)

Create a files section in your page blueprint:

```
sections:
  videos:
    type: files
    template: bunny-video
    label: Videos
```

Upload a video and it will automatically be sent to Bunny Stream. The original file is replaced with a small placeholder while Bunny handles storage and delivery.

### Direct Upload (Large Files)

[](#direct-upload-large-files)

For large files that exceed PHP upload limits, use the direct upload section. This uploads directly from the browser to Bunny via the TUS protocol, bypassing your server entirely.

Add to your page blueprint:

```
sections:
  video-upload:
    type: bunny-video-upload
    label: Upload Video
    help: Supports files up to 10GB

  videos:
    type: files
    template: bunny-video
    create: false  # Disable standard upload
```

Both upload methods produce identical results – use whichever suits your needs:

MethodBest forUpload pathStandard (files section)Small files, familiar UXBrowser → Server → BunnyDirect (bunny-video-upload)Large files (100MB+)Browser → Bunny (TUS)### Custom Thumbnails

[](#custom-thumbnails)

The default blueprint includes a `customthumbnail` field. Upload an image to override Bunny's auto-generated thumbnail. The `bunnyThumbnail()` method automatically returns the custom thumbnail if set.

### Selecting Videos

[](#selecting-videos)

Use the preset field to select only videos that have finished encoding:

```
fields:
  video:
    extends: fields/bunnyvideo
    label: Select Video
```

Or use a standard files field:

```
fields:
  video:
    type: files
    query: page.files.template("bunny-video")
    max: 1
```

### Filtering by Status

[](#filtering-by-status)

Filter videos by encoding status in blueprints:

```
# Only ready videos
query: page.files.template("bunny-video").filter(file => file.isBunnyReady)

# Only processing videos
query: page.files.template("bunny-video").filter(file => file.isBunnyProcessing)
```

Or in PHP:

```
// Get ready videos from current page
$readyVideos = $page->bunnyVideos();

// Get all videos including processing ones
$allVideos = $page->bunnyVideos(readyOnly: false);

// Manual filtering
$videos = $page->files()->template('bunny-video');
$ready = $videos->filter(fn($f) => $f->isBunnyReady());
$processing = $videos->filter(fn($f) => $f->isBunnyProcessing());
```

### In Templates

[](#in-templates)

```
