Skip to content

Metrics

The player automatically tracks a set of playback metrics. Access them via player.metrics() or receive periodic updates via the playback:metrics event.

Accessing metrics

TypeScript
const metrics = player.metrics();
console.log(metrics.sessionDurationMs);
console.log(metrics.rebufferRatio);

if (metrics.droppedFrames !== null) {
console.log(`Dropped frames: ${metrics.droppedFrames}`);
}

PlaybackMetrics reference

metrics() always returns a PlaybackMetrics object. It never returns null. Individual counters that cannot be measured by the current backend return null for that field.

CounterTypeDescription
ttfbnumber | nullTime-to-first-byte in ms from load() to first network response byte
ttffnumberTime-to-first-frame in ms from play() to the firstFrame event
rebufferRationumberRatio of stalled time to total playback time (0–1)
avgBitratenumber | nullAverage received bitrate over the session in bits/sec
droppedFramesnumber | nullCumulative dropped video frames
decoderStallsnumber | nullNumber of times the decoder stalled waiting for data
joinTimenumberms from setup() to the first rendered frame (session join latency)
sessionDurationMsnumberTotal active playback time in this session in ms
[customMetric: string]number | nullExtension slot, plugins publish namespaced counters here

Backend availability matrix

Counterhtml5VideoBackendhtml5AudioBackend (music)
ttfbnull, not available from html5 backendnull
ttffnumber (from firstFrame)number (from firstFrame)
rebufferRationumber (from backend:waiting)number
avgBitratenull, not available from html5 backendnull
droppedFramesnumber (from getVideoPlaybackQuality())null, no video element
decoderStallsnull, not available from html5 backendnull
joinTimenumbernumber
sessionDurationMsnumbernumber

null means the counter is structurally unavailable from that backend, it is not a temporary condition.

Periodic metrics events

The player emits playback:metrics on a configurable interval. Use this for server-side analytics ingestion:

TypeScript
player.on('playback:metrics', (metrics) => {
analytics.record({
sessionId: mySession.id,
ttff: metrics.ttff,
rebufferRatio: metrics.rebufferRatio,
sessionDurationMs: metrics.sessionDurationMs,
});
});

Configure the interval via setup({ metricsIntervalMs }). Default is 10000 ms (10 seconds). Set to 0 to disable the periodic event.

Custom metrics

Plugins can write namespaced numeric counters into the metrics store:

TypeScript
class ScrobblePlugin extends Plugin {
private scrobbleCount = 0;

use(): void {
this.on('ended', () => {
this.scrobbleCount++;
this.player.recordMetric('nomercy:scrobble/count', this.scrobbleCount);
});
}
}

Custom counters appear in player.metrics() and in the playback:metrics event payload under their key.

progress vs playback:metrics

Two separate throttled events serve different purposes:

EventConfig keyDefaultUse for
progressprogressIntervalMs5000Server watch-position saves, payload { time, duration, percentage }
playback:metricsmetricsIntervalMs10000Analytics ingestion, payload is the full PlaybackMetrics snapshot

These are separate timers with separate config keys and different defaults. progress is the lightweight event for position reporting. playback:metrics carries the full metrics object.