Kaltura Player Plugin

playkit-js-aws-analytics

Drop-in Kaltura Player plugin that replicates all 12 AWS TV analytics events, auto-detected from native player events and bridged to AWS's Libra/Experience Builder framework via CustomEvent dispatch, which relays to Adobe Analytics.

Further reading: Kaltura Player Embed Guide · playkit-js-plugin-example — reference implementation for custom player plugins

Live Demo
The player below runs the real plugin. Play the video, seek, pause, change volume, go fullscreen — every action is captured in the event log below.
Event Log 0 events
Analytics State Logger
Play the video to see events appear here in real time.
How It Works
The plugin sits between the Kaltura Player and AWS's Libra/Experience Builder framework, translating native player events into the exact CustomEvent format Libra expects. From there, AWS's internal AWSMA layer relays the events to Adobe Analytics.

Viewer

Clicks play, pauses, seeks, changes volume…

→

Kaltura Player

Fires native events: PLAYING, PAUSE, TIME_UPDATE…

→

AWS Analytics Plugin

Dedup, thresholds, seek filtering, payload formatting

→

Libra Framework

Listens for CustomEvents, relays via AWSMA to Adobe Analytics

"Libra" is part of AWS's internal Experience Builder platform. It has no network code of its own here — it forwards events through AWS's internal AWSMA wrapper, which sends them to Adobe Analytics (Omniture/SiteCatalyst) as the actual backend.

3 CustomEvent Channels

Analytics

custom_aws_eb-analytics_notify-listener
Target: document
All 12 analytics events (Play, Pause, Watch, Complete, etc.) with video metadata.

State

custom_awstv_video-player-state
Target: document.body
Player state broadcasts: play, pause, ended. Fires every time (not deduped).

Logger

custom_aws_eb-logger_notify-listener
Target: document
Buffer duration metrics. Fires each time the player exits a buffering state.
12 Analytics Events
Matches the real AWS TV player exactly. All events are auto-detected from native player events — no manual API calls needed. Fire-once events reset on loadMedia().

Play

First playback starts (FIRST_PLAYING)

fire-once

Pause

User pauses (deferred, filtered during seek/ended)

fire-once

Replay

Playback resumes after ended state

fire-once

Watch

Accumulated watch time exceeds threshold (default 30s)

fire-once

Complete

Watch ratio exceeds threshold (default 95%)

fire-once

WatchTime

Page hidden or unloaded — sends accumulated watch time

repeatable

VolumeChange

Volume level changed (VOLUME_CHANGE)

fire-once

FullScreenChange

Enter or exit fullscreen (ENTER/EXIT_FULLSCREEN)

fire-once

SeekForward

Auto-detected: seek delta > 1s forward (SEEKED)

fire-once

SeekBackward

Auto-detected: seek delta > 1s backward (SEEKED)

fire-once

QualityChange

Auto-detected: video track switch (VIDEO_TRACK_CHANGED)

fire-once

TranscriptToggle

Auto-detected: caption/subtitle change (TEXT_TRACK_CHANGED)

fire-once

3 Logger Metrics

Operational metrics dispatched on the custom_aws_eb-logger_notify-listener channel.

VideoBufferTime

Duration spent buffering, fires each time player exits buffering state

VideoPlayerReady

Time from plugin init to CAN_PLAY (milliseconds), fires once

VideoError

Player errors with code, message, videoId, and videoTitle

Setup
Load the plugin after the Kaltura Player script. An empty config object is all you need.
Zero Config
Custom Config
UI Events API
HTML <!-- 1. Kaltura Player --> <script src="https://cdn.jsdelivr.net/npm/@playkit-js/kaltura-player-js@latest/dist/kaltura-ovp-player.js"></script> <!-- 2. Plugin (auto-registers as 'awsAnalytics') --> <script src="playkit-aws-analytics.js"></script> <script> const player = KalturaPlayer.setup({ targetId: 'player-container', provider: { partnerId: YOUR_PARTNER_ID }, plugins: { awsAnalytics: {} // That's it. videoId & videoTitle auto-resolve. } }); player.loadMedia({ entryId: 'YOUR_ENTRY_ID' }); </script>
JavaScript plugins: { awsAnalytics: { videoId: 'custom-id', // override auto-resolved entry ID videoTitle: 'Custom Title', // override auto-resolved entry name orgId: 'my_org', // default: 'awsm_tv' watchThresholdSeconds: 15, // default: 30 completeThresholdPercent: 0.90 // default: 0.95 } }
JavaScript // Get the plugin instance const plugin = player._pluginManager.get('awsAnalytics'); // Call from your custom UI controls plugin.sendUiEvent('SeekForward'); plugin.sendUiEvent('SeekBackward'); plugin.sendUiEvent('TranscriptToggle'); plugin.sendUiEvent('QualityChange');
Why no endpoint URLs or API keys?

This plugin is a CustomEvent bridge, not an HTTP transport. It dispatches browser events that AWS's Libra/Experience Builder framework (already on the page) listens for. That framework relays events through AWS's internal AWSMA layer to Adobe Analytics, which handles all network transport, authentication, batching, and retries. The plugin itself has zero network code.

Configuration
All options are optional. videoId and videoTitle auto-resolve from the Kaltura Player's media info.
Option Type Default Description
videoId string auto Auto-resolved from player.sources.id. Set to override.
videoTitle string auto Auto-resolved from player.sources.metadata.name. Set to override.
orgId string 'awsm_tv' Organization ID in buffer-time logger events.
watchThresholdSeconds number 30 Seconds of watch time before Watch fires.
completeThresholdPercent number 0.95 Fraction of duration before Complete fires.
Event Payloads
Every analytics event includes these base fields. Some events add extra fields.
Analytics
State
Logger
CustomEvent.detail { "type": "awsTvVideo", "name": "Play", // event name "videoId": "1_abc123", // auto-resolved or config "videoTitle": "My Video" // auto-resolved or config } // Complete adds: "duration": "120" // WatchTime adds: "timestamp", "watchTime", "duration"
CustomEvent.detail { "state": "play", // "play" | "pause" | "ended" "videoId": "1_abc123" }
CustomEvent.detail { "logLevel": "info", "namespace": "VideoPlayer", "orgId": "awsm_tv", "metricName": "VideoBufferTime", "payload": { "duration": 1.234, "unit": "Seconds" } }