Repository navigation
v0.1.4
0.1.4 — first release
<h5p-player> plays an .h5p package in the browser with no server-side code. Point it at a
package URL or hand it a file picked from disk. The archive is read in place, never unpacked,
and a Service Worker serves its files to the H5P runtime.
npm i @missing-elements/h5p-offline-player<script type="module">import '@missing-elements/h5p-offline-player'</script>
<h5p-player src="https://host.example/course.h5p" auto-resize></h5p-player>It works with no build step too. Load the element from a CDN and copy h5p-sw.js onto your
site. You can also frame the hosted /embed page and put nothing on your site at all. The
README covers all three setups.
What it does
- Plays packages from any host that sends CORS headers. A host that honours
Rangeis read
on demand, so a 200 MB course starts after a few hundred kilobytes. A host that ignores
Rangegets one download, and the player boots as soon as the libraries have arrived instead
of waiting for the whole archive. - Streams large video. Stored media is sliced straight out of the archive. Deflated media
is inflated in a background worker and served while that runs, one video at a time, with
the one on screen first. - Survives a bad link. A request that goes quiet or drops picks up from the byte it
reached. A host that is briefly unreachable does not leave a video stuck. - Boots fast on slow hosts. The runtime's libraries are pulled in a few large requests
before the content starts, not hundreds of small ones. On one real host that took the boot
from 136 s to 15 s. - Fills in missing libraries. Exports from h5p.com and h5p.org often carry only the
content.libraries="hub"fetches what is missing from the H5P hub. Without it, you get a
clear error naming the missing libraries. - Handles storage limits. Caching is optional on a
Rangehost. When the browser runs out
of room, the player serves straight from the archive. It evicts only packages no tab is using. - Treats archives as untrusted. Hostile entry names are rejected one by one. The content
runs in a frame with a per-response Content Security Policy. - Fits into the page.
auto-resizefollows the content's height through H5P's own resizer
protocol. Events coverready,xapi,finished,progress,resize,statechangeand
error. - Works with an existing Service Worker. A site limited to one worker per origin can mount
the handlers into its own worker from@missing-elements/h5p-offline-player/sw.
Tools
npm run normalize -- course.h5p rewrites a package so it streams best. It stores the media
and moves each mp4's index to the front. Use it on packages whose video was compressed inside
the zip, which otherwise has to be downloaded in full before it plays.
Requirements
- The page is served over
https://orlocalhost. h5p-sw.jsis served from your own origin. A bundler that followsnew URL(…, import.meta.url)
does this for you.- The package host sends CORS headers.
Known limitations
- It plays content only. There is no editor, no save and resume, and no results storage. xAPI
statements are emitted as events and stored nowhere. - A video that is compressed inside the zip and keeps its index at the end cannot start until
its last byte arrives. Normalizing the package fixes it. - Safari does not run Service Workers inside a third-party iframe. The
/embedpage detects
this and offers a link that opens the player in its own tab. - The browser test suite runs in Chromium. Firefox and Safari have been checked by hand, not
under test.
Licence
(MIT AND GPL-3.0-only). The player's own code is MIT. The H5P runtime files in
dist/frame-assets/ come from h5p-standalone, which bundles H5P core under GPL-3.0; see
tunapanda/h5p-standalone#188. NOTICE.md and the files inside frame-assets/ have the details.
Keep them with the runtime files when you serve them.