Skip to content

v0.1.4

Choose a tag to compare

@alekswebnet alekswebnet released this 25 Sep 22:01
· 344 commits to main since this release

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 Range is read
    on demand, so a 200 MB course starts after a few hundred kilobytes. A host that ignores
    Range gets 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 Range host. 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-resize follows the content's height through H5P's own resizer
    protocol. Events cover ready, xapi, finished, progress, resize, statechange and
    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:// or localhost.
  • h5p-sw.js is served from your own origin. A bundler that follows new 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 /embed page 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.