npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

sveltekit-video-element

v0.0.1

Published

A sveltekit video element component supporting JWPlayer, VideoJS, Cloudflare Stream and multiple video providers

Downloads

115

Readme

SvelteKit Video Elements

A comprehensive SvelteKit video component library with support for multiple video players and streaming platforms. Built with TypeScript, SSR support, and optimized for modern web applications.

📚 Documentation

Features

  • Full SSR Support - Works seamlessly with SvelteKit's server-side rendering
  • TypeScript Support - Complete type definitions for all components
  • Multiple Video Players - Support for 8 different video players and platforms
  • Lightweight - Tree-shakeable, only import what you need
  • Modern - Built with latest web standards and best practices
  • Flexible - Easy to customize and extend

Supported Players

  • JW Player - Professional video player with analytics
  • Cloudflare Stream - Video streaming with Cloudflare's CDN
  • Video.js - Popular open-source video player
  • HLS - HTTP Live Streaming with hls.js
  • DASH - Dynamic Adaptive Streaming with dash.js
  • Mux Video - Professional video hosting and streaming
  • Cloudinary - Video transformation and optimization
  • Custom Player - Bring your own video player

Installation

npm install sveltekit-video-elements

Quick Start

HLS Video

<script>
	import { HlsVideo } from 'sveltekit-video-elements';
</script>

<HlsVideo
	src="https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"
	controls
	autoplay
	poster="https://example.com/poster.jpg"
/>

Mux Video

<script>
	import { MuxVideo } from 'sveltekit-video-elements';
</script>

<MuxVideo
	playbackId="YOUR_PLAYBACK_ID"
	streamType="on-demand"
	controls
	metadata={{
		video_title: 'My Awesome Video',
		viewer_user_id: 'user-123'
	}}
/>

Cloudinary Video

<script>
	import { CloudinaryVideo } from 'sveltekit-video-elements';
</script>

<CloudinaryVideo
	cloudName="your-cloud-name"
	publicId="your-video-id"
	transformation={{
		quality: 'auto',
		width: 1280,
		height: 720,
		crop: 'fill'
	}}
	controls
/>

Video.js

<script>
	import { VideoJsVideo } from 'sveltekit-video-elements';
</script>

<VideoJsVideo
	src="https://example.com/video.mp4"
	controls
	options={{
		fluid: true,
		aspectRatio: '16:9'
	}}
/>

JW Player

<script>
	import { JwPlayerVideo } from 'sveltekit-video-elements';
</script>

<JwPlayerVideo
	playerId="YOUR_PLAYER_ID"
	mediaId="YOUR_MEDIA_ID"
	controls
	config={{
		aspectratio: '16:9',
		skin: {
			name: 'bekle'
		}
	}}
/>

Cloudflare Stream

<script>
	import { CloudflareVideo } from 'sveltekit-video-elements';
</script>

<CloudflareVideo videoId="YOUR_VIDEO_ID" accountId="YOUR_ACCOUNT_ID" controls autoplay />

DASH Video

<script>
	import { DashVideo } from 'sveltekit-video-elements';
</script>

<DashVideo
	src="https://example.com/video.mpd"
	controls
	dashConfig={{
		streaming: {
			lowLatencyEnabled: true,
			bufferTimeDefault: 4
		}
	}}
/>

Custom Player

<script>
	import { CustomVideo } from 'sveltekit-video-elements';

	let myCustomPlayer = {
		init: async (element, config) => {
			// Initialize your custom player
			const player = new YourVideoPlayer(element);
			player.load(config.src);
			return player;
		}
	};
</script>

<CustomVideo
	src="https://example.com/video.mp4"
	customPlayer={myCustomPlayer}
	controls
	onPlayerReady={(player) => {
		console.log('Player ready:', player);
	}}
/>

Common Props

All video components support these common HTML5 video attributes:

| Prop | Type | Default | Description | | ------------- | ---------------------------------- | ------------ | --------------------- | | src | string | undefined | Video source URL | | poster | string | undefined | Poster image URL | | controls | boolean | true | Show video controls | | autoplay | boolean | false | Auto-play video | | loop | boolean | false | Loop video playback | | muted | boolean | false | Mute audio | | preload | 'none' \| 'metadata' \| 'auto' | 'metadata' | Preload strategy | | width | number \| string | '100%' | Video width | | height | number \| string | 'auto' | Video height | | crossorigin | 'anonymous' \| 'use-credentials' | undefined | CORS setting | | playsinline | boolean | false | Play inline on mobile | | class | string | '' | CSS class |

Component-Specific Props

HlsVideo

{
  hlsConfig?: {
    autoStartLoad?: boolean;
    startPosition?: number;
    debug?: boolean;
    maxBufferLength?: number;
    lowLatencyMode?: boolean;
    // ... and many more hls.js options
  }
}

MuxVideo

{
  playbackId: string;
  streamType?: 'on-demand' | 'live' | 'live:dvr';
  tokens?: {
    playback?: string;
    thumbnail?: string;
    storyboard?: string;
  };
  metadata?: {
    video_id?: string;
    video_title?: string;
    viewer_user_id?: string;
  };
  envKey?: string; // For Mux Data analytics
  customDomain?: string;
  maxResolution?: string;
  minResolution?: string;
}

CloudinaryVideo

{
  cloudName: string;
  publicId: string;
  transformation?: {
    quality?: string | number;
    width?: number;
    height?: number;
    crop?: string;
    gravity?: string;
    effect?: string;
    startOffset?: number | string;
    endOffset?: number | string;
    duration?: number | string;
  };
  sourceTypes?: string[]; // Default: ['mp4', 'webm', 'ogv']
  secure?: boolean; // Default: true
}

VideoJsVideo

{
  options?: {
    fluid?: boolean;
    aspectRatio?: string;
    controlBar?: object;
    // ... all Video.js options
  };
  plugins?: {
    [pluginName: string]: any;
  };
}

JwPlayerVideo

{
  playerId: string;
  mediaId?: string;
  libraryUrl?: string;
  config?: {
    aspectratio?: string;
    skin?: object;
    advertising?: object;
    // ... all JW Player options
  };
}

CloudflareVideo

{
  videoId: string;
  accountId: string;
  streamUrl?: string;
  signedUrl?: string;
  thumbnailTime?: number;
}

DashVideo

{
  dashConfig?: {
    streaming?: {
      lowLatencyEnabled?: boolean;
      bufferTimeDefault?: number;
      retryAttempts?: object;
      // ... all dash.js options
    };
    debug?: {
      logLevel?: number;
    };
  };
}

CustomVideo

{
  customPlayer: {
    init: (element: HTMLElement, config: any) => Promise<any> | any;
  } | Function;
  playerConfig?: Record<string, any>;
  onPlayerReady?: (player: any) => void;
}

Events

All components forward standard HTML5 video events:

<HlsVideo
	src="..."
	on:play={(e) => console.log('Playing')}
	on:pause={(e) => console.log('Paused')}
	on:ended={(e) => console.log('Ended')}
	on:timeupdate={(e) => console.log('Time update')}
	on:error={(e) => console.log('Error', e.detail)}
/>

Available Events

  • loadstart
  • loadedmetadata
  • loadeddata
  • canplay
  • canplaythrough
  • play
  • pause
  • ended
  • timeupdate
  • volumechange
  • seeking
  • seeked
  • waiting
  • durationchange
  • progress
  • error

Player-Specific Events

HlsVideo also emits:

  • hlsmanifestparsed
  • hlslevelswitched
  • hlsfragloaded

DashVideo also emits:

  • dashmanifestloaded
  • dashstreaminitialized
  • dashqualitychanged
  • dashbufferloaded
  • dashfragmentloaded

Methods

All components expose methods via component references:

<script>
	import { HlsVideo } from 'sveltekit-video-elements';

	let videoRef;

	function handlePlay() {
		videoRef.play();
	}

	function handlePause() {
		videoRef.pause();
	}

	function getElement() {
		const element = videoRef.getVideoElement();
		console.log('Current time:', element.currentTime);
	}
</script>

<HlsVideo bind:this={videoRef} src="..." />
<button on:click={handlePlay}>Play</button>
<button on:click={handlePause}>Pause</button>

Common Methods

  • play() - Play video
  • pause() - Pause video
  • getVideoElement() - Get underlying video element
  • getPlayer() - Get player instance (where applicable)

Player-Specific Methods

HlsVideo:

  • getHls() - Get hls.js instance
  • getCurrentLevel() - Get current quality level
  • setCurrentLevel(level) - Set quality level
  • getLevels() - Get available quality levels

DashVideo:

  • getBitrateInfoListFor(type) - Get available bitrates
  • setQualityFor(type, index) - Set quality
  • getQualityFor(type) - Get current quality
  • setAutoSwitchQualityFor(type, value) - Enable/disable ABR

MuxVideo:

  • getMuxInstance() - Get Mux Data instance

CloudinaryVideo:

  • getTransformationUrl(transformation) - Get URL with transformations

Advanced Usage

Using with SvelteKit Load Functions

// +page.server.ts
export async function load() {
	return {
		videoSrc: 'https://example.com/video.m3u8',
		posterUrl: 'https://example.com/poster.jpg'
	};
}
<!-- +page.svelte -->
<script>
	import { HlsVideo } from 'sveltekit-video-elements';

	export let data;
</script>

<HlsVideo src={data.videoSrc} poster={data.posterUrl} controls />

Adaptive Streaming with HLS

<script>
	import { HlsVideo } from 'sveltekit-video-elements';

	let videoRef;
	let levels = [];
	let currentLevel = -1;

	function handleManifestParsed() {
		levels = videoRef.getLevels();
		currentLevel = videoRef.getCurrentLevel();
	}

	function setQuality(level) {
		videoRef.setCurrentLevel(level);
	}
</script>

<HlsVideo bind:this={videoRef} src="..." on:hlsmanifestparsed={handleManifestParsed} />

<select value={currentLevel} on:change={(e) => setQuality(+e.target.value)}>
	<option value={-1}>Auto</option>
	{#each levels as level, i}
		<option value={i}>{level.height}p - {(level.bitrate / 1000000).toFixed(2)} Mbps</option>
	{/each}
</select>

Dynamic Cloudinary Transformations

<script>
	import { CloudinaryVideo } from 'sveltekit-video-elements';

	let quality = 'auto';
	let width = 1280;
	let effect = '';

	$: transformation = {
		quality,
		width,
		...(effect && { effect })
	};
</script>

<CloudinaryVideo cloudName="demo" publicId="video-sample" {transformation} controls />

<input type="range" bind:value={width} min="640" max="1920" />
<select bind:value={quality}>
	<option value="auto">Auto</option>
	<option value="80">High</option>
	<option value="50">Medium</option>
	<option value="30">Low</option>
</select>
<input bind:value={effect} placeholder="Effect (e.g., sepia)" />

TypeScript Support

Full TypeScript support with comprehensive type definitions:

import type {
	HlsVideoProps,
	MuxVideoProps,
	CloudinaryVideoProps,
	VideoPlayerInstance
} from 'sveltekit-video-elements';

const props: HlsVideoProps = {
	src: 'https://example.com/video.m3u8',
	controls: true,
	hlsConfig: {
		debug: true,
		lowLatencyMode: true
	}
};

Utilities

The library exports useful utility functions:

import {
	buildCloudinaryUrl,
	buildMuxUrl,
	buildCloudflareStreamUrl,
	generateId,
	isBrowser,
	loadScript,
	debounce,
	throttle
} from 'sveltekit-video-elements';

// Build a Cloudinary URL
const url = buildCloudinaryUrl('demo', 'video-id', {
	quality: 'auto',
	width: 1280
});

// Build a Mux URL
const muxUrl = buildMuxUrl('playback-id', {
	maxResolution: '1080p'
});

// Check if running in browser
if (isBrowser()) {
	// Browser-only code
}

Browser Support

  • Chrome/Edge 90+
  • Firefox 88+
  • Safari 14+
  • iOS Safari 14+
  • Android Chrome 90+

Performance Tips

  1. Use preload="none" for videos not immediately visible
  2. Enable lazy loading with Intersection Observer
  3. Use appropriate video formats (HLS for adaptive streaming)
  4. Optimize poster images
  5. Consider using CDN for video delivery

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT

Credits

Built with inspiration from media-elements by Mux.

Support

For issues and questions, please open an issue on GitHub.