← All @molecule/* packages · App templates
@molecule/app-videoFeature · video · App (browser) · v1.0.1 · Apache-2.0
Video playback core — provider-swappable player interface with a built-in native HTML5 provider (MP4/WebM/Ogg; HLS/DASH require a custom provider)
npm install @molecule/app-video@molecule/app-video is a ready-made video feature for the app (browser) side. It composes the core interfaces it needs, so it works with whichever providers your app has bonded.
import { createPlayer, setProvider, createNativeVideoProvider } from '@molecule/app-video'
// Wire the provider once at startup (defaults to native HTML5 if skipped)
setProvider(createNativeVideoProvider())
// Create a player imperatively against a DOM container
const player = await createPlayer({
container: '#video-root',
sources: [{ src: 'https://example.com/video.mp4', type: 'video/mp4', label: '1080p' }],
poster: 'https://example.com/poster.jpg',
autoplay: false,
controls: true,
})
player.on('ended', () => console.log('Playback finished'))Providers (1): @molecule/app-video-hls
Works with: @molecule/app-bond, @molecule/app-i18n
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Video player interface for molecule.dev.
A unified imperative API for video playback: createPlayer() builds a
VideoPlayer (play/pause/seek/volume/quality/fullscreen/PiP/captions/
events) from whatever VideoProvider is bonded, with a built-in native
HTML5 <video> provider as the default.
import { createPlayer, setProvider, createNativeVideoProvider } from '@molecule/app-video'
// Wire the provider once at startup (defaults to native HTML5 if skipped)
setProvider(createNativeVideoProvider())
// Create a player imperatively against a DOM container
const player = await createPlayer({
container: '#video-root',
sources: [{ src: 'https://example.com/video.mp4', type: 'video/mp4', label: '1080p' }],
poster: 'https://example.com/poster.jpg',
autoplay: false,
controls: true,
})
player.on('ended', () => console.log('Playback finished'))
feature
npm install @molecule/app-video @molecule/app-bond @molecule/app-i18n
ControlsConfigVideo player control toggles (play/pause, progress, volume, fullscreen, PiP, captions, quality, etc.).
interface ControlsConfig {
/**
* Enable/disable all controls.
*/
enabled?: boolean
/**
* Individual control toggles.
*/
playPause?: boolean
progress?: boolean
currentTime?: boolean
duration?: boolean
volume?: boolean
mute?: boolean
fullscreen?: boolean
pip?: boolean
settings?: boolean
captions?: boolean
quality?: boolean
playbackRate?: boolean
download?: boolean
seekForward?: boolean
seekBackward?: boolean
/**
* Seek time in seconds.
*/
seekTime?: number
/**
* Available playback rates.
*/
playbackRates?: number[]
}
PlayerConfigVideo player initialization options (sources, poster, autoplay, controls, tracks, aspect ratio, etc.).
interface PlayerConfig {
/**
* Container element.
*/
container: HTMLElement | string
/**
* Video sources.
*/
sources: VideoSource[]
/**
* Poster image URL.
*/
poster?: string
/**
* Autoplay.
*/
autoplay?: boolean
/**
* Loop playback.
*/
loop?: boolean
/**
* Muted.
*/
muted?: boolean
/**
* Initial volume (0-1).
*/
volume?: number
/**
* Playback rate.
*/
playbackRate?: number
/**
* Preload mode.
*/
preload?: 'none' | 'metadata' | 'auto'
/**
* Text tracks (captions/subtitles).
*/
tracks?: TextTrack[]
/**
* Controls configuration.
*/
controls?: ControlsConfig | boolean
/**
* Inline playback (iOS).
*/
playsinline?: boolean
/**
* Cross-origin mode.
*/
crossorigin?: 'anonymous' | 'use-credentials'
/**
* Aspect ratio (e.g., '16:9', '4:3').
*/
aspectRatio?: string
/**
* Fluid width (responsive).
*/
fluid?: boolean
/**
* Fill container.
*/
fill?: boolean
/**
* Custom CSS class.
*/
className?: string
/**
* Language for UI.
*/
language?: string
/**
* Keyboard shortcuts.
*/
keyboard?: boolean
/**
* Click to play/pause.
*/
clickToPlay?: boolean
/**
* Double-click to fullscreen.
*/
doubleClickFullscreen?: boolean
/**
* Hide controls delay (ms).
*/
hideControlsDelay?: number
}
PlayerStateCurrent video player state (playing, paused, time, duration, volume, buffered, quality).
interface PlayerState {
/**
* Current playback time in seconds.
*/
currentTime: number
/**
* Total duration in seconds.
*/
duration: number
/**
* Buffered time ranges.
*/
buffered: { start: number; end: number }[]
/**
* Whether the video is playing.
*/
playing: boolean
/**
* Whether the video is paused.
*/
paused: boolean
/**
* Whether the video has ended.
*/
ended: boolean
/**
* Whether the video is seeking.
*/
seeking: boolean
/**
* Whether the video is waiting for data.
*/
waiting: boolean
/**
* Whether the video is muted.
*/
muted: boolean
/**
* Volume level (0-1).
*/
volume: number
/**
* Playback rate.
*/
playbackRate: number
/**
* Whether fullscreen is active.
*/
fullscreen: boolean
/**
* Whether picture-in-picture is active.
*/
pip: boolean
/**
* Current quality level.
*/
quality?: QualityLevel
/**
* Error (if any).
*/
error?: Error
}
QualityLevelAvailable video quality level (resolution, bitrate, label, and active flag).
interface QualityLevel {
/**
* Quality ID.
*/
id: string | number
/**
* Label (e.g., '1080p HD', '720p', 'Auto').
*/
label: string
/**
* Height in pixels.
*/
height?: number
/**
* Width in pixels.
*/
width?: number
/**
* Bitrate in kbps.
*/
bitrate?: number
}
TextTrackText track (captions/subtitles) configuration.
interface TextTrack {
/**
* Track kind.
*/
kind: 'subtitles' | 'captions' | 'descriptions' | 'chapters' | 'metadata'
/**
* Track label.
*/
label: string
/**
* Language code.
*/
language: string
/**
* Source URL.
*/
src: string
/**
* Default track.
*/
default?: boolean
}
VideoPlayerVideo player instance.
interface VideoPlayer {
/**
* Plays the video.
*/
play(): Promise<void>
/**
* Pauses the video.
*/
pause(): void
/**
* Toggles play/pause.
*/
togglePlay(): void
/**
* Stops the video.
*/
stop(): void
/**
* Seeks to a time.
*/
seek(time: number): void
/**
* Seeks forward.
*/
seekForward(seconds?: number): void
/**
* Seeks backward.
*/
seekBackward(seconds?: number): void
/**
* Gets current time.
*/
getCurrentTime(): number
/**
* Gets duration.
*/
getDuration(): number
/**
* Gets buffered time ranges.
*/
getBuffered(): { start: number; end: number }[]
/**
* Sets volume.
*/
setVolume(volume: number): void
/**
* Gets volume.
*/
getVolume(): number
/**
* Mutes the video.
*/
mute(): void
/**
* Unmutes the video.
*/
unmute(): void
/**
* Toggles mute.
*/
toggleMute(): void
/**
* Checks if muted.
*/
isMuted(): boolean
/**
* Sets playback rate.
*/
setPlaybackRate(rate: number): void
/**
* Gets playback rate.
*/
getPlaybackRate(): number
/**
* Gets available quality levels.
*/
getQualityLevels(): QualityLevel[]
/**
* Sets quality level.
*/
setQuality(level: QualityLevel | string | number): void
/**
* Gets current quality.
*/
getQuality(): QualityLevel | undefined
/**
* Enters fullscreen.
*/
enterFullscreen(): Promise<void>
/**
* Exits fullscreen.
*/
exitFullscreen(): Promise<void>
/**
* Toggles fullscreen.
*/
toggleFullscreen(): Promise<void>
/**
* Checks if fullscreen.
*/
isFullscreen(): boolean
/**
* Enters picture-in-picture.
*/
enterPip(): Promise<void>
/**
* Exits picture-in-picture.
*/
exitPip(): Promise<void>
/**
* Toggles picture-in-picture.
*/
togglePip(): Promise<void>
/**
* Checks if in picture-in-picture.
*/
isPip(): boolean
/**
* Loads new sources.
*/
load(sources: VideoSource[], poster?: string): void
/**
* Gets current source.
*/
getSource(): VideoSource | undefined
/**
* Gets player state.
*/
getState(): PlayerState
/**
* Adds event listener.
*/
on(event: PlayerEvent, handler: (data: unknown) => void): () => void
/**
* Removes event listener.
*/
off(event: PlayerEvent, handler: (data: unknown) => void): void
/**
* Gets available text tracks.
*/
getTextTracks(): TextTrack[]
/**
* Sets active text track.
*/
setTextTrack(language: string | null): void
/**
* Gets active text track.
*/
getActiveTextTrack(): TextTrack | undefined
/**
* Shows controls.
*/
showControls(): void
/**
* Hides controls.
*/
hideControls(): void
/**
* Gets the video element.
*/
getVideoElement(): HTMLVideoElement
/**
* Gets the container element.
*/
getContainer(): HTMLElement
/**
* Gets the underlying player instance.
*/
getInstance(): unknown
/**
* Takes a screenshot.
*/
screenshot(): string
/**
* Destroys the player.
*/
destroy(): void
}
VideoProviderVideo provider interface.
interface VideoProvider {
/**
* Create a new video player instance with the given configuration.
* @returns A VideoPlayer instance for controlling playback.
*/
createPlayer(config: PlayerConfig): VideoPlayer | Promise<VideoPlayer>
/**
* Get the name of this video provider (e.g., 'html5', 'hls.js', 'shaka').
* @returns The provider name string.
*/
getName(): string
/**
* Check if the video provider's library has been loaded and is ready.
* @returns Whether the provider is loaded and ready to create players.
*/
isLoaded(): boolean
/**
* Get the list of video formats supported by this provider (e.g., 'mp4', 'webm', 'hls').
* @returns Array of supported format strings.
*/
getSupportedFormats(): string[]
/**
* Check if HTTP Live Streaming (HLS) playback is supported.
* @returns Whether HLS is supported by this provider.
*/
supportsHls(): boolean
/**
* Check if MPEG-DASH adaptive streaming is supported.
* @returns Whether DASH is supported by this provider.
*/
supportsDash(): boolean
}
VideoSourceVideo source configuration.
interface VideoSource {
/**
* Source URL.
*/
src: string
/**
* Source type (e.g., 'video/mp4', 'video/webm', 'application/x-mpegURL').
*/
type?: string
/**
* Source label (for quality selection).
*/
label?: string
/**
* Resolution (e.g., '1080p', '720p', '480p').
*/
resolution?: string
/**
* Bitrate in kbps.
*/
bitrate?: number
}
PlayerEventVideo player lifecycle events (play, pause, ended, seek, time update, error, etc.).
type PlayerEvent =
| 'play'
| 'pause'
| 'ended'
| 'timeupdate'
| 'progress'
| 'seeking'
| 'seeked'
| 'volumechange'
| 'ratechange'
| 'waiting'
| 'canplay'
| 'canplaythrough'
| 'loadedmetadata'
| 'loadeddata'
| 'durationchange'
| 'error'
| 'fullscreenchange'
| 'enterpictureinpicture'
| 'leavepictureinpicture'
| 'qualitychange'
createNativePlayer(config)Create a native HTML5 video player instance. Uses the browser's <video> element
with standard playback controls, source management, and event handling.
function createNativePlayer(config: PlayerConfig): VideoPlayer
config — Player configuration (container, source, autoplay, controls, etc.).Returns: A VideoPlayer instance for controlling the HTML5 video element.
createNativeVideoProvider()Create a native HTML5 video provider. Supports standard formats (MP4, WebM, Ogg)
using the browser's built-in <video> element. Does not support HLS or DASH streaming.
function createNativeVideoProvider(): VideoProvider
Returns: A VideoProvider backed by native HTML5 video.
createPlayer(config)Create a new video player instance using the current provider.
function createPlayer(config: PlayerConfig): VideoPlayer | Promise<VideoPlayer>
config — Player configuration (container, source, autoplay, controls, etc.).Returns: A VideoPlayer instance for controlling playback.
formatTime(seconds)Format a duration in seconds as a human-readable time string. Returns 'H:MM:SS' for durations over an hour, or 'M:SS' otherwise.
function formatTime(seconds: number): string
seconds — The duration in seconds.Returns: A formatted time string (e.g., '1:23:45' or '3:07').
getProvider()Get the current video provider. Falls back to a native HTML5 video provider if none has been explicitly set.
function getProvider(): VideoProvider
Returns: The active VideoProvider instance.
getVideoType(url)Infer the MIME type of a video from its URL based on the file extension. Supports MP4, WebM, Ogg, HLS (.m3u8), and DASH (.mpd).
function getVideoType(url: string): string | undefined
url — The video URL.Returns: The MIME type string, or undefined if the format is unrecognized.
hasProvider()Check if a video provider has been registered.
function hasProvider(): boolean
Returns: Whether a VideoProvider has been bonded.
parseTime(time)Parse a time string (H:MM:SS or M:SS or S) into total seconds.
function parseTime(time: string): number
time — The time string to parse.Returns: The total duration in seconds.
setProvider(provider)Set the video provider.
function setProvider(provider: VideoProvider): void
provider — VideoProvider implementation to register.Peer dependencies:
@molecule/app-bond ^1.0.1@molecule/app-i18n ^1.0.1@molecule/app-bond@molecule/app-i18nTwo shipped providers: the built-in native HTML5 one (default) and
@molecule/app-video-hls. For HLS (.m3u8) streaming that works in
EVERY browser (adaptive bitrate; the native provider only plays HLS in
Safari), bond it: import { provider } from '@molecule/app-video-hls'; setProvider(provider) at startup. For other libraries (Video.js / Plyr /
Vidstack) or MPEG-DASH, implement the VideoProvider interface yourself and
wire it with setProvider() (registered on the app bond registry under
'video').
Native-provider limits a weak integrator must know: MP4/WebM/Ogg only
(supportsHls() / supportsDash() return false — no HLS outside Safari's
native support unless you bond @molecule/app-video-hls, no DASH);
controls is effectively boolean —
passing a ControlsConfig object just enables the browser's native
controls and every granular toggle, seekTime and playbackRates are
ignored; fluid, fill, aspectRatio, language, keyboard,
clickToPlay, doubleClickFullscreen, hideControlsDelay and the
initial playbackRate are also ignored (the <video> is styled
100%x100% of its container — size the container). setQuality accepts a
source index or label string; passing a QualityLevel object is
currently a no-op. Quality "levels" are just the sources array —
switching swaps video.src and restores the current time.
Source-label strings route through t('video.source.label') — the
companion @molecule/app-locales-video bond translates them. For
ready-made React chrome see @molecule/app-video-player-react (a
standalone <video> wrapper; it does NOT consume this package).
Translation strings are provided by @molecule/app-locales-video.