# Introducing mod_bunnystream: Modern Video for Moodle

https://cubite.io/blogs/moodle-bunnystream-plugin-modern-video-pipeline

**By:** Amir Tadrisi
**Updated:** 2026-05-14

A 1GB video adds 1GB to every Moodle backup. The Moodle Bunny Stream plugin moves video to Bunny.net with completion tracking, gradebook, and mobile support.

# Introducing mod_bunnystream: Stop Bloating Your Moodle Backups

A 1GB video uploaded to Moodle adds approximately 1GB to every Moodle backup — every time it runs. Across a course catalog with a dozen lectures and weekly backups, that math compounds fast: bigger backups, longer restore windows, full disks, and on MoodleCloud, a hard 250MB upload cap that stops you at the door.

Today we're releasing the Moodle Bunny Stream plugin (mod_bunnystream) — a GPL-v3 open-source Moodle activity module that moves video out of Moodle entirely. Teachers upload directly from Moodle to Bunny.net Stream via TUS. Bunny does the encoding. Your Moodle storage stays lean. Completion tracking, gradebook integration, captions, chapters, and native mobile-app support come with it.

This article walks through the Moodle video pain that's been quietly compounding for years, what the plugin ships in v0.1.0, how it compares to Video Time / Panopto / Kaltura, and how to install it in five steps on Moodle 4.5 LTS through 5.2.

---

## What Moodle Operators Have Been Doing Instead

If you've run Moodle at any scale, you've tried at least one of these. Each is a real choice with real trade-offs.

| Approach | Setup cost | Bypasses 250MB cap | Backup-lean | Completion + gradebook | Cost at scale |
| --- | --- | --- | --- | --- | --- |
| Native Moodle upload | Zero | No | No — bloats | Native | Storage + backup costs grow forever |
| YouTube unlisted embed | Zero | Yes (external) | Yes | No native integration | Free, but no DRM, ad/brand bleed |
| Vimeo + Video Time plugin | Low | Yes (external) | Yes | Partial (Video Time Pro is paid) | Vimeo pricing escalates fast |
| Panopto / Kaltura / MediaSite | Medium | Yes | Yes | Yes (enterprise-grade) | High — enterprise pricing |
| **mod_bunnystream** | **5 steps** | **Yes** | **Yes** | **Native + gradebook** | **Bunny pay-as-you-go (~$0.005/GB delivery)** |

Honest reads on each:

Native upload is what most courses ship with by default. It works until your storage bill or your backup window forces a conversation.

Video Time is solid — used on more than 1,000 sites and a fine pick if your videos already live on Vimeo. The Pro tier adds tracking, resume, channels, and deeper Vimeo integration, but that's a separate cost on top of Vimeo's own.

Panopto, Kaltura, MediaSite are full enterprise video platforms with their own pipelines, analytics, and pricing. If your institution already has one, integrating it with Moodle is the right play. If not, the licensing is a meaningful line item.

mod_bunnystream is a different category from any of the above. Upload-and-encode native to the Moodle activity form, Moodle-native completion + gradebook, native mobile-app support — and Bunny's pay-as-you-go economics underneath. It's the right pick when you want a coherent integrated path on a small-or-medium Moodle deployment without enterprise procurement.

---

## What mod_bunnystream Ships And What Bunny Adds Underneath

This is the section where being precise matters most. The plugin is noticeably richer than a simple embed module — completion tracking, gradebook integration, mobile-app templates, and the full captions/chapters UI all live in the plugin itself, not in Bunny. Bunny supplies what video platforms supply: encoding, DRM, captions generation, global delivery.

In the plugin (GPL-v3, ships from us):

- Direct TUS upload to Bunny — teachers upload directly from the Moodle activity form via the TUS resumable upload protocol. The bytes never touch Moodle storage, which is exactly what solves the backup-bloat and MoodleCloud-cap problems at their root.
- Encoding-status webhooks — with triple-layer authentication: constant-time secret matching, library-mismatch guards, and lifecycle regression checks.
- Custom thumbnails — upload alternative thumbnail images per video.
- Subtitle and caption support — attach .vtt subtitle files directly from the Moodle activity form.
- Auto-transcription trigger — fire Bunny's automated transcription service from inside the plugin; captions return as VTT files attached to the video.
- Chapter markers — define and manage chapter breakpoints within videos.
- Token authentication — every embed URL is SHA-256-signed with a 6-hour TTL. Cross-origin requests return 401.
- Native Moodle Mobile app support — a custom Ionic template ships with the plugin so users of the native Moodle app get a real video player, not a degraded fallback.
- Completion tracking — configurable percentage-watched threshold (default 90%). The player listens to Bunny's postMessage events (timeupdate, ended) in real time, so completion fires the moment the threshold is hit, not at page reload.
- Gradebook integration — reports watched percentage (0–100) to the Moodle gradebook automatically.
- libsodium AEAD credential encryption — Bunny API Key and Security Key are encrypted at rest using authenticated encryption.
- Single library per instance — centralized config in the mdl_bunnystream_config table.

From Bunny.net Stream (configured in the Bunny dashboard, applied automatically):

- Adaptive bitrate HLS encoding — multiple resolutions, free, automatic.
- MediaCage anti-download DRM — Bunny's free baseline DRM (Bunny MediaCage docs).
- Enterprise multi-DRM — Widevine, FairPlay, PlayReady (premium plans).
- Domain allowlist / referrer restrictions — Bunny pull-zone hotlink-protection settings (security options).
- Dynamic watermarking — overlays a learner identifier as a forensic deterrent (premium).
- Global delivery — 119 PoPs, 250 Tbps backbone, $0.005/GB delivery, $0.01/GB storage, free encoding (bunny.net/stream).

---

## How It Looks for Teachers and Learners

Two flows, both invisible-by-design. The teacher experience is the headline UX win.

Teacher flow (Moodle activity authoring):

- Add Bunny credentials to the site administration

- Add a "Bunny Stream" activity to a course section.

- Drag a video file into the activity form (or use the file selector).

- Real-time progress bar fills as bytes stream directly to Bunny. The status reads "Bunny is processing…" while encoding runs.

- Status flips to ready: the post-encoding form shows the generated thumbnail, lets the teacher upload a custom thumbnail or .vtt captions, define chapters, set the completion threshold, and configure the gradebook entry — all without leaving the form.

Learner flow (web and mobile app):

- Course page loads the activity. The signed iframe renders the Bunny player.

- As the learner watches, the plugin captures Bunny postMessage events in real time. When watched percentage crosses the configurable threshold (default 90%), completion fires and the gradebook entry updates — all automatically, no page reload required.
- Native Moodle Mobile app users get a proper player via the plugin's Ionic template — not a degraded webview fallback.

That's the entire experience. No external dashboard. No copy-paste iframe URLs. No "go to YouTube to set captions". The teacher does everything from inside the Moodle activity form; the learner gets a real player with real completion tracking.

---

## How to Install mod_bunnystream on Your Moodle Site

Five steps. The plugin is a standard Moodle activity module — if you've installed anything from GitHub into /mod/ before, this will be familiar.

Step 1 — Clone the repository into Moodle's /mod/ directory:

```bash
git clone https://github.com/amirtds/moodle-mod_bunnystream.git \
  /path/to/moodle/mod/bunnystream
```

Step 2 — Run the Moodle upgrade to register the plugin:

php admin/cli/upgrade.php --non-interactive

Step 3 — Configure credentials at Site administration → Plugins → Activity modules → Bunny Stream. You'll need:

- Library ID — Bunny: Stream → Library → API
- API Key — Bunny: Stream → Library → API
- Security Key — Bunny: Stream → Library → Security (requires Token Authentication enabled in Bunny)
- CDN Hostname — Bunny: Stream → Library → API → Pull Zone Hostname

Credentials are encrypted at rest with libsodium AEAD before being stored in mdl_bunnystream_config.

Step 4 — Register the webhook in Bunny. Copy the webhook URL shown in the plugin admin page, then in your Bunny dashboard go to Stream → Library → Webhooks and paste it in. This is what flips activity status from "Bunny is processing…" to ready.

Step 5 — Smoke test. Create a course, add a Bunny Stream activity, upload a 30-second test clip, and verify:

- Upload progress fills inside the activity form
- Status transitions to ready within a couple minutes
- The signed iframe renders on the learner-facing page
- A curl of the iframe URL from an unauthorized origin returns 401
- Playing past the completion threshold marks the activity complete and updates the gradebook

Compatibility: Moodle 4.5 LTS, 5.0, 5.1, and 5.2 — every actively-supported Moodle release as of May 2026. PHP 8.1+.

---

## FAQ

### What is the mod_bunnystream plugin for Moodle?

mod_bunnystream is a GPL-v3 open-source Moodle activity module from Cubite that integrates Bunny.net Stream into Moodle. It ships direct TUS upload, signed-URL token authentication, custom thumbnails, .vtt captions, auto-transcription, chapter markers, completion tracking, gradebook integration, and native mobile-app support — compatible with Moodle 4.5 LTS through 5.2. The repository lives at github.com/amirtds/moodle-mod_bunnystream. It works with any Bunny.net account — no Cubite tenancy or hosting required. The plugin is GPL-v3 (the standard license for Moodle plugins); issues and pull requests are welcome.

### Why are my Moodle backups so large?

If you've uploaded videos directly into Moodle, every backup includes a full copy — a 1GB video adds roughly 1GB to every backup. Across a catalog with many courses and frequent backups, that overhead compounds fast. MoodleDocs explicitly recommends external streaming for larger files. Plugins like mod_bunnystream move video out of Moodle storage entirely, keeping backups lean. The bloat is invisible until it isn't. Restore windows lengthen. Disk fills. Backups slow. mod_bunnystream solves the root cause: video bytes never enter Moodle storage, so they're not in the backup to begin with.

### How do I bypass Moodle's video upload size limit?

Move video out of Moodle storage entirely. Plugins like mod_bunnystream upload videos directly to Bunny.net via the TUS resumable protocol, bypassing Moodle's PHP upload size and MoodleCloud's 250MB site-wide cap. The video file never lives in Moodle, so it doesn't count against site storage or bloat backups. This is exactly what official MoodleDocs recommends ("investigate a proper streaming server outside of Moodle"). mod_bunnystream is one implementation of that recommendation — the difference vs. embedding YouTube or Vimeo is that you get Moodle-native completion tracking and gradebook integration on top.

### How do I install mod_bunnystream?

Clone the repo to /path/to/moodle/mod/bunnystream, run php admin/cli/upgrade.php --non-interactive, then configure credentials at Site administration → Plugins → Activity modules → Bunny Stream. Copy the generated webhook URL into your Bunny dashboard at Stream → Library → Webhooks. Compatible with Moodle 4.5 LTS, 5.0, 5.1, and 5.2. Full walkthrough is in the install section above. After install, smoke-test with a 30-second clip and verify the signed iframe rejects unauthorized embed requests with 401, then confirm playing past the completion threshold updates the gradebook.

### Does mod_bunnystream support completion tracking and gradebook?

Yes. The plugin reports watched percentage (0–100) to the Moodle gradebook and marks activities complete when learners cross a configurable threshold (default 90% watched). It listens to Bunny player postMessage events (timeupdate, ended) in real time — so completion fires the moment the threshold is hit, not at page reload. This is the part that separates mod_bunnystream from generic embed plugins. Embedding a Bunny iframe directly in Moodle gives you video; it doesn't give you native completion or gradebook integration. The plugin is the Moodle-aware layer on top.

### Is mod_bunnystream a Video Time / Panopto / Kaltura alternative?

Different category. Video Time is embed-focused (paste a Vimeo URL). Panopto and Kaltura are full enterprise video platforms with their own pipelines and pricing. mod_bunnystream is the right pick when you want Bunny's pay-as-you-go economics, direct upload from the Moodle activity form, completion tracking, and gradebook integration in one GPL-v3 plugin. For institutions already invested in Panopto or Kaltura, sticking with them and integrating to Moodle is the right move. For Moodle teams who want a lightweight, modern video pipeline without enterprise procurement, mod_bunnystream is built for you.

### Does it work on MoodleCloud?

mod_bunnystream is a code plugin and MoodleCloud does not allow installing arbitrary plugins.

### Is mod_bunnystream GDPR-compliant?

Yes. Bunny.net is a Slovenia-headquartered (European) provider with GDPR-compliant data processing, EU PoPs, and standard DPA agreements available. For European universities and other regulated Moodle deployments, this often makes the Bunny + mod_bunnystream stack a cleaner procurement story than US-only video providers.

### Does it work with the Moodle Mobile app?

Yes — and this is one of the plugin's better-than-typical features. mod_bunnystream ships a custom Ionic template for the native Moodle Mobile app, so app users get a proper video player rather than a degraded webview fallback. Completion events and gradebook updates flow the same way they do in the web client.

---

## The Bottom Line

The Moodle video pain is real, has been real for years, and has a clean solution today. mod_bunnystream is the bridge — Moodle-native completion tracking, gradebook integration, captions, chapters, mobile-app support — and Bunny.net Stream is the platform underneath: encoding, DRM, captions generation, global delivery.

Pulling it together:

- Stop bloating backups. Video bytes never touch Moodle storage when the upload goes directly to Bunny via TUS.
- Bypass the MoodleCloud 250MB cap. Or, if you're on MoodleCloud and can't install plugins, consider managed Cubite Moodle hosting where the plugin is pre-installed.
- On Open edX instead? We've shipped the parallel piece for that LMS — see the bunny-xblock launch article.
- Get Moodle-native completion + gradebook, plus a real mobile-app player — without paying for Panopto.
- GPL-v3, public repo, contributions welcome. Two commands to install on Moodle 4.5 LTS through 5.2.

If you've been improvising — YouTube embeds, Vimeo iframes, paid plugins, or watching your backups slowly turn into the operational bottleneck — the cost of trying mod_bunnystream is five steps and a 30-second test clip. The cost of not trying it is another year of backup bloat and storage spend.
