All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Player no longer leaks its internal z-index to the host page:
.vide-uiand the IMA ad container now establish their own stacking context (isolation: isolate), so controls (z-index 3) and the IMA overlay (z-index 10 on touch) can't overlap host UI. destroy()resets player state toidle(it previously kept reporting the last state, e.g.ready).
- State machine missing transitions: buffering→paused/ended and error→ready
once()/off()removal bug — track wrappers in WeakMap sooff()removes pre-fire handlers- EventBus event drift — route
drm:keystatusanddrm:readythrough EventBus - VAST content restore timeout and error state listener to prevent
onReadyleaks - VMAP content restore using
player.srcinstead ofplayer.el.srcfor HLS/DASH routing sendBeaconfallback to Image pixel when return value is false- DRM/HLS race condition — await
drmReadypromise before config merge - Destroy guards on
on/off/emit/once/play/pause/srcto prevent post-destroy leaks - Copy cleanups array before iterating in
destroy()to prevent mutation during loop
- Replace
noExplicitAnysuppressions withEventHandler<never>in event system
devicePixelRatioinMediaSelectionHintsfor Retina-aware media scoring- Error codes
ERR_VAST_RESTORE_TIMEOUT(6000) andERR_VMAP_RESTORE_TIMEOUT(7000)
- Mark
Player.durationasreadonlyand remove no-op setter - Expose
setStateonPluginPlayervia typed object literal instead ofas unknown ascast - Extract
resolveAndLoadSource()to deduplicate handler matching inprocessSourceElementsandsrcsetter
- IMA ResizeObserver loop causing continuous resize during ad playback
- Framework selector to playground code generation
data-tooltipattributes to React, Vue, and Svelte framework wrappers
- Fix responsive layout, replace emoji logo with SVG, update IMA text
- Larger UI controls: icon 18px, button 34px, controls height 48px
- Thicker progress bar (4px/6px) with visible track background
- More spacious tooltip padding
- Remove hero demo footer badge
- Biome lint and formatting issues across docs, UI theme, and streaming plugins
- Redesign UI controls: inline progress bar layout, stroke-based SVG icons, mockup-matched styling
- Redesign Playground: 3-column layout with config sidebar, live inspector, and read-only code panel
- Refactor core.ts: extract pure modules for state machine, event bus, text tracks, and media listeners
- Biome lint and format issues across DRM plugin, tests, theme CSS, and IMA example
- README Features section: flatten to single list, add OMID, TypeScript, zero deps, web standards
- DRM plugin: PlayReady (Edge/Xbox/Smart TV) and ClearKey (testing/dev) key system support
- DRM plugin: robustness level and encryption scheme configuration
- DRM plugin: license request retry with exponential backoff
- DRM plugin: key status events on the player event bus
- DRM plugin: FairPlay init data transform callback and standalone DRM capability query API
- DRM plugin: generalized server certificate management (Widevine + FairPlay)
- Type-safe
pluginDataviaPluginDataMapregistry (setPluginData/getPluginDatawith generics) - Docs: Features section, StackBlitz playground, and dedicated CDN page
- Docs: DRM plugin docs for PlayReady, ClearKey, robustness, retry, and events
- Mini progress bar showing during normal video playback (now ad-only)
- Theme animations: BigPlay scale+fade, controls slide-up+fade, conic-gradient loader, accent glow on progress handle
- Google IMA SDK plugin (
vide/ima) — delegates ad lifecycle to IMA SDK - IMA framework components:
Ima(wrapping),ImaPlugin(ref-based),useImahook for React, Vue, Svelte - IMA plugin documentation with layout structure guide and framework usage examples
- VPAID 2.0 plugin (
vide/vpaid) for JavaScript-based interactive ad creatives - VAST parser:
apiFrameworkonVastMediaFile,adParametersonVastLinear - IMA and VPAID to plugin tables in README, docs index, and demo page
- IMA to docs sidebar navigation
- React IMA example with three usage patterns (wrap, ref, hook)
- IMA: content video not pausing during ad breaks (
CONTENT_PAUSE_REQUESTEDnow pauses content) - IMA: plugin cleanup during ad break now resumes content playback and resets player state
- Trailing blank line in VAST plugin (
src/vast/index.ts)
PluginPlayerinterface for type-safe plugin state control- VAST ads support in
endedstate for on-demand ad insertion (post-roll) - ARIA attributes and accessibility improvements across all UI implementations (React, Vue, Svelte)
- Custom Components section to Vue and Svelte docs
- Styling section to React docs
- Post-roll ad: restore content source and use player interface after ad ends
- Post-roll ad skip leaving ad media still playing
- Text shadow intensity in theme.css for improved readability
- Vue/Svelte
VideVideo: align with React by removing div wrapper and slot support - video.js migration guide inaccuracies
- Biome lint and format issues from accessibility changes
- Ad-learn-more tests to match updated component structure
- Lint errors in React AdLearnMore, Vue AdLearnMore, and Svelte VideUI
- Ad components (React, Vue, Svelte):
AdLearnMorenow matches vanilla UI structure (icon, title, hostname) - Ad components (React, Vue, Svelte):
AdSkipnow rendersspan.vide-skip__label+ skip icon matching vanilla - Ad component ordering in docs/examples:
AdOverlayreplaced byAdLearnMoreas default - Removed
showTitleprop fromAdLearnMore(title auto-displays when available)
AdLabel/AdCountdownno longer float above controls whenAdLearnMore(CTA) is absent- Svelte
VideUI: fixedbind:thisonconstvariable (changed tolet)
- Icons:
IconExternalLink,IconSkipForwardfor React, Vue, Svelte - React docs:
useUivs<Vide.UI>clarification - React docs: custom components guide with
useVideContext()anduseVideEvent()examples
- Lint errors across React, Svelte, and Vue components
- Redesigned ad UI: improved layout, skip button style, mini progress bar, responsive adjustments
- Ad UI components:
AdLearnMore,AdCountdown,AdLabel,AdSkip,AdOverlay(vanilla, React, Vue, Svelte) ad:startevent payload expanded:clickThrough,skipOffset,duration,adTitleuseAdStatehook/composable for React, Vue, Svelte (AdStatewithactive,meta)AdMetatype for framework ad state- UI
includeoption for opt-in components (ad-learn-moredefaults to off) - Ad Pod sequence playback: multiple
<Ad>elements withsequenceattributes are played sequentially - Waterfall ad fallback: multiple
<Ad>elements withoutsequenceare tried in order until one succeeds - Pod events:
ad:pod:start,ad:pod:end,ad:pod:adstart,ad:pod:adend - Stand-alone ad substitution in pods per VAST 3.3.1 (failed pod ads replaced with unsequenced ads)
allowMultipleAdsenforcement in VMAP (whenfalse, only first ad is played)- New exports:
classifyAds,playSingleAd,playPod,playWaterfall,selectMediaFile - New types:
ClassifiedAds,PlayableAd,PodResult,PlaySingleAdOptions,SingleAdResult - HTML examples:
index.html,vast-debug.html,without-ui.html,ad-pod.html,cdn-ads.html,cdn-all.html,cdn-individual.html,companion-ads.html,nonlinear-ads.html,ui-standalone.html,wrapper.html
- Svelte:
createVidePlayer()returnsPlayerGetterdirectly instead of{ player }object
- React context returns
Player | nullinstead of throwing - CSS class name:
vide-ad-skip→vide-skipto match theme.css - Svelte/Vue: cross-entry imports, CSS classes, child element structure
<audio>element support withisAudioproperty and automatic UI exclusion- Live stream detection (
isLive,seekableRange,livestatechangeevent) - Unified quality level API for HLS/DASH streams
- Text track API for subtitle/caption control
- IIFE global builds for CDN /
<script>tag usage - Ad
clickThroughnavigation support - Automatic error recovery for HLS/DASH streaming plugins
- Play button icon not updating during ad states
- Lint errors (formatting, import sorting)
repositoryfield for npm provenance
- Stub jsdom media methods for test compatibility
idle → playingandloading → playingstate transitions for early play calls- UI styling reference, HTML attributes guide, and CDN usage docs
- Testing, docs, and bundle size sections to CONTRIBUTING.md
- E2E UI tests: focus correct element and use correct class name
- API reference 404 by moving TypeDoc output to
docs/api-reference/
- DRM standalone EME support (encrypted MP4 without HLS/DASH)
- Error code constants (
ERR_DRM_*,ERR_HLS_*,ERR_DASH_*,ERR_MEDIA) - iOS Safari DRM patches
- E2E test suite (Playwright) for core playback, HLS, UI controls, and keyboard shortcuts
- TypeDoc API reference generation
- Performance tests (setup timing budgets, event listener cleanup, create/destroy cycle stability)
- HTML markup examples to docs and README
- Bigplay button staying visible during playback (race condition)
- API reference link to point to TypeDoc-generated index
- CI workflow (GitHub Actions)
- VitePress documentation site
- CHANGELOG.md
packageManagerfield for pnpm version detection in CI
- Bigplay button not hiding during playback
- Biome lint errors
- DRM plugin with Widevine and FairPlay support
- SSAI plugin for server-side ad insertion metadata detection (HLS DATERANGE/ID3, DASH EventStream)
setPluginData()/getPluginData()for cross-plugin data sharing- Proxy 17 HTMLVideoElement properties on Player interface (
loop,autoplay,poster,preload,defaultPlaybackRate,defaultMuted,crossOrigin,controls, etc.)
- SSAI DATERANGE detection and reworked example with real HLS metadata
- Bigplay button appearing during playback due to autohide class collision
- UI plugin with two-layer architecture (headless components + optional theme)
- 13 UI components: play, progress, time, volume, fullscreen, loader, error, bigplay, poster, ad-countdown, ad-skip, ad-overlay, ad-label
- YouTube-quality UI: SVG icons, keyboard shortcuts (Space, arrows, M, F, 0-9), click-to-play, auto-hide controls
- BEM class names and CSS custom properties for styling
theme.csswith design tokens, explicit box-model, ad UI polish- Individual component exports for standalone usage (
createPlayButton,createProgress, etc.) - AdPlugin integration for VAST skip/click/countdown via
getAdPlugin() - DASH streaming plugin (wraps dashjs)
- DASH + VAST example
- UI plugin bugs: fullscreen, bigplay replay, ad-skip, headless progress
- VAST content restoration after ad skip/end
- Content source not restored after VAST ad on HTML-attributed src
<source>tag race condition and DASH autoplay handling
- HLS streaming plugin (wraps hls.js, 618 bytes gzip)
- SourceHandler mechanism for extensible source handling
player.srcsetter/getter with SourceHandler hook chainregisterSourceHandler()for custom source types<source>element auto-processing- State transition support for source switching during playback
- Safari native HLS detection with dynamic hls.js import
- Fatal error mapping and
hlsConfigpassthrough
- VAST content restoration for HLS sources
- Content autoplay after VAST ad ends on HLS sources
- VAST/VMAP tracking events (mute, unmute, fullscreen, volumeChange)
PlayerEventMapad event types
ad:clickevent with clickThrough and clickTracking data- Example HTML files for various plugin combinations
- SIMID sandbox, creative overlay display, and requestStop handling
- DOM removed from VAST plugin (plugin no longer creates DOM elements)
- SIMID 1.2 plugin for interactive ad creatives
- Sandboxed iframe communication via MessageChannel
- Full SIMID handshake sequence
- Media event bridge for creatives
- Policy-based creative request handling
- AdPlugin lifecycle (
adPluginsoption) for VAST/VMAP plugins - InteractiveCreativeFile extraction in VAST parser
- Refactored OMID to use AdPlugin lifecycle
- OMID plugin for ad viewability measurement via OM SDK
- Typed EventBus fallback with
addEventListener/removeEventListenerdelegation to HTMLVideoElement
- VMAP plugin with ad break scheduling and wrapper ad resolution
- VAST event tracking: click, pause/resume, skip
- VAST ad playback: infer initial state, wait for canplay
- Spec gaps, error handling, and type safety issues from codebase audit
- Core player with
createPlayer()factory - EventBus with typed custom events (
statechange,error,ad:*) - StateMachine with validated state transitions
- Plugin system with explicit opt-in via
player.use() - HTMLVideoElement proxy pattern
- VAST 4.1 parser (pure function, no I/O)
- VAST tracker with sendBeacon/Image pixel support
- Quartile tracking for ad metrics
- TypeScript strict mode, ESM only, zero dependencies