
Quick installation
1. Download the code
git clone github.com/MatthiasPeltzer/vidply.git
cd vidply
2. Install dependencies
npm install
This will install the following:
esbuild- Fast TypeScript/JavaScript bundlertypescript- Strict type checking and.d.tsgenerationclean-css- CSS minifiervitest+@playwright/test- Unit and end-to-end tests
3. Creating the player
npm run build
This generates production-ready files in dist/:
prod/vidply.esm.min.js- Minified ES module (recommended for production)legacy/vidply.min.js- Minified IIFE bundle (globalVidPly)types/index.d.ts- TypeScript type declarations for IDE /tscusersvidply.min.css- Minified styles (~12 KB)
4. Watch the demo
npm run dev
Open http://localhost:3000/demo/ to see VidPly in action!
Your first video player
Create index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Video Player</title>
<link rel="stylesheet" href="dist/vidply.min.css">
</head>
<body>
<h1>My Video Player</h1>
<video
data-vidply
width="800"
height="450"
poster="poster.jpg"
>
<source src="video.mp4" type="video/mp4">
<track
kind="captions"
src="captions.vtt"
srclang="en"
label="English"
>
</video>
<script type="module">
import Player from './dist/prod/vidply.esm.min.js';
// That's it! Player auto-initializes
</script>
</body>
</html>
Test
# Start a local server
npm run dev
# Or use Python
python -m http.server 3000
# Or use PHP
php -S localhost:3000
Open http://localhost:3000 in your browser.
Quick start in 3 steps
If you simply want to use the source files directly without compiling them:
Step 1: Insert the CSS
<link rel="stylesheet" href="src/styles/vidply.css">
Step 2: Add your video
<video data-vidply width="800" height="450">
<source src="your-video.mp4" type="video/mp4">
</video>
Step 3: Import the player
<script type="module">
import Player from './src/index.js';
</script>
That’s it!
Simple examples
Example 1: Simple video
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="src/styles/vidply.css">
</head>
<body>
<video data-vidply src="video.mp4" width="800" height="450"></video>
<script type="module">
import Player from './src/index.js';
</script>
</body>
</html>
Example 2: Audio player
<audio data-vidply>
<source src="music.mp3" type="audio/mpeg">
<track kind="captions" src="lyrics.vtt" srclang="en" label="Lyrics">
</audio>
Example 3: YouTube video
<video
data-vidply
src="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
></video>
Example 4: Vimeo video
<video
data-vidply
src="https://vimeo.com/76979871"
></video>
Example 5: SoundCloud track
<audio
data-vidply
src="https://soundcloud.com/artist/track-name"
></audio>
Example 6: HLS streaming
<video
data-vidply
src="https://example.com/stream.m3u8"
></video>
Example 7: DASH streaming
<video
data-vidply
src="https://example.com/video/dash/manifest.mpd"
></video>
Example 8: With download button
<video
data-vidply
data-vidply-download-button="true"
data-vidply-download-url="/files/lecture.mp4"
src="/streams/lecture/manifest.mpd">
</video>
Example 9: With the custom floating player
Enable the in-page floating player (‘custom PiP’). When the original page is scrolled out of the viewport, VidPly displays the video in a movable and resizable floating window in the selected corner; when the page is scrolled back into the viewport, the player is docked again. The PiP button in the control bar can be used to manually dock or undock the floating window. The browser’s native PiP function is automatically disabled whilst floating mode is active.
<video
data-vidply
data-vidply-options='{"floating": true, "floatingPosition": "bottom-right", "floatingMinViewportWidth": 768}'
src="video.mp4"
width="800" height="450">
<track kind="subtitles" src="captions.vtt" srclang="en" label="English">
</video>
Ignore audio player
floating. This function is located belowfloatingMinViewportWidth(default768px) and the PiP button for the floating player never appears in the overflow menu.
Example 10: Using options
<video
data-vidply
data-vidply-options='{"autoplay": true, "loop": true, "muted": true}'
src="video.mp4"
></video>
Example 11: Manual initialisation
<video id="my-video" src="video.mp4"></video>
<script type="module">
import Player from './dist/prod/vidply.esm.min.js';
const player = new Player('#my-video', {
controls: true,
autoplay: false,
volume: 0.8,
language: 'en'
});
player.on('ready', () => {
console.log('Player is ready!');
});
</script>
Do you use TypeScript? Import directly from the source code directory (
import Player from 'vidply') – VidPly provides its own.d.tsdeclarations, giving you full type safetyPlayerOptions, events and the renderer APIs.
Configuration
About data attributes
<video
data-vidply
data-vidply-options='{
"autoplay": true,
"loop": true,
"volume": 0.5,
"language": "de"
}'
src="video.mp4"
></video>
About JavaScript
const player = new Player('#my-video', {
controls: true,
autoplay: false,
loop: false,
volume: 0.8,
playbackSpeed: 1.0,
captions: true,
captionsDefault: true,
keyboard: true,
language: 'en',
responsive: true
});
General options
{
// Playback
autoplay: false, // Auto-start playback
loop: false, // Loop video
muted: false, // Start muted
volume: 0.8, // Volume (0-1)
playbackSpeed: 1.0, // Speed (0.25-2.0)
// Display
responsive: true, // Responsive sizing
controls: true, // Show controls
// Captions
captions: true, // Enable captions
captionsDefault: false, // Show captions by default
// Accessibility
keyboard: true, // Keyboard shortcuts
// Language
language: 'en' // UI language (en, es, fr, de, ja)
}
Multilingual captions
<video data-vidply src="video.mp4">
<track kind="captions" src="en.vtt" srclang="en" label="English">
<track kind="captions" src="es.vtt" srclang="es" label="Español">
<track kind="captions" src="fr.vtt" srclang="fr" label="Français">
<track kind="captions" src="de.vtt" srclang="de" label="Deutsch">
</video>
Here’s how it works:
- Click the ‘CC’ button to open the subtitles menu
- Select your preferred language
- Or press the ‘C’ key to open the menu (if multiple audio tracks are available)
- The active audio track is marked with a tick
Create subtitles (WebVTT)
Create a file named captions.vtt:
WEBVTT
00:00:00.000 --> 00:00:05.000
Welcome to my video!
00:00:05.000 --> 00:00:10.000
This is how captions work.
00:00:10.000 --> 00:00:15.000
Pretty easy, right?
Player controls
const player = new Player('#video');
// Playback
player.play();
player.pause();
player.stop();
player.seek(60); // Jump to 1 minute
// Volume
player.setVolume(0.5); // 50% volume
player.mute();
player.unmute();
// Speed
player.setPlaybackSpeed(1.5); // 1.5x speed
// Fullscreen
player.enterFullscreen();
player.exitFullscreen();
// Captions
player.enableCaptions();
player.disableCaptions();
// Events
player.on('play', () => console.log('Playing!'));
player.on('pause', () => console.log('Paused'));
player.on('ended', () => console.log('Finished'));
player.on('timeupdate', (time) => {
console.log('Current time:', time);
});
Keyboard shortcuts
Once the player is active:
- Space bar / P / K – Play/Pause
- F – Full screen
- M – Mute/Unmute
- ↑ / ↓ – Increase/decrease volume
- ← / → – Skip forwards/backwards 10 seconds
- C – Turn subtitles on/off
- A – Open subtitle style menu
- < / > – Decrease/increase playback speed
- S – Open the ‘Playback speed’ menu
- Q – Open the quality menu
- J – Open the chapter menu
- T – Switch transcript on/off
- D – Toggle drag mode (transcript/sign language)
- R – Toggle zoom mode (transcript/sign language)
- Home – Reset position (transcript/sign language)
- Esc – Exit mode or close menu
Customising styles
Override CSS variables
.vidply-player {
--vidply-primary-color: #ff0000;
--vidply-background: rgba(0, 0, 0, 0.9);
}
Custom progress bar
.vidply-progress-played {
background: linear-gradient(90deg, #ff0000, #ff00ff);
}
Custom hover effect for buttons
.vidply-button:hover {
background: rgba(255, 0, 0, 0.2);
}
Change language
Supported languages
VidPly includes translations for 5 languages:
en- Englishes- Spanish (Español)fr- French (Français)de- Germanja- Japanese (日本語)
const player = new Player('#video', {
language: 'de' // German UI
});
Custom translations
You can add your own translations by loading language files via URLs. The player supports the JSON and YAML formats.
Using data attributes
Loading multiple language files:
<video
data-vidply
data-vidply-language-files='{"pt": "languages/pt.json", "it": "languages/it.json"}'
src="video.mp4"
></video>
Loading a single language file:
<video
data-vidply
data-vidply-language-file='{"pt": "languages/pt.json"}'
src="video.mp4"
></video>
Or use separate attributes:
<video
data-vidply
data-vidply-language-file-code="pt"
data-vidply-language-file-url="languages/pt.json"
src="video.mp4"
></video>
Using JavaScript options
const player = new Player('#video', {
language: 'pt', // Set language after loading
languageFiles: {
'pt': 'languages/pt.json',
'it': 'languages/it.json'
}
});
Language file format (JSON)
Create a file languages/pt.json:
{
"player": {
"play": "Reproduzir",
"pause": "Pausar",
"mute": "Silenciar",
"unmute": "Ativar som",
"fullscreen": "Tela cheia",
"exitFullscreen": "Sair da tela cheia",
"captions": "Legendas",
"settings": "Configurações"
},
"time": {
"currentTime": "Tempo atual",
"duration": "Duração"
}
}
Automatic detection from HTML
The player automatically detects the language based on the HTML lang attribute, provided a suitable translation is available:
<html lang="pt">
<video data-vidply
data-vidply-language-file='{"pt": "languages/pt.json"}'
src="video.mp4">
</video>
</html>
Programmatic loading of translations
import { i18n } from './src/i18n/i18n.js';
// Load a language file
await i18n.loadLanguageFromUrl('pt', 'languages/pt.json');
// Or load multiple languages
await i18n.loadLanguagesFromUrls({
'pt': 'languages/pt.json',
'it': 'languages/it.json'
});
// Set the language
i18n.setLanguage('pt');
Development mode
Enable debug logging:
const player = new Player('#video', {
debug: true
});
Check the browser console for detailed logs.
Deployment options
Option 1: ES module (modern browsers)
<link rel="stylesheet" href="dist/vidply.min.css">
<script type="module">
import Player from './dist/prod/vidply.esm.min.js';
</script>
Option 2: Traditional script tag (IIFE)
<link rel="stylesheet" href="dist/vidply.min.css">
<script src="dist/legacy/vidply.min.js"></script>
<script>
const player = new VidPly.Player('#video');
</script>
Option 3: CDN (in future)
<!-- Will be available after publishing to npm -->
<link rel="stylesheet" href="https://cdn.example.com/vidply@1.0.0/vidply.min.css">
<script type="module">
import Player from 'https://cdn.example.com/vidply@1.0.0/vidply.esm.min.js';
</script>
Optimisation for mobile devices
VidPly is mobile-friendly by default and uses a mobile breakpoint of 768px. For best results:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
And use responsive mode:
const player = new Player('#video', {
responsive: true
});
Mobile-specific behaviour (breakpoint < 768px):
- The transcript window appears below the video (cannot be moved or resized)
- The sign language video cannot be moved or resized
- Optimised control bar with an overflow menu for numerous buttons
- Touch-friendly user interface with touch targets of at least 44px
- Minimum width of the transcript window: 300px
Accessibility
VidPly is WCAG 2.2 AA-compliant by default:
- Full keyboard navigation
- Support for screen readers
- High-contrast mode
- Focus indicators
- ARIA labels
No additional configuration required!
Troubleshooting
Video won’t play
- Check the console for errors (press F12)
- Check that the video URL is correct
- Check the CORS headers if the video is being loaded from a different domain
- Enable debug mode:
{ debug: true }
Subtitles are not displayed
- Check that the VTT file format is correct
- Check the file path
- To enable subtitles: Click the ‘CC’ button
- Or enable by default:
{ captionsDefault: true }
Creation failed
# Clean and rebuild
npm run clean
rm -rf node_modules
npm install
npm run build
Autoplay is not working
Browsers block automatic playback with sound. Solution:
const player = new Player('#video', {
autoplay: true,
muted: true // Required for autoplay
});
Available build scripts
npm run build # Build everything
npm run build:js # Build JS only
npm run build:css # Build CSS only
npm run watch # Watch mode for development
npm run clean # Clean dist/
npm run dev # Start dev server (port 3000)
npm start # Alias for npm run dev
File structure
Once created, you will receive:
vidply/
├── dist/
│ ├── dev/
│ │ └── vidply.esm.js # ES Module (dev)
│ ├── prod/
│ │ └── vidply.esm.min.js # ES Module (prod)
│ ├── legacy/
│ │ ├── vidply.js # IIFE (dev)
│ │ └── vidply.min.js # IIFE (prod)
│ ├── types/
│ │ └── index.d.ts # TypeScript declarations
│ ├── vidply.css # Styles (dev)
│ └── vidply.min.css # Styles (prod)
└── ...
Include only in the production environment:
dist/prod/vidply.esm.min.js(ordist/legacy/vidply.min.js)dist/vidply.min.css
Total: ~62 KB uncompressed, ~18 KB gzipped
Streaming (HLS & DASH)
VidPly automatically recognises streaming formats based on the file extension:
- HLS (
.m3u8) – Uses hls.js 1.6.16 in Chrome / Firefox / Edge / Desktop Safari (CDN fallback if not pre-installed). On iOS / iPadOS, the native<video>HLS support is utilised and integrated via theTextTrackAPI. - DASH (
.mpd) – Uses dash.js 5.2.0 (modern UMD), which is loaded if required, provided it is not already present on the page. - SoundCloud – Is automatically detected for any URL that
soundcloud.com; the SoundCloud Widget API is loaded as required.
<!-- HLS -->
<video data-vidply src="https://example.com/stream.m3u8"></video>
<!-- DASH -->
<video data-vidply src="https://example.com/manifest.mpd"></video>
<!-- SoundCloud -->
<audio data-vidply src="https://soundcloud.com/artist/track-name"></audio>
All formats support adaptive quality selection and subtitles. DASH streams with embedded TTML subtitles are rendered natively by dash.js, whilst WebVTT subtitles are processed by VidPly’s subtitling system and also support the interactive transcript.
Next steps
- You can find further examples in the “USAGE.md” file
- Take a look at “demo/demo.html” for live demos
- For information on playlist features, see Playlist Features
- Read “BUILD.md” for build customisations
Tips
- Always use a local server – do not open HTML files directly (file://)
- Enable subtitles by default for better accessibility
- Use responsive mode to support mobile devices
- Test keyboard shortcuts to ensure accessibility
- Check the browser console for helpful debug messages
You’re all set!
That’s it! You now know how to:
- Install and create
- Create video/audio players
- Add subtitles
- Configure options
- control playback
- Customise styles
Enjoy coding!
Need help? Have a look at the README file or create an issue.