@kodezen/player
v1.0.1
Published
Framework-agnostic, tracking-free HTML5 / YouTube / Vimeo media player core with a custom control bar. Emits progress events and accepts a resume position; the host owns all tracking and completion logic.
Readme
@kodezen/player
A small, framework-agnostic media player core with a custom control bar.
Tracking-free by design. The library plays media, renders controls, emits progress events, and accepts a resume position. It never persists anything and knows nothing about WordPress, courses, or completion — the host wires progress saving, resume, and completion gating on top of its events. That keeps it reusable and makes it a clean seam for a future analytics/verification layer.
Status
Phase 1: html5 (self-hosted / external mp4 & webm) + control bar + React
adapter. youtube and vimeo providers implement the same Provider
interface and land in Phase 2 — nothing else changes when they are added.
Install
npm install @kodezen/playerDuring local development against this repo directly (before a version is
published), it can also be consumed from disk (e.g. a webpack alias to
dist/):
npm install
npm run buildVanilla usage
import { createPlayer } from '@kodezen/player';
import '@kodezen/player/styles.css';
const player = createPlayer(document.getElementById('mount'), {
source: { type: 'html5', url: 'https://example.com/lesson.mp4' },
resumeAt: 312, // seconds — host supplies from its own store
lockSeek: true, // block seeking past the furthest watched point
speeds: [1, 1.25, 1.5, 2],
});
player.on('timeupdate', ({ current, furthest, duration, percent }) => {
// Host saves this (throttled) to its own backend.
});
player.on('ended', () => {/* host may auto-complete */});
// player.play() / pause() / seek(s) / getState() / destroy()React usage
import { KodezenPlayer } from '@kodezen/player/react';
import '@kodezen/player/styles.css';
<KodezenPlayer
source={{ type: 'html5', url: lessonUrl }}
resumeAt={savedPosition}
lockSeek={gatingEnabled}
onTimeUpdate={({ percent, current }) => saveProgress(percent, current)}
onEnded={() => maybeComplete()}
/>API
createPlayer(container, options) → instance.
Options: source {type,url,id,poster,mime}, resumeAt, lockSeek,
autoplay, muted, speeds[], controls{}, className.
Instance: play(), pause(), toggle(), seek(s), getState(),
on(event, cb), off(event, cb), destroy().
Events: ready, play, pause, timeupdate, durationchange, ended,
error. timeupdate payload: { current, furthest, duration, percent }
(percent = furthest / duration, so it reflects watched coverage, not the
scrub position).
Host integration notes
- Resume = pass
resumeAt; player seeks onreadyunless within 2s of end. - Watch gate = enable
lockSeekand readpercentfromtimeupdate; the furthest-position measure is only honest while seeking is locked. - Completion = the host decides (e.g. auto-complete at a threshold or on
ended); the library stays out of it.
