Docs

Events and metrics

Playback event payloads and measurements.

The playback tracker records each attempt to watch a video as a view. Each view has a view_id, and its events have their own event_id and sequence number within that view.

In each payload, event_name includes the chunkify.video. prefix.

Event When it is sent
view_started A playback attempt starts.
view_snapshot A cumulative update during playback.
playback_state_changed Playback enters a different state.
rendition_changed The first known rendition is selected, or playback changes rendition.
seek_completed A grouped seek interaction settles or is interrupted.
subtitle_changed The showing subtitle or caption language changes during a view.
playback_rate_changed The playback speed changes during a view.
playback_error The first reported playback error in the view.
view_ended The viewing attempt ends.

Choose events

Use includeEvents to choose which event types reach your destinations. With Chunkify Player already on the page, this example sends only the start and final records for each view:

import '@chunkify/player';
import { monitor } from '@chunkify/player-analytics';

await customElements.whenDefined('chunkify-player');
const player = document.querySelector('chunkify-player');
if (!player) throw new Error('Missing chunkify-player element');

const session = monitor(player, {
    videoId: 'ast_3Ljtoej7c3Y1plabZoElbQwdwLh',
    destinations: [{ send: (event) => console.log(event) }],
    includeEvents: ['view_started', 'view_ended'],
});

Use short names such as view_ended, without the chunkify.video. prefix. Omit includeEvents to send all nine types. An empty array sends nothing.

The selection applies to every destination. The tracker still measures playback when intermediate events are excluded, so view_ended retains its view metrics. Call session.destroy() when monitoring stops.

Shared fields

The payloads below show complete, illustrative tracker events before destination mapping. Measurements are null when unavailable; zero means a measured zero.

Every event contains these fields:

Fields Meaning
schema_version Event schema version. Currently 1.
event_name Full event name, such as chunkify.video.view_started.
event_id Unique record ID. Use it to deduplicate deliveries.
sequence Increasing sequence number within the view.
occurred_at UTC timestamp when the tracker emits the record.
view_id ID for this playback attempt.
video_id The videoId supplied by your application.
sdk_name, sdk_version Playback package name and version.
connector_name, connector_version Media or engine connector that produced the event.
player_name, player_version Player reported by the connector, or null. This can identify the underlying engine, such as hls.js, when using Chunkify Player.
visibility_state visible, hidden, or null when tab visibility is unavailable.
delivery_hostname Media hostname when available. The complete playback URL is not included.
environment Your optional environment label, or null.
viewer_id Anonymous ID the tracker generates for the browser. It is reused across page loads unless persistViewerId is false.
user_id Your optional userId, or null.
video_title Your optional videoTitle, or null.
reason, startup_outcome End reason and startup result on view_ended. Otherwise null.
error_category, error_code, error_fatal, error_playhead_seconds Error details on playback_error. Otherwise null.

Events

View started

view_started opens a viewing attempt. It normally follows the media element's play event. The Shaka connector starts the attempt when Shaka loads a source.

It is the only event that carries your custom dimensions, as a custom object with the keys and values you set. The field is omitted when you set none.

A start does not guarantee that any video played. If your code calls play(), call session.startAttempt() immediately beforehand to include attempts rejected before a play event.

The payload includes all view metrics, with initial counters and measurements available at that time.

View snapshot

view_snapshot reports cumulative view metrics. By default, the tracker sends a snapshot after each 30 seconds of active playing time. Pauses, buffering, and seeking do not advance that interval.

A tab visibility change also emits a snapshot during an attempt. A hidden tab can keep accumulating playing time; visibility does not determine whether playback is paused.

Set snapshotIntervalMs in your collection options to change the interval. Use the latest totals or differences between snapshots when calculating usage.

Playback state changed

playback_state_changed reports a transition between playback states. Its payload adds these fields to the shared fields:

Field Meaning
from_state State the view left.
to_state State the view entered.
previous_state_duration_ms Wall-clock milliseconds spent in from_state.
playhead_seconds Media position when the transition is recorded, or null.

Possible states are startup, resuming, playing, paused, buffering, seeking, error, ended, and stopped.

When seek_completed is enabled, it replaces intermediate state-change records during a seek interaction. A final transition to ended or stopped normally precedes view_ended.

Rendition changed

rendition_changed reports the initial known rendition and later changes. The initial selection has null previous-rendition fields. Repeated reports of the same rendition do not emit another record.

The connector must expose rendition information. Initial selection is not counted as a rendition switch.

Fields Meaning
playhead_seconds Media position at the change, or null.
player_width_px, player_height_px Displayed media size in CSS pixels.
previous_rendition_* Previous rendition's width, height, codec, bitrate_bps, and frame_rate.
selected_rendition_* Selected rendition's width, height, codec, bitrate_bps, and frame_rate.

Rendition dimensions are pixels, bitrate is bits per second, and frame rate is frames per second. Individual properties can be null.

Seek completed

seek_completed summarizes a logical seek interaction. Rapid seeks are grouped until 400 ms have passed since the last seeked. If playback was running, the tracker also waits for it to resume.

Fields Meaning
seek_started_at UTC timestamp of the first seek.
last_seeked_at UTC timestamp of the final seeked, or null.
playback_resumed_at UTC timestamp when playback resumes, or null.
state_before_seek, state_after_seek Playback states surrounding the interaction.
from_playhead_seconds, to_playhead_seconds Starting and final media positions, or null when unavailable.
seek_interaction_duration_ms Total time spent seeking during this interaction.
seek_resume_wait_ms Time from the final seeked to resumed playback, or null.
seek_outcome resumed, paused, or interrupted.

A view ending, a source change, or a fatal error can flush a pending seek as interrupted. Use the seek timestamps to locate the interaction; occurred_at is when its summary is emitted.

Subtitle changed

subtitle_changed reports a change of the showing subtitle or caption track during a view. The tracker reads the media element's text tracks, so it detects the language choices made in Chunkify Player's menus as well as tracks your code turns on or off.

Field Meaning
previous_subtitle_language Language before the change, or null when no subtitles were detected.
subtitle_language Language after the change, or null. See Subtitles and playback speed.
playhead_seconds Media position when the change was recorded, or null.

The record is sent only when the language changes. The language when a view starts is in view_started.

Playback rate changed

playback_rate_changed reports a change of playback speed during a view, such as a choice in Chunkify Player's speed menu.

Field Meaning
previous_playback_rate Speed before the change, or null.
playback_rate Speed after the change, or null. See Subtitles and playback speed.
playhead_seconds Media position when the change was recorded, or null.

The record is sent only when the speed changes after rounding. With Shaka Player, the tracker reports Shaka's playback rate, so buffering is not recorded as a speed change. The speed when a view starts is in view_started.

Playback error

playback_error includes cumulative view metrics and the first reported error in that view. Later error reports in the same view do not produce additional error records.

Field Meaning
error_category aborted, network, decode, unsupported, or unknown.
error_code Browser or engine code, as a string or number, or null.
error_fatal Whether the reported error is fatal.
error_playhead_seconds Media position when the error was recorded, or null.

Raw error messages and URLs are omitted. A fatal error moves the view into the error state; view_ended still reports how the attempt later closes.

View ended

view_ended closes an attempt and includes its final cumulative metrics. It can be sent when playback finishes, monitoring stops, the source changes, or the page exits.

Field Values
reason ended, destroyed, source_changed, or page_exit.
startup_outcome started, failed_before_start, or ended_before_start.

Only reason: "ended" means playback reached the media end. startup_outcome: "started" means the tracker observed playback begin. An attempt can end before playback starts without a reported failure.

View metrics

view_started, view_snapshot, playback_error, and view_ended include the metrics below. Time counters accumulate within a view; dimensions and rendition fields describe the current playback state.

State, rendition, seek, subtitle, and playback-rate records contain their event-specific fields instead.

Time and progress

Field Meaning
playhead_seconds Current media position, or null.
played_ranges Merged media sections played by this attempt, or null when unavailable.
media_duration_seconds Media duration, or null when unknown.
startup_time_ms Time from the attempt starting to the first playing event.
first_video_frame_time_ms Time to the first video frame callback when the browser exposes it. It can differ from startup time.
playing_time_ms Wall-clock time spent playing, excluding pauses, buffering, and seeking.
rebuffer_count Buffering interruptions after startup, excluding seeks.
rebuffer_duration_ms Cumulative time spent buffering after startup.
rebuffer_ratio Buffering time divided by playing plus buffering time. null until that total is positive.
seek_count Number of grouped seek interactions.
seek_duration_ms Cumulative time spent seeking.
maximum_playhead_seconds Furthest media position reached.
furthest_progress_ratio Furthest position divided by media duration, capped at 1. Seeking forward increases it without watching the intervening video.

Video and player

Fields Meaning
media_width_px, media_height_px The media element's intrinsic video dimensions. They can differ from encoded rendition dimensions.
player_width_px, player_height_px Displayed media box in CSS pixels. For Chunkify Player, this is the inner media element.
dropped_video_frames, total_video_frames Per-view browser frame counters, when available.

Player dimensions are sampled when records are emitted. The final event retains the last measurable size if the element has already been removed.

Renditions and delivery

Fields Meaning
selected_rendition_width, selected_rendition_height Current rendition dimensions in pixels.
selected_rendition_codec Current video codec string.
selected_rendition_bitrate_bps Current rendition bitrate in bits per second.
rendition_switch_count Changes between known renditions during the view.
rendition_playing_time Cumulative playing time per known rendition. Each entry contains width, height, codec, bitrate_bps, frame_rate, and playing_time_ms.
delivery_request_count Completed media requests observed by the connector.
delivery_transferred_bytes Response bytes observed by the connector.
delivery_throughput_bps Aggregate transfer throughput in bits per second.

rendition_playing_time is null without a rendition-aware connector and [] before one identifies a rendition. It excludes playing time before the rendition is known, so its total can be lower than playing_time_ms.

Engine metrics depend on the active connector. hls.js, Shaka, and Video.js 10 with its hls.js engine expose rendition and request data when available.

Native <video> and Chunkify Player's native HLS or MP4 playback leave engine metrics null.

Subtitles and playback speed

Fields Meaning
subtitle_language Language of the showing subtitle or caption track, such as fr or en-US. und means a track without a declared language. null means no subtitles were detected.
playback_rate Current playback speed, rounded to two decimals, such as 1 or 1.5. null for a speed outside the reported range, such as 0.
subtitle_playing_time Cumulative playing time per subtitle language, including null for time without subtitles. Each entry contains language and playing_time_ms. Only on view_snapshot and view_ended.
playback_rate_playing_time Cumulative playing time per speed. Each entry contains rate and playing_time_ms. Only on view_snapshot and view_ended.

null subtitles means either subtitles are off or they cannot be detected. The tracker reads the media element's showing subtitles or captions track, so subtitles that a player draws without a showing text track, such as Shaka's built-in subtitle display, are reported as null. When several tracks show at once, the first one is reported.

The playing-time lists count only time spent playing, like rendition_playing_time. Each list keeps at most 32 distinct values; playing time in further values is not added, so a list's total can be lower than playing_time_ms. Playing time at a null speed is not attributed to a speed.

Watched sections and background playback

played_ranges records the sections actually played as cumulative start_seconds and end_seconds pairs. Overlaps and replays merge within an attempt; seeking over a section does not mark it watched.

An empty array means no measured section. null means coverage is unavailable, including after the tracker exceeds 128 disjoint ranges. Use the final record, or the latest snapshot, for watched-section reports.

visibility_state records the document visibility at event time. A pause recorded while hidden can be shown as "Paused in background", but it does not establish whether the browser, application, or viewer caused it.

Use events in reports

Count distinct view_id values from view_started to count attempts. To count confirmed playback starts, use the first transition to playing, or final records with startup_outcome: "started".

Do not add cumulative snapshots together. Use each view's final totals, or differences between successive snapshots. A final record can be lost when the page closes, so snapshots can provide an earlier result.

Deduplicate by event_id and order a view's records by sequence. Distinct viewer_id values approximate unique viewers per browser; each view_id identifies an attempt.

See Send events to choose destinations and transform the payload they receive.