Skip to Content

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:

<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 seconds

State 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.