
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.tsoutputclean-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 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 on-page floating player (“custom PiP”). When the original content is scrolled out of view, VidPly displays the video in a movable, resizable floating shell in the selected corner; when it is scrolled back into view, the player re-docks. The PiP button in the control bar manually locks or unlocks the floating shell. The native browser PiP is automatically suppressed whilst the floating player 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. The function is available underfloatingMinViewportWidth(default768px) and the button for the floating PiP player never appears in the overflow menu.
Example 10: With 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 work with 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 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>
How it works:
- Click the CC button to open the subtitles menu
- Select your preferred language
- Or press C 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 in focus:
- Space bar / P / K – Play/Pause
- F – Full screen
- M – Mute/Unmute
- ↑ / ↓ – Increase/decrease volume
- ← / → – Skip forward/backward 10 seconds
- C – Turn subtitles on/off
- A – Open subtitle style menu
- < / > – Decrease/increase speed
- S – Open speed menu
- Q – Open quality menu
- J – Open chapter menu
- T – Turn transcript on/off
- D – Toggle drag mode (transcript/sign language)
- R – Switch between resize mode (transcript/sign language)
- Home – Reset position (transcript/sign language)
- Esc – Exit mode or close menu
Customise 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 button hover
.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 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 attribute lang , 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 (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, with a mobile breakpoint at 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 (< 768px breakpoint):
- 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 overflow menu for numerous buttons
- Touch-friendly 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
- 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 in production only:
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) – Usedhls.jsin Chrome / Firefox / Edge / Desktop Safari (loaded automatically from the CDN). On iOS / iPadOS, native<video>HLS support is used and integrated via theTextTrackAPI. - DASH (
.mpd) – Useddash.js, automatically loaded from the CDN. - SoundCloud – Detected automatically for every URL that
soundcloud.com; the SoundCloud Widget API is loaded on demand.
<!-- 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 more examples in USAGE.md
- Check out demo/demo.html for live demos
- See PLAYLIST.md for 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? Check the README file or create a ticket.