Vize

Video Player

Headless video player: the shared MediaPlayer controls under VideoPlayer* names plus the native <video> part, fullscreen, and picture-in-picture. Shared types and helpers are exported from @vizejs/ui/media-player.

Package @vizejs/ui/video-player
Maturity stable
Own the source vize lib pull video-player
Requires context, media-player
Aliases video player, video, video controls, picture in picture, fullscreen video
Covers HTML video, Fullscreen API, Picture-in-Picture API, Vidstack Player, Media Chrome

Usage

import { VideoPlayerCaptionsButton, VideoPlayerLoadingIndicator, VideoPlayerMuteButton, VideoPlayerPlayButton, VideoPlayerPlaybackRateButton, VideoPlayer, VideoPlayerRoot, VideoPlayerSeekSlider, VideoPlayerTimeDisplay, VideoPlayerVolumeSlider, VideoPlayerFullscreenButton, VideoPlayerPictureInPictureButton, VideoPlayerVideo } from "@vizejs/ui/video-player";

Or copy the source into your project with vize lib pull video-player (see Source Distribution).

API

VideoPlayerCaptionsButton

Source: src/families/media/media-player/media-player-captions-button.vue

Props

Prop Type Default Description
ariaLabel string | null undefined Accessible name override. undefined uses the state-dependent label from the root messages; null omits aria-label so visible slot text names the button.

Events

Event Payload Description
click [nativeEvent: MouseEvent] Fired before the action. Call preventDefault() to skip it.

Slots

Slot Slot props Description
default MediaPlayerSlotState Button content, e.g. an icon. Receives the playback state.

Exposed

Member Type Description
disabled —
element Readonly<ShallowRef<HTMLElement | null>> Template ref to the rendered root element.

VideoPlayerLoadingIndicator

Source: src/families/media/media-player/media-player-loading-indicator.vue

Slots

Slot Slot props Description
default MediaPlayerSlotState Indicator content, rendered only while loading. Defaults to messages.loading.

VideoPlayerMuteButton

Source: src/families/media/media-player/media-player-mute-button.vue

Props

Prop Type Default Description
ariaLabel string | null undefined Accessible name override. undefined uses the state-dependent label from the root messages; null omits aria-label so visible slot text names the button.

Events

Event Payload Description
click [nativeEvent: MouseEvent] Fired before the action. Call preventDefault() to skip it.

Slots

Slot Slot props Description
default MediaPlayerSlotState Button content, e.g. an icon. Receives the playback state.

Exposed

Member Type Description
disabled —
element Readonly<ShallowRef<HTMLElement | null>> Template ref to the rendered root element.

VideoPlayerPlayButton

Source: src/families/media/media-player/media-player-play-button.vue

Props

Prop Type Default Description
ariaLabel string | null undefined Accessible name override. undefined uses the state-dependent label from the root messages; null omits aria-label so visible slot text names the button.

Events

Event Payload Description
click [nativeEvent: MouseEvent] Fired before the action. Call preventDefault() to skip it.

Slots

Slot Slot props Description
default MediaPlayerSlotState Button content, e.g. an icon. Receives the playback state.

Exposed

Member Type Description
disabled —
element Readonly<ShallowRef<HTMLElement | null>> Template ref to the rendered root element.

VideoPlayerPlaybackRateButton

Source: src/families/media/media-player/media-player-playback-rate-button.vue

Props

Prop Type Default Description
ariaLabel string | null undefined Accessible name override. undefined uses the state-dependent label from the root messages; null omits aria-label so visible slot text names the button.
rates readonly number[] [0.5, 1, 1.25, 1.5, 2] Rates cycled on click, in order. The next rate after the current one is chosen; an unknown current rate selects the first.

Events

Event Payload Description
click [nativeEvent: MouseEvent] Fired before the action. Call preventDefault() to skip it.

Slots

Slot Slot props Description
default MediaPlayerSlotState Button content, e.g. an icon. Receives the playback state.

Exposed

Member Type Description
disabled —
element Readonly<ShallowRef<HTMLElement | null>> Template ref to the rendered root element.

VideoPlayer

Source: src/families/media/media-player/media-player-root.vue

Props

Prop Type Default Description
id string | null undefined Consumer-owned base id. null and undefined select a deterministic fallback.
volume number undefined Controlled volume from 0 to 1 (v-model:volume).
defaultVolume number 1 Initial volume for uncontrolled use.
muted boolean undefined Controlled muted state (v-model:muted).
defaultMuted boolean false Initial muted state for uncontrolled use. Rendered as the native muted attribute, so muted autoplay works before hydration.
playbackRate number undefined Controlled playback rate (v-model:playbackRate).
defaultPlaybackRate number 1 Initial playback rate for uncontrolled use.
currentTime number undefined Synchronized playback position (v-model:currentTime). The media element stays the source of truth: timeupdate emits the position, and a parent value more than half a second away from it seeks.
keyboardShortcuts boolean true Handle media keyboard shortcuts while focus is inside the player.
seekStep number 5 Seconds moved by arrow keys on the seek slider and root shortcuts.
skipStep number 10 Seconds skipped by the J and L shortcuts.
volumeStep number 0.05 Volume change for arrow keys, from 0 to 1.
messages MediaPlayerMessages undefined Localized accessible labels for every control part. Missing keys use English defaults.
dir "ltr" | "rtl" "ltr" Reading direction used by horizontal sliders and arrow keys.
ariaLabel string undefined Accessible player name; adds role="group".
ariaLabelledby string undefined Ids that name the player; adds role="group".

Events

Event Payload Description
update:volume [volume: number] Fired when the volume requests a new controlled value.
update:muted [muted: boolean] Fired when the muted state requests a new controlled value.
update:playbackRate [rate: number] Fired when the playback rate requests a new controlled value.
update:currentTime [time: number] Fired on every native timeupdate and seek with the current position.
play [] Fired after playback starts.
pause [] Fired after playback pauses.
ended [] Fired after playback reaches the end.
playRejected [reason: unknown] Fired when play() is rejected, e.g. by an autoplay policy.
error [code: number | null] Fired when the media element reports an error (MediaError.code).

Slots

Slot Slot props Description
default MediaPlayerSlotState Media element and controls. Receives the complete playback state.

Exposed

Member Type Description
buffered —
captionTrack —
currentTime —
duration —
element Readonly<ShallowRef<HTMLElement | null>> Template ref to the rendered root element.
error —
fullscreen —
loading —
media —
muted —
pause —
paused —
pictureInPicture —
play —
playbackRate —
seek —
seekBy —
seeking —
setCaptionTrack —
setMuted —
setPlaybackRate —
setVolume —
state —
textTracks —
toggleCaptions —
toggleFullscreen —
togglePictureInPicture —
togglePlay —
volume —

VideoPlayerRoot

Source: src/families/media/media-player/media-player-root.vue

Props

Prop Type Default Description
id string | null undefined Consumer-owned base id. null and undefined select a deterministic fallback.
volume number undefined Controlled volume from 0 to 1 (v-model:volume).
defaultVolume number 1 Initial volume for uncontrolled use.
muted boolean undefined Controlled muted state (v-model:muted).
defaultMuted boolean false Initial muted state for uncontrolled use. Rendered as the native muted attribute, so muted autoplay works before hydration.
playbackRate number undefined Controlled playback rate (v-model:playbackRate).
defaultPlaybackRate number 1 Initial playback rate for uncontrolled use.
currentTime number undefined Synchronized playback position (v-model:currentTime). The media element stays the source of truth: timeupdate emits the position, and a parent value more than half a second away from it seeks.
keyboardShortcuts boolean true Handle media keyboard shortcuts while focus is inside the player.
seekStep number 5 Seconds moved by arrow keys on the seek slider and root shortcuts.
skipStep number 10 Seconds skipped by the J and L shortcuts.
volumeStep number 0.05 Volume change for arrow keys, from 0 to 1.
messages MediaPlayerMessages undefined Localized accessible labels for every control part. Missing keys use English defaults.
dir "ltr" | "rtl" "ltr" Reading direction used by horizontal sliders and arrow keys.
ariaLabel string undefined Accessible player name; adds role="group".
ariaLabelledby string undefined Ids that name the player; adds role="group".

Events

Event Payload Description
update:volume [volume: number] Fired when the volume requests a new controlled value.
update:muted [muted: boolean] Fired when the muted state requests a new controlled value.
update:playbackRate [rate: number] Fired when the playback rate requests a new controlled value.
update:currentTime [time: number] Fired on every native timeupdate and seek with the current position.
play [] Fired after playback starts.
pause [] Fired after playback pauses.
ended [] Fired after playback reaches the end.
playRejected [reason: unknown] Fired when play() is rejected, e.g. by an autoplay policy.
error [code: number | null] Fired when the media element reports an error (MediaError.code).

Slots

Slot Slot props Description
default MediaPlayerSlotState Media element and controls. Receives the complete playback state.

Exposed

Member Type Description
buffered —
captionTrack —
currentTime —
duration —
element Readonly<ShallowRef<HTMLElement | null>> Template ref to the rendered root element.
error —
fullscreen —
loading —
media —
muted —
pause —
paused —
pictureInPicture —
play —
playbackRate —
seek —
seekBy —
seeking —
setCaptionTrack —
setMuted —
setPlaybackRate —
setVolume —
state —
textTracks —
toggleCaptions —
toggleFullscreen —
togglePictureInPicture —
togglePlay —
volume —

VideoPlayerSeekSlider

Source: src/families/media/media-player/media-player-seek-slider.vue

Props

Prop Type Default Description
ariaLabel string undefined Accessible name. Defaults to the root messages.seek.
ariaLabelledby string undefined Ids that name the slider instead of aria-label.

Slots

Slot Slot props Description
default MediaPlayerSlotState Thumb content. Receives the playback state.

Exposed

Member Type Description
dragging —
element Readonly<ShallowRef<HTMLElement | null>> Template ref to the rendered root element.
focus —
thumb —

VideoPlayerTimeDisplay

Source: src/families/media/media-player/media-player-time-display.vue

Props

Prop Type Default Description
mode MediaPlayerTimeDisplayMode "current" Which time to show: the position, the duration, or the time remaining (rendered with a leading minus sign).

Slots

Slot Slot props Description
default MediaPlayerSlotState & { readonly text: string; readonly seconds: number } Custom rendering. Receives the formatted text, raw seconds, and playback state.

VideoPlayerVolumeSlider

Source: src/families/media/media-player/media-player-volume-slider.vue

Props

Prop Type Default Description
ariaLabel string undefined Accessible name. Defaults to the root messages.volume.
ariaLabelledby string undefined Ids that name the slider instead of aria-label.

Slots

Slot Slot props Description
default MediaPlayerSlotState Thumb content. Receives the playback state.

Exposed

Member Type Description
dragging —
element Readonly<ShallowRef<HTMLElement | null>> Template ref to the rendered root element.
focus —
thumb —

VideoPlayerFullscreenButton

Source: src/families/media/video-player/video-player-fullscreen-button.vue

Props

Prop Type Default Description
ariaLabel string | null undefined Accessible name override. undefined uses the state-dependent label from the root messages; null omits aria-label so visible slot text names the button.
unsupported VideoPlayerUnsupportedBehavior "disable" Behavior when the platform lacks support, detected after mount (the server always renders the unsupported state): disable the button or hide it.

Events

Event Payload Description
click [nativeEvent: MouseEvent] Fired before the request. Call preventDefault() to skip it.

Slots

Slot Slot props Description
default MediaPlayerSlotState Button content, e.g. an icon. Receives the playback state.

Exposed

Member Type Description
disabled —
element Readonly<ShallowRef<HTMLElement | null>> Template ref to the rendered root element.

VideoPlayerPictureInPictureButton

Source: src/families/media/video-player/video-player-picture-in-picture-button.vue

Props

Prop Type Default Description
ariaLabel string | null undefined Accessible name override. undefined uses the state-dependent label from the root messages; null omits aria-label so visible slot text names the button.
unsupported VideoPlayerUnsupportedBehavior "disable" Behavior when the platform lacks support, detected after mount (the server always renders the unsupported state): disable the button or hide it.

Events

Event Payload Description
click [nativeEvent: MouseEvent] Fired before the request. Call preventDefault() to skip it.

Slots

Slot Slot props Description
default MediaPlayerSlotState Button content, e.g. an icon. Receives the playback state.

Exposed

Member Type Description
disabled —
element Readonly<ShallowRef<HTMLElement | null>> Template ref to the rendered root element.

VideoPlayerVideo

Source: src/families/media/video-player/video-player-video.vue

Props

Prop Type Default Description
src string undefined Video source, validated by the shared media-source policy. Unsafe sources are dropped (data-invalid-src); use <source> children for format fallbacks.
poster string undefined Poster image, validated as an image source.
preload MediaPlayerPreload "metadata" Native preload hint.
playsinline boolean true Play inline on iOS instead of entering native fullscreen.
autoplay boolean false Native autoplay. Browsers usually require the root defaultMuted as well.
loop boolean false Restart at the end.
controls boolean false Also render the browser's native controls.
crossOrigin MediaPlayerCrossOrigin undefined Native CORS policy, required for cross-origin captions.
disablePictureInPicture boolean false Hide the browser picture-in-picture affordance and disable the PiP button.
width number | string undefined Intrinsic width used to reserve layout space.
height number | string undefined Intrinsic height used to reserve layout space.
allowInsecure boolean false Permit unencrypted http: sources for local development.

Slots

Slot Slot props Description
default MediaPlayerSlotState <source> and <track> children, plus fallback content.

Exposed

Member Type Description
element Readonly<ShallowRef<HTMLElement | null>> Template ref to the rendered root element.

Behavior

Normative state x input -> outcome table for video-player-video.vue, video-player-fullscreen-button.vue, and video-player-picture-in-picture-button.vue (@vizejs/ui/video-player). The shared controls re-exported as VideoPlayer* follow media-player.behavior.md. Every row is proven by the named test.

ID State Input Outcome Evidence
VP1 render props native <video> with validated src/poster, playsinline, preload, CORS, size, slot <track>s; unsafe sources are dropped renders a native video with validated sources and inline-playback attributes
VP2 defaultMuted autoplay the element renders and stays muted so muted autoplay is allowed defaultMuted mutes the element for muted autoplay
VP3 fullscreen supported button / F key the root container enters and leaves fullscreen; state, data-fullscreen, and labels follow fullscreenchange fullscreen toggles the root through the standard API and reports state
VP4 prefixed platforms toggle falls back to webkitRequestFullscreen, then native iOS video fullscreen with webkitbeginfullscreen/webkitendfullscreen fullscreen falls back to WebKit prefixes and native video fullscreen
VP5 PiP supported button enters and leaves picture-in-picture, tracking enterpictureinpicture/leavepictureinpicture; disablePictureInPicture opts out picture-in-picture is detected after mount and toggles the video
VP6 unsupported render platform buttons are disabled, or hidden with unsupported="hide", and report data-supported="false" unsupported platform controls are disabled or hidden
VP7 any click with preventDefault() the request is skipped; ariaLabel overrides the default label platform buttons honor preventDefault and aria-label overrides
VP8 aliases import / setup VideoPlayer aliases the shared root; video parts require the provider VideoPlayer aliases the shared root and requires a provider for its parts
VP9 SSR isolated requests markup is byte-identical and platform buttons render the unsupported state until mount renders byte-identical video player markup with unsupported platform controls
VP10 SSR / hydration hydrate server markup hydrates without warnings or node replacement hydrates video player markup without warnings or node replacement
VP11 types compile the root is the shared MediaPlayer root and unsupported behavior is a closed union video-player.types.test-d.ts

Platform capabilities are detected after mount. WebKit-prefixed APIs are reached through in checks and Reflect, never through casts.