<bunny-player> custom element that attaches player.js and turns the player’s events into DOM events.
Astro example on GitHub
An Astro site with custom controls and an event log.
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 your video IDs
Copy the library ID and video GUID from the video’s page in the dashboard. Both are public, since they appear in every embed URL.Astro inlines
.env
PUBLIC_ variables at build time. Without them, the embed URL reads undefined/undefined.4
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 from the component, so only pages with a player fetch it.
src/lib/load-playerjs.ts
player.js import in BunnyPlayer.astro for the loader, and wait for it before setting src.
src/components/BunnyPlayer.astro
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.