tristantbg/kirby-mux

Upload videos directly to mux

Maintainers

Package info

github.com/tristantbg/kirby-mux

Homepage

Type:kirby-plugin

pkg:composer/tristantbg/kirby-mux

Statistics

Installs: 30

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.6.11 2026-06-11 08:52 UTC

This package is auto-updated.

Last update: 2026-06-11 08:52:41 UTC


README

A Kirby plugin to upload video files to Mux.

Installation

Download

Download and copy this repository to /site/plugins/kirby-mux.

Git submodule

git submodule add https://github.com/tristantbg/kirby-mux.git site/plugins/kirby-mux

Composer

composer require tristantbg/kirby-mux

Configuration

Add your Mux API credentials to your Kirby config file:

// site/config/config.php
return [
  'tristantbg.kirby-mux' => [
    'tokenId' => 'XXX', // Your Mux API Access Token ID
    'tokenSecret' => 'XXX', // Your Mux API Secret Key
  ],
];

Options

Option Type Default Description
tokenId String '' Your Mux API Access Token ID
tokenSecret String '' Your Mux API Secret Key
webhookSecret String '' Your Mux webhook signing secret (required for webhooks)
organizationId String '' Your Mux organization id, used to link assets to the Mux dashboard
environmentId String '' Your Mux environment id, used to link assets to the Mux dashboard
dev Boolean false Use a test video instead of the actual upload
optimizeDiskSpace Boolean false Download the low-res MP4 locally and replace the original

Dev Mode

Set dev to true for local development. Instead of the actual video, the plugin will upload a test video to Mux. This is necessary since videos need to be publicly accessible for Mux to import them.

// site/config/config.php
return [
  'tristantbg.kirby-mux' => [
    'tokenId' => 'XXX',
    'tokenSecret' => 'XXX',
    'dev' => true,
  ],
];

Webhooks

The plugin processes Mux assets asynchronously via webhooks instead of polling the Mux API during page rendering. This avoids 429 Too Many Requests rate-limit errors that occur when many videos are rendered or when assets are still encoding.

The plugin exposes a webhook endpoint at:

https://your-domain.com/mux/webhook

This path is provided automatically by the plugin (a Kirby route). However, the webhook itself must be created manually in the Mux dashboard — Mux does not offer an API for managing webhooks, so the plugin cannot create, update, or restore it for you.

Setup (one-time, per environment)

  1. In the Mux dashboard, go to Settings → Webhooks and click Create new webhook.

  2. Select the environment and set the URL to your site's endpoint:

    https://your-domain.com/mux/webhook
    
  3. Copy the webhook signing secret Mux generates and add it to your config:

    // site/config/config.php
    return [
      'tristantbg.kirby-mux' => [
        'tokenId' => 'XXX',
        'tokenSecret' => 'XXX',
        'webhookSecret' => 'XXX', // Mux webhook signing secret
      ],
    ];

When Mux finishes processing an asset (status ready) or its static renditions, it calls the webhook. The plugin verifies the signature, locates the matching Kirby file via the asset passthrough, stores the latest asset data, and saves the thumbnail. The front-end file methods then read only this stored data and never call the Mux API.

Notes & maintenance

  • Public HTTPS required. Mux must be able to reach the endpoint over the internet, so it cannot call localhost. For local development, expose your site with a tunnel (e.g. ngrok or Cloudflare Tunnel) and point the Mux webhook at the tunnel URL.
  • If your domain changes, edit the existing webhook's URL in the Mux dashboard to the new domain. The signing secret stays the same, so webhookSecret does not need to change. The mux/webhook path is relative to the domain and works on whatever domain Kirby is served from.
  • If the webhook is deleted in Mux, it is not recreated automatically. Mux stops sending events, and stored asset data (thumbnails, rendition status) will no longer update. Re-create it in the dashboard to restore the flow.
  • Retries & recovery. Mux retries failed deliveries for ~24h, so brief downtime or a late URL fix usually still delivers queued events. For anything missed beyond that window, re-saving or replacing the affected video re-triggers processing.
  • Assets uploaded before webhooks were configured have no passthrough and are skipped by the handler. Re-saving or replacing those videos attaches the passthrough so future events are handled.

Note: Without a configured webhookSecret and a reachable webhook URL, the stored asset data will not be updated after upload, and static-rendition URLs may not be available until Mux finishes encoding.

Static Renditions

The plugin automatically requests static MP4 renditions at 270p, 720p, and 1080p for every uploaded video.

Panel View

The plugin adds a Mux entry to the Panel menu with an overview of every Mux video file across the site. It is useful for spotting videos whose mux field was never populated (e.g. uploaded before webhooks were configured, or while a webhook was down).

The view shows, for each video:

  • A thumbnail (when a playback id is available)
  • The filename and the page it belongs to
  • The processing status (ready, preparing, errored, or missing when there is no stored Mux data)
  • The static renditions status
  • A button to open the asset in the Mux dashboard (deep-links to the asset when environmentId is configured, otherwise opens the general dashboard)
  • A Refetch button to pull the latest data for a single video directly from the Mux API
  • A button to open the file in the Panel
  • A header filter to show only videos whose renditions are not yet ready
  • A Refresh button to reload the list from the stored data

Videos are sorted by last modification time, newest first.

The list reads stored file data only — it never calls the Mux API, so it does not count against your rate limits.

Refetching missing data

If a video is missing its Mux data (status missing) — for example it was uploaded before webhooks were configured, or while a webhook was down — use the per-row Refetch button to recover it. Refetching makes a direct Mux API call:

  • If the video already has a stored asset id, the latest asset data is pulled and saved. If the asset's static renditions are disabled, they are re-enabled (270p, 720p, 1080p) so the MP4 download URLs become available again.
  • If the video has no Mux data at all, it is re-uploaded to Mux, creating a fresh asset (with the passthrough so future webhooks resolve correctly).

Because refetching calls the Mux API directly, trigger it manually rather than relying on it for normal rendering.

To enable deep links straight to the asset in the Mux dashboard, set your organization id and environment id (otherwise the button opens the general dashboard):

// site/config/config.php
return [
  'tristantbg.kirby-mux' => [
    // …
    'organizationId' => 'XXX', // from your Mux dashboard URL
    'environmentId' => 'XXX', // from your Mux dashboard URL
  ],
];

File Methods

$file->muxPlaybackId()

Returns the Mux playback ID.

$file->muxUrlLow()

Returns the URL to the 270p static MP4 rendition. Reads stored asset data only (no API call); the rendition becomes available once Mux reports it via webhook.

$file->muxUrlHigh()

Returns the URL to the 1080p static MP4 rendition (falls back to 720p if only one rendition file is available). Reads stored asset data only (no API call); the rendition becomes available once Mux reports it via webhook.

$file->muxUrlStream()

Returns the HLS streaming URL (.m3u8).

$file->muxThumbnail($width, $height, $time, $extension)

Returns a Mux thumbnail URL.

Parameter Type Default Description
$width int null Thumbnail width
$height int null Thumbnail height (enables smartcrop)
$time float null Time in seconds for the frame
$extension string jpg Image format (jpg, png, webp)

$file->muxThumbnailAnimated($width, $height, $start, $end, $fps, $extension)

Returns a Mux animated thumbnail URL.

Parameter Type Default Description
$width int null Thumbnail width
$height int null Thumbnail height
$start float null Start time in seconds
$end float null End time in seconds
$fps int null Frames per second
$extension string gif Format (gif or webp)

$file->muxKirbyThumbnail()

Returns a Kirby File object for the Mux thumbnail. Downloads and saves the thumbnail locally on first call.

Hooks

The plugin handles the full lifecycle of video files automatically:

  • file.create:after — Uploads the video to Mux and stores the initial asset data (non-blocking).
  • file.delete:before — Deletes the Mux asset and removes the local thumbnail.
  • file.replace:before — Deletes the old Mux asset.
  • file.replace:after — Uploads the replacement video to Mux.

Thumbnails, static renditions, and optional disk optimization are finalized asynchronously by the webhook once Mux finishes processing.

Blueprints

The plugin provides two blueprints:

  • files/mux-video — File blueprint for Mux video files
  • blocks/mux-video — Block blueprint for embedding Mux videos

Caveats

The plugin does not include any frontend-facing code or snippets. To stream videos from Mux, implement your own video player. HLS.js is a good option.

License

MIT