<bunny-player> custom element that attaches player.js and turns the player’s events into DOM events.
Astro example on GitHub
Custom controls and an event log around this component.
bun install && bun dev plays a demo video.Quickstart
1
Install player.js
tsconfig.json includes, for example player.js.d.ts. It covers the methods and events the Bunny Player supports:player.js.d.ts
2
Create the component
The embed URL waits in
data-src until the element has a Player listening. An iframe with src in the HTML can finish loading first, and then ready never arrives.src/components/BunnyPlayer.astro
3
Add it to a page
src/pages/index.astro
params takes any player parameter.Control playback
ready hands over the Player as event.detail.
send() covers the gap:
play() before the viewer has clicked anything. Mute first if playback has to start on its own. The Playback control API lists every method and event.
Track progress
timeupdate fires several times a second. Throttle it before it reaches your backend.
params={{ t: savedSeconds }} to resume.
Signed embed URLs
With embed view token authentication on, sign the URL in the page frontmatter and passtoken and expires through params. Render that page on demand. A prerendered page hands every visitor the same token, and it expires. The signing code is in Sign embed URLs on the server.
Load player.js from the CDN instead
We host a build of player.js that addssetPlaybackRate() and the playbackratechange event (Methods). Load it in your layout’s <head> with is:inline, which keeps Astro from bundling it and runs it ahead of the component’s script.
const playerjs = window.playerjs and declare the global.
Troubleshooting
The ready event never fires
The ready event never fires
The iframe loaded before player.js was listening. Keep the URL in
data-src and let the element set src.A hidden tab also holds ready back until the viewer switches to it.Controls stop working after a view transition
Controls stop working after a view transition
<ClientRouter /> runs page scripts once, leaving your ready listener on the previous page’s element. Register it inside an astro:page-load listener.The iframe shows a 403
The iframe shows a 403
The library’s allowed domains, direct access block, or token authentication is rejecting the embed. See Embedding restrictions.