Video Embed Player API
You can use our JavaScript API to listen to and control the embed player. Our iframe player is compatible with the player.js API standard by Embedly.
1. Setup
First, include the player.js library in your page:
CDN
<script type="text/javascript" src="//cdn.embed.ly/player-0.1.0.min.js"></script>Next, initialize the player with your iframe:
// Get reference to your iframe element
const iframe = document.getElementById('your-iframe-id');
// Create player instance
const player = new playerjs.Player(iframe);
// Wait for player to be ready before interacting
player.on('ready', () => {
console.log('Player is ready!');
// Now you can safely use player methods
});Always wait for the ready event before calling player methods. The player will queue messages until ready is fired.
2. Events (Methods)
These are the methods you can call on the player to control playback:
Playback Control
play() - Start playback
player.play();pause() - Pause playback
player.pause();Volume Control
mute() - Mute the player
player.mute();unmute() - Unmute the player
player.unmute();setVolume(volume) - Set volume (0-100)
player.setVolume(50); // Set to 50%Seeking
setCurrentTime(seconds) - Seek to specific time
player.setCurrentTime(30); // Seek to 30 secondsState Queries
getPaused(callback) - Check if player is paused
player.getPaused((paused) => {
console.log('Player is paused:', paused);
});getMuted(callback) - Check if player is muted
player.getMuted((muted) => {
console.log('Player is muted:', muted);
});getVolume(callback) - Get current volume (0-100)
player.getVolume((volume) => {
console.log('Current volume:', volume);
});getDuration(callback) - Get video duration in seconds
player.getDuration((duration) => {
console.log('Video duration:', duration, 'seconds');
});getCurrentTime(callback) - Get current playback time
player.getCurrentTime((time) => {
console.log('Current time:', time, 'seconds');
});Text Tracks (Captions & Subtitles)
The text track methods are not part of the built-in player.js library, so you need to bind them once. Add the following helper and call it inside your ready handler:
function bindTextTrackMethods(player) {
player.enableTextTrack = (value, callback) =>
player.send({ method: 'enableTextTrack', value }, callback);
player.disableTextTrack = () => player.send({ method: 'disableTextTrack' });
player.getTextTracks = (callback) => player.send({ method: 'getTextTracks' }, callback);
player.getTextTrack = (callback) => player.send({ method: 'getTextTrack' }, callback);
}
player.on('ready', () => {
bindTextTrackMethods(player);
});Only subtitle and caption tracks are exposed. Chapter tracks are excluded. Each track is an object with language, kind, label, and mode fields.
getTextTracks(callback) - Get all available text tracks
player.getTextTracks((tracks) => {
// [{ language, kind, label, mode }, ...]
console.log('Available text tracks:', tracks);
});getTextTrack(callback) - Get the active text track, or null when text tracks are off
player.getTextTrack((track) => {
console.log('Active text track:', track);
});enableTextTrack(track, callback) - Enable a text track by language, or by language and kind
If you pass only a language and it matches more than one track, the player prefers an exact language match, then subtitles over captions. The optional callback receives the enabled track.
// Enable by language
player.enableTextTrack('en');
// Enable by language and kind (when both exist for the same language)
player.enableTextTrack({ language: 'en', kind: 'captions' });
// Read the enabled track from the optional callback
player.enableTextTrack('en', (track) => {
console.log('Enabled text track:', track);
});disableTextTrack() - Turn off text tracks
player.disableTextTrack();3. Listeners (Events)
These are the events you can listen to for player state changes:
Basic Events
ready - Fired when the player is ready to receive commands
player.on('ready', () => {
console.log('Player is ready for interaction');
});play - Fired when playback starts
player.on('play', () => {
console.log('Playback started');
});pause - Fired when playback is paused
player.on('pause', () => {
console.log('Playback paused');
});ended - Fired when playback ends
player.on('ended', () => {
console.log('Playback finished');
});Progress Events
timeupdate - Fired during playback with current time/duration data
player.on('timeupdate', (data) => {
console.log('Current time:', data.seconds);
console.log('Duration:', data.duration);
// Calculate progress percentage
const progress = (data.seconds / data.duration) * 100;
console.log('Progress:', progress + '%');
});progress - Fired during loading with buffering progress data
player.on('progress', (data) => {
console.log('Buffering progress:', data.percent * 100 + '%');
});Text Track Events
texttrackchange - Fired when the active text track changes, either through the API or the in-player controls
player.on('texttrackchange', (track) => {
// `track` is the active track object, or null when text tracks are off
console.log('Active text track:', track ? track.language : 'off');
});texttrackerror - Fired when enableTextTrack cannot resolve a matching track
player.on('texttrackerror', (error) => {
// error.name: 'InvalidTrackLanguageError' | 'InvalidTrackError'
console.error('Text track error:', error.name);
});For live streams, subtitle tracks are discovered as the manifest loads and may not be available immediately after ready. Query getTextTracks again once playback has started to pick up late-arriving tracks. The texttrackchange event only fires when the active track changes, so don’t rely on it to detect newly discovered tracks.
Error Handling
error - Fired when an error occurs
player.on('error', (error) => {
console.error('Player error:', error);
});Complete Example
Here’s a complete example showing how to set up and use the player API:
// Initialize player
const iframe = document.getElementById('video-player');
const player = new playerjs.Player(iframe);
// Bind the text track methods (not part of the built-in player.js library)
function bindTextTrackMethods(player) {
player.enableTextTrack = (value, callback) =>
player.send({ method: 'enableTextTrack', value }, callback);
player.disableTextTrack = () => player.send({ method: 'disableTextTrack' });
player.getTextTracks = (callback) => player.send({ method: 'getTextTracks' }, callback);
player.getTextTrack = (callback) => player.send({ method: 'getTextTrack' }, callback);
}
// Set up event listeners
player.on('ready', () => {
console.log('Player ready!');
bindTextTrackMethods(player);
// Get initial state
player.getDuration((duration) => {
console.log('Video duration:', duration);
});
player.getVolume((volume) => {
console.log('Current volume:', volume);
});
// List available text tracks
player.getTextTracks((tracks) => {
console.log('Text tracks:', tracks);
});
});
player.on('play', () => {
console.log('Started playing');
});
player.on('pause', () => {
console.log('Paused');
});
player.on('timeupdate', (data) => {
// Update progress bar
const progress = (data.seconds / data.duration) * 100;
document.getElementById('progress-bar').style.width = progress + '%';
});
player.on('ended', () => {
console.log('Video finished');
});
player.on('texttrackchange', (track) => {
console.log('Active text track:', track ? track.language : 'off');
});
player.on('texttrackerror', (error) => {
console.error('Text track error:', error.name);
});
player.on('error', (error) => {
console.error('Error:', error);
});
// Example control functions
function playVideo() {
player.play();
}
function pauseVideo() {
player.pause();
}
function setVolume(volume) {
player.setVolume(volume);
}
function seekTo(seconds) {
player.setCurrentTime(seconds);
}
function enableSubtitles(language) {
player.enableTextTrack(language);
}
function disableSubtitles() {
player.disableTextTrack();
}If you have multiple players on the same page with the same src, you may run into inconsistencies. To avoid this, append a unique identifier (UUID or timestamp) to each iframe’s src.