Svelte Video Player

May 12, 2026 ยท View on GitHub

SVP logo
version licence dependencies typescript

Svelte Video Player

A video player component for Svelte 5 with HLS/DASH streaming, subtitles, picture-in-picture, playback rate control, quality selection, and Media Session API support.

Controls are fully keyboard-accessible. Starting a player pauses any previously playing instance. Fullscreen is disabled on iPhone but works on other mobile and desktop browsers.

Demo

https://svelte-video-player.netlify.app/

Installation

npm install svelte-video-player

Requires Svelte 5.

Usage

Provide width and height props matching the video's real dimensions to calculate the correct aspect ratio and prevent CLS. The player's actual size is determined by its parent element.

<script>
  import VideoPlayer from 'svelte-video-player';
</script>

<VideoPlayer
  poster="https://example.com/poster.jpg"
  source="https://example.com/video.mp4"
/>

Multiple sources

Pass an array to provide fallback formats:

<VideoPlayer
  source={['video.mp4', 'video.webm']}
/>

HLS streaming

HLS streams are auto-detected from .m3u8 URLs. hls.js is lazy-loaded only when needed.

<VideoPlayer source="https://example.com/stream.m3u8" />

DASH streaming

DASH streams are auto-detected from .mpd URLs. dashjs is lazy-loaded only when needed.

<VideoPlayer source="https://example.com/stream.mpd" />

Subtitles / Captions

A CC toggle button appears automatically when tracks are provided. Track selection is available in the settings menu. The crossorigin attribute is set automatically when tracks are present.

<VideoPlayer
  source="video.mp4"
  tracks={[
    { src: '/subs/en.vtt', srclang: 'en', label: 'English', default: true },
    { src: '/subs/es.vtt', srclang: 'es', label: 'Spanish' }
  ]}
/>

Chapters

<VideoPlayer
  source="video.mp4"
  chapters={[
    { time: 0, label: 'Intro' },
    { time: 60, label: 'Chapter 1' },
    { time: 180, label: 'Chapter 2' }
  ]}
/>

Media Session

Integrate with the browser's Media Session API for OS-level media controls:

<VideoPlayer
  source="video.mp4"
  mediaSession={{
    title: 'My Video',
    artist: 'Author',
    album: 'Collection',
    artwork: [{ src: '/art.jpg', sizes: '512x512', type: 'image/jpeg' }]
  }}
/>

Props

PropTypeDefaultDescription
widthnumber | string1920Real video width for aspect ratio calculation
heightnumber | string1080Real video height for aspect ratio calculation
posterstring''Poster image URL
sourcestring | string[]''Video source URL(s) โ€” supports mp4, webm, ogg, m3u8, mpd
loopbooleanfalseLoop playback
autoplaybooleanfalseAutoplay on load
playsinlinebooleantruePlay inline on mobile
preloadstring'metadata'Preload behavior (none, metadata, auto)
crossoriginstringundefinedCORS mode (auto-set to anonymous when tracks are provided)
skipSecondsnumber | string5Seconds to skip with arrow keys
controlsOnPausebooleantrueShow controls when paused
timeDisplaybooleantrueShow current time / duration
remainingTimebooleanfalseShow remaining time instead of current time
playbackRateControlbooleantrueEnable playback rate control in settings menu
tracksTextTrackConfig[][]Subtitle/caption tracks
chaptersChapter[][]Chapter markers on the progress bar
mediaSessionMediaSessionConfigundefinedMedia Session API metadata
currentTimenumber0Bindable. Use bind:currentTime to read playback position or seek by writing to it.

Styling props

PropTypeDefaultDescription
colorstring'#FF3E00'Main color of controls
playerBgColorstring'black'Player background color
iconColorstring'white'Button icon color
focusColorstring'white'Focus outline color
barsBgColorstring'white'Track background color
borderColorstring'none'Player border color (set to a color value to show border)
controlsHeightstring'55px'Height of bottom control bar
trackHeightstring'4px'Height of playbar and volume tracks
thumbSizestring'15px'Size of slider thumbs
centerIconSizestring'60px'Size of center play icon
borderRadiusstring'8px'Player corner radius
buttonBorderRadiusstring'50%'Button corner radius

Keyboard shortcuts

KeyAction
SpacePlay / Pause
Left / Right arrowSkip backward / forward
TabNavigate controls
Enter / SpaceActivate focused control
EscapeClose settings menu
< / >Decrease / Increase playback rate

SSR

The component renders a server-side placeholder matching the video's aspect ratio. The full player hydrates on the client.

License

MIT