JS Control & Events - Kaltura Player
JS Control (Play/Pause/Seek/Volume)
With dynamic JS embeds, the player instance exposes standard controls:
// Play / Pause
player.play();
player.pause();
// Seek (seconds)
player.currentTime = 90;
// Volume (0.0 – 1.0)
player.volume = 0.5;
These APIs are part of the web player's base interface. Key properties and methods:
| API | Type | Description |
|---|---|---|
player.play() | method | Start playback |
player.pause() | method | Pause playback |
player.currentTime | get/set | Current playback position in seconds |
player.duration | get | Total media duration in seconds |
player.volume | get/set | Volume level (0.0 – 1.0) |
player.muted | get/set | Mute state (boolean) |
player.playbackRate | get/set | Playback speed (1.0 = normal) |
player.isLive() | method | Whether the current media is a live stream |
player.ready() | method | Returns a Promise that resolves when the player is ready for interaction |
player.loadMedia({entryId}) | method | Load a new media entry into the player |
Binding to JS Player Events
The Kaltura player exposes a DOM-style event system and a Promise for readiness. Use it for analytics beacons, UI reactions, gated flows, etc.
Player core events consist of two event types:
- HTML5 Video Events — Standard events from the underlying
<video>element - Player Custom Events — Events specific to the Kaltura player that extend beyond standard HTML5 video
All core events are accessible via player.Event.Core as shown in the example below.
HTML5 Video Events
| Event | Constant | Callback Payload |
|---|---|---|
| Play | PLAY | No payload. Fired when playback is requested (before media actually starts playing). |
| Pause | PAUSE | No payload. Fired when playback is paused. |
| Ended | ENDED | No payload. Fired when playback reaches the end of the media. |
| Seeking | SEEKING | No payload. The player's currentTime property reflects the target seek position. |
| Seeked | SEEKED | No payload. Fired when a seek operation completes. |
| Time Update | TIME_UPDATE | No payload. Fired continuously during playback (typically every 250ms). Read player.currentTime and player.duration for position data. |
| Volume Change | VOLUME_CHANGE | No payload. Read player.volume (0.0-1.0) for the new volume level. |
| Waiting | WAITING | No payload. Fired when playback stalls due to buffering. |
| Playing | PLAYING | No payload. Fired when playback resumes after buffering or pause. |
| Can Play | CANPLAY | No payload. Fired when enough data is buffered to begin playback. |
| Loaded Metadata | LOADED_METADATA | No payload. Fired when media metadata (duration, dimensions) is available. Read player.duration for the media length. |
| Loaded Data | LOADED_DATA | No payload. Fired when the first frame of the media is loaded. |
| Duration Change | DURATION_CHANGE | No payload. Fired when player.duration changes (e.g., live stream duration updates). |
| Rate Change | RATE_CHANGE | No payload. Read player.playbackRate for the new rate value. |
| Error | ERROR | event.payload — object with severity (number: 0=CRITICAL, 1=RECOVERABLE), category (number: 1=NETWORK, 2=TEXT, 3=MEDIA, 4=MANIFEST, 5=ENCRYPTION), code (number), and data (error details object). |
Player Custom Events
| Event | Constant | Callback Payload |
|---|---|---|
| Player State Changed | PLAYER_STATE_CHANGED | event.payload.oldState — object with type (string: "idle", "loading", "playing", "paused", "buffering"). event.payload.newState — object with type (same values). |
| Media Loaded | MEDIA_LOADED | No payload. Fired after loadMedia() resolves and media sources are set. |
| First Play | FIRST_PLAY | No payload. Fired once per media load — the first time play is requested. |
| First Playing | FIRST_PLAYING | No payload. Fired once per media load — the first time media actually renders a frame. |
| Tracks Changed | TRACKS_CHANGED | event.payload.tracks — array of track objects, each with type (string: "video", "audio", "text"), label (string), language (string), active (boolean), and index (number). |
| Text Track Changed | TEXT_TRACK_CHANGED | event.payload.selectedTextTrack — track object with language (string), label (string), kind (string: "subtitles", "captions"), active (boolean), and index (number). |
| Audio Track Changed | AUDIO_TRACK_CHANGED | event.payload.selectedAudioTrack — track object with language (string), label (string), active (boolean), and index (number). |
| Video Track Changed | VIDEO_TRACK_CHANGED | event.payload.selectedVideoTrack — track object with width (number), height (number), bitrate (number), active (boolean), and bandwidth (number). |
| Enter Fullscreen | ENTER_FULLSCREEN | No payload. Fired when the player enters fullscreen mode. |
| Exit Fullscreen | EXIT_FULLSCREEN | No payload. Fired when the player exits fullscreen mode. |
| Enter Picture-in-Picture | ENTER_PICTURE_IN_PICTURE | No payload. Fired when the player enters PiP mode. |
| Exit Picture-in-Picture | EXIT_PICTURE_IN_PICTURE | No payload. Fired when the player exits PiP mode. |
| Source Selected | SOURCE_SELECTED | event.payload.selectedSource — array of source objects, each with mimetype (string), url (string), id (string), bandwidth (number), width (number), height (number). |
| Change Source Started | CHANGE_SOURCE_STARTED | No payload. Fired when a new media source begins loading (e.g., after loadMedia()). |
| Change Source Ended | CHANGE_SOURCE_ENDED | No payload. Fired when the new media source has been applied. |
| Autoplay Failed | AUTOPLAY_FAILED | event.payload — object with error (string, browser's autoplay rejection reason). |
| Mute Change | MUTE_CHANGE | event.payload.mute — boolean, the new mute state. |
| Playback Start | PLAYBACK_START | No payload. Fired once per session when the first play begins (differs from FIRST_PLAY in that it fires after buffering completes). |
| Playback Ended | PLAYBACK_ENDED | No payload. Fired when all media in the playlist or single entry finishes. |
| Ad Started | AD_STARTED | event.payload.adType — string ("preroll", "midroll", "postroll"). event.payload.adPosition — number (ad index). |
| Ad Completed | AD_COMPLETED | event.payload.adType — string. event.payload.adPosition — number. |
| Ad Skipped | AD_SKIPPED | event.payload.adType — string. event.payload.adPosition — number. |
<script>
window.player = player;
function onPlay() { console.log('PLAY'); }
function onPause() { console.log('PAUSE'); }
function onEnded() { console.log('ENDED'); }
function onError(ev){ console.error('ERROR', ev && ev.payload); }
function onSeeking() { console.log('SEEKING...'); }
function onSeeked() { console.log('SEEKED'); }
function onTimeUpdate() { console.log("currentTime: ", player.currentTime); }
player.ready().then(() => {
console.log("player is ready!");
const E = player.Event.Core;
// bind to events:
player.addEventListener(E.PLAY, onPlay);
player.addEventListener(E.PAUSE, onPause);
player.addEventListener(E.ENDED, onEnded);
player.addEventListener(E.ERROR, onError);
player.addEventListener(E.TIME_UPDATE, onTimeUpdate);
player.addEventListener(E.SEEKING, onSeeking);
player.addEventListener(E.SEEKED, onSeeked);
});
window.dispose = function() {
console.log('disposing...');
const E = player.Event.Core;
window.player.removeEventListener(E.PLAY, onPlay);
window.player.removeEventListener(E.PAUSE, onPause);
window.player.removeEventListener(E.ENDED, onEnded);
window.player.removeEventListener(E.ERROR, onError);
window.player.removeEventListener(E.TIME_UPDATE, onTimeUpdate);
window.player.removeEventListener(E.SEEKING, onSeeking);
window.player.removeEventListener(E.SEEKED, onSeeked);
}
</script>
PlayKit Plugin Ecosystem
The Kaltura Player v7 (PlayKit) supports 30+ plugins that extend playback with interactive features. Plugins are configured via the plugins block in KalturaPlayer.setup():
const player = KalturaPlayer.setup({
targetId: 'kplayer',
provider: { partnerId: PARTNER_ID, uiConfId: UICONF_ID, ks: KS },
plugins: {
dualscreen: {}, // enable Dual Screen plugin
transcript: {}, // enable Transcript plugin
navigation: {} // enable Navigation plugin
}
});
Key plugins and their configuration parameters:
Dual Screen (dualscreen)
Multi-stream PIP / side-by-side layout switching for entries with a secondary stream (e.g., slides + presenter).
| Parameter | Type | Default | Description |
|---|---|---|---|
layout | string | "pip" | Initial layout: "pip" (picture-in-picture), "sbs" (side-by-side), "single" (primary only), "singleSecondary" (secondary only) |
mainViewEntryId | string | (auto) | Entry ID for the main (primary) view |
secondaryViewEntryId | string | (auto) | Entry ID for the secondary view |
pip.position | string | "bottom-right" | PiP window position: "top-left", "top-right", "bottom-left", "bottom-right" |
inverse | boolean | false | Swap primary and secondary media in the layout |
childSizeMultiplier | number | 0.3 | PiP window size as a fraction of the player (0.0 - 1.0) |
plugins: {
dualscreen: {
layout: 'sbs',
inverse: false,
childSizeMultiplier: 0.3
}
}
Navigation (navigation)
Chapter-based navigation with thumbnails from cue points defined on the entry.
| Parameter | Type | Default | Description |
|---|---|---|---|
position | string | "right" | Panel position: "right", "left", "top", "bottom" |
expandOnFirstPlay | boolean | true | Auto-expand the navigation panel on first play |
visible | boolean | true | Show the navigation panel |
itemsOrder.bySortOrder | boolean | true | Sort chapters by the cue point sortOrder field |
plugins: {
navigation: {
position: 'right',
expandOnFirstPlay: true
}
}
Transcript (transcript)
Searchable transcript overlay synced to playback, using caption assets on the entry.
| Parameter | Type | Default | Description |
|---|---|---|---|
position | string | "right" | Panel position: "right", "left", "top", "bottom" |
expandOnFirstPlay | boolean | true | Auto-expand the transcript panel on first play |
visible | boolean | true | Show the transcript panel |
showTime | boolean | true | Display timestamps next to each line |
scrollOffset | number | 0 | Pixels to offset auto-scroll from the top |
searchDebounceTimeout | number | 250 | Milliseconds to debounce search input |
searchNextPrevVisible | boolean | true | Show next/previous navigation in search results |
downloadDisabled | boolean | false | Hide the transcript download button |
plugins: {
transcript: {
position: 'right',
expandOnFirstPlay: true,
showTime: true,
downloadDisabled: false
}
}
Q&A (qna)
Live Q&A panel for virtual events, enabling audience questions and moderator responses.
| Parameter | Type | Default | Description |
|---|---|---|---|
position | string | "right" | Panel position: "right", "left" |
expandOnFirstPlay | boolean | false | Auto-expand the Q&A panel on first play |
visible | boolean | true | Show the Q&A panel |
dateFormat | string | "mmmm do, yyyy" | Date display format for Q&A entries |
bannerDuration | number | 5000 | Banner notification duration in milliseconds |
plugins: {
qna: {
position: 'right',
expandOnFirstPlay: false
}
}
Hotspots (hotspots)
Clickable overlay hotspots on video, defined via cue points with custom data.
| Parameter | Type | Default | Description |
|---|---|---|---|
visible | boolean | true | Show hotspot overlays |
plugins: {
hotspots: {}
}
Hotspot content, position, and timing are defined by cue points on the entry (via the cuePoint API service), not by plugin config. The plugin reads these cue points and renders them at the specified times.
In-Video Quiz (IVQ) (ivq)
Interactive quizzes during playback, pausing the video to present questions at configured cue points.
| Parameter | Type | Default | Description |
|---|---|---|---|
visible | boolean | true | Show quiz overlays |
plugins: {
ivq: {}
}
Quiz questions, answers, and timing are defined by cue points on the entry (created via the quiz plugin in KMC or through the API). The IVQ plugin renders them during playback.
SEO (seo)
Auto-generates JSON-LD structured data (VideoObject schema) for video entries to improve search engine discoverability.
| Parameter | Type | Default | Description |
|---|---|---|---|
includeDescription | boolean | true | Include the entry description in the JSON-LD output |
includeThumbnail | boolean | true | Include the thumbnail URL in the JSON-LD output |
includeUploadDate | boolean | true | Include the upload date in the JSON-LD output |
plugins: {
seo: {}
}
Downloads (downloads)
Adds a download button to the player UI that lists available flavor assets (transcoded versions) for download.
| Parameter | Type | Default | Description |
|---|---|---|---|
flavorParamIds | string | "" | Comma-separated flavor param IDs to offer for download. Empty string means all available flavors. |
presetName | string | "" | Name for the download preset group |
displayFlavors | boolean | true | Show individual flavor selection (resolution/bitrate) in the download menu |
displayCaptions | boolean | true | Show caption download options in the download menu |
displayAttachments | boolean | true | Show attachment download options in the download menu |
plugins: {
downloads: {
flavorParamIds: '',
displayFlavors: true,
displayCaptions: true
}
}
KAVA (kava)
Built-in analytics event reporting that sends playback metrics to the Kaltura Analytics system.
| Parameter | Type | Default | Description |
|---|---|---|---|
partnerId | number | (from provider) | Override the partner ID for analytics reporting |
entryId | string | (from media) | Override the entry ID for analytics reporting |
ks | string | (from provider) | Override the KS for analytics reporting |
tamperAnalyticsHandler | function | null | Callback to modify analytics events before sending. Receives the event object and returns modified event or false to cancel. |
customVar1 | string | "" | Custom variable 1 (passed to analytics backend) |
customVar2 | string | "" | Custom variable 2 |
customVar3 | string | "" | Custom variable 3 |
plugins: {
kava: {
customVar1: 'department-engineering',
customVar2: 'campaign-q4'
}
}
Three shared infrastructure packages power the interactive plugins: kaltura-cuepoints (temporal markers), ui-managers (shared UI components), and timeline (timeline visualization). These are bundled automatically when the plugin is enabled.
Plugin availability depends on your player configuration (
uiConfId). Configure plugins in the KMC under Studio > TV Platform (select a player, then edit its plugins) or via thepluginsconfig block inKalturaPlayer.setup().
Player Runtime API
After the player is created with KalturaPlayer.setup(), you can control plugins and player behavior at runtime using the service and plugin APIs.
player.getService(name)
Retrieve a plugin service by name. Returns undefined if the plugin is not loaded for the current player configuration.
var svc = player.getService('dualScreen');
if (svc) {
svc.ready.then(function() {
console.log('Dual Screen service is ready');
});
} else {
console.log('Dual Screen plugin not available in this player config');
}
| Method | Returns | Description |
|---|---|---|
player.getService(name) | service object or undefined | Get a plugin's service interface. The name is the service registration name (e.g., 'dualScreen', 'sidePanels'). |
service.ready | Promise | Resolves when the service has finished initializing (e.g., secondary media is loaded for dual screen). |
player.plugins.*
Access plugin instances directly to call runtime methods. Each plugin is accessible by its config key:
// Access the Dual Screen plugin instance
var ds = player.plugins.dualscreen;
// Switch layouts at runtime (after service is ready)
var svc = player.getService('dualScreen');
svc.ready.then(function() {
ds._switchToPIP({ force: true }, true); // Switch to PiP layout
ds._switchToSideBySide({ force: true }, true); // Switch to side-by-side
ds._switchToSingleMedia({ force: true }, true); // Switch to single view
ds._switchToInversePIP({ force: true }, true); // Switch to inverse PiP
});
player.configure()only sets the initial config. It does not trigger runtime changes for plugins like Dual Screen. To control plugins at runtime, use the plugin instance methods (e.g.,player.plugins.dualscreen._switchTo*()) after the servicereadypromise resolves.
player.configure(config)
Updates player configuration at runtime. Effective for playback and ui settings, but not for plugin runtime state changes (plugins read config only at setup time):
// These work at runtime:
player.configure({ playback: { volume: 0.5 } });
player.configure({ ui: { css: '.custom { color: red; }' } });
// This does NOT trigger a plugin layout change at runtime:
player.configure({ plugins: { dualscreen: { layout: 'sbs' } } });
// Instead, use: player.plugins.dualscreen._switchToSideBySide({ force: true }, true);
player.destroy()
Destroys the player instance, removing all event listeners, stopping playback, and cleaning up the DOM. Call this when removing the player from the page:
player.destroy();