Cue Points
Overview
Cue points are timestamped markers that you can display on the Fastevo MP2 Player's seek bar. When playback reaches a cue point, the player emits an event so your page can react — display a note, update surrounding UI, log progress, show related material, and so on. Viewers can also click (or tap) a cue point on the seek bar to seek directly to that moment.
Cue points are injected at runtime from your page: you supply the list and the player paints the ticks and handles all the interaction.
Typical use cases:
- Chapter-style navigation on long content.
- Highlighting notable moments (goals, key scenes, quiz boundaries).
- Triggering UI changes, overlays, or call-to-actions at specific times.
- User-driven bookmarking or tagging.
Compatibility
- VOD only. Cue points are disabled for live streams. Since seekable ranges shift over time on live content, cue point positions become ambiguous.
- Video content only. Cue points do not apply to audio or image content types.
Cue Point Object Shape
Each cue point is a plain object with two required fields:
| Field | Type | Description |
|---|---|---|
time | number | Timestamp in milliseconds from the start of the video. |
text | string | Label shown in the tooltip when the tick is hovered. Kept short is best (single line). |
Example list:
var cuePointsList = [
{ time: 5000, text: "Introduction" },
{ time: 15000, text: "Chapter 1" },
{ time: 30000, text: "Key takeaway" },
{ time: 45000, text: "Chapter 2" },
{ time: 60000, text: "Conclusion" }
];Cue points whose time falls beyond the video's duration are silently ignored — they are not painted and they do not fire events.
Injecting Cue Points
You inject the list by sending a setCuePoints command to the player, with the cue points array under data.cuePoints.
As with every other player command, you have two equivalent ways to send it:
Method 1 — player.sendCommand
var container = document.getElementById("my-video-container");
container.addEventListener("playerInitialized", function (e) {
var player = window.players[e.detail.playerId];
player.sendCommand("setCuePoints", {
cuePoints: [
{ time: 5000, text: "Introduction" },
{ time: 15000, text: "Chapter 1" },
{ time: 30000, text: "Key takeaway" }
]
});
});Method 2 — Dispatching a playerCommand event
var container = document.getElementById("my-video-container");
container.addEventListener("playerInitialized", function () {
var setCuePointsEvent = new CustomEvent("playerCommand", {
detail: {
eventName: "setCuePoints",
data: {
cuePoints: [
{ time: 5000, text: "Introduction" },
{ time: 15000, text: "Chapter 1" },
{ time: 30000, text: "Key takeaway" }
]
}
}
});
container.dispatchEvent(setCuePointsEvent);
});Both approaches produce the same result. Use whichever matches your project's style.
When Can I Inject?
Any time after the player is ready. The safe signals are:
playerInitializedon the container — fires once the player instance has been created and registered atwindow.players[containerId]. This is the earliest reliable point.loadedMetadata— fires slightly later, once the media metadata (duration, dimensions) has loaded. Useful if you want to compute cue point times based on the video's duration.
You can inject before or after playback starts, multiple times, at any moment during the session.
Replacing Cue Points
Every call to setCuePoints replaces the entire list. The player does not merge or append — it normalizes the new list, wipes the old ticks, and repaints.
// Set an initial list.
player.sendCommand("setCuePoints", {
cuePoints: [
{ time: 5000, text: "Intro" }
]
});
// Later, replace it entirely with a different set.
player.sendCommand("setCuePoints", {
cuePoints: [
{ time: 10000, text: "Act 1" },
{ time: 60000, text: "Act 2" }
]
});
// To clear all cue points, send an empty list.
player.sendCommand("setCuePoints", { cuePoints: [] });When you replace the list mid-playback, cue points whose time is already behind the current playhead do not fire retroactively. Only cue points that the playhead crosses going forward will emit cuePointReached.
Listening to Cue Point Events
Two events are emitted by the player. You can listen to them with either player.on(eventName, handler) or a DOM listener on the container.
cuePointReached
Description: Fired when the playhead crosses a cue point's timestamp during playback.
Event Data:
time(number) — The cue point time in milliseconds (matches the original injected value).text(string) — The cue point label.index(number) — The index of the cue point in the list that was most recently passed tosetCuePoints.
Applicable to: Video
Example:
player.on("cuePointReached", function (data) {
console.log("Reached cue point:", data.text, "at", data.time, "ms");
});
// or via DOM event:
container.addEventListener("cuePointReached", function (e) {
console.log("Reached cue point:", e.detail.text, "at", e.detail.time, "ms");
});cuePointClicked
Description: Fired when the viewer clicks or taps a cue point tick on the seek bar. The player automatically seeks to the cue point's time when this happens.
Event Data:
time(number) — The cue point time in milliseconds.text(string) — The cue point label.index(number) — The index of the cue point in the current list.currentTimeAtClickInSeconds(number) — Where the playhead was (in seconds) before the click triggered the seek.
Applicable to: Video
Example:
player.on("cuePointClicked", function (data) {
console.log(
"User jumped from", data.currentTimeAtClickInSeconds, "s",
"to cue point:", data.text
);
});
// or via DOM event:
container.addEventListener("cuePointClicked", function (e) {
console.log("Cue point clicked:", e.detail);
});Firing Behavior In Detail
The rules for when cuePointReached fires are designed to feel predictable and avoid floods:
- Forward playback: as the playhead crosses a cue point, the event fires once for that cue point.
- Forward seek that crosses several cue points at once (e.g. the viewer drags the scrubber past three markers): only the last cue point in the jumped range fires. This prevents burst-firing.
- Backward seek: no cue points refire when moving backward. If the viewer later plays forward and crosses the same cue point again, it will fire then.
- Looping: when the video loops back to the start, subsequent forward crossings fire cue points again as expected.
- Exact-time matching: the player compares against a half-open range, so brief skips in the native
timeupdatecadence never miss a cue point.
Customizing the Look
Color
Cue points are rendered as small circular markers on the seek bar. The fill color is configurable through your player configuration's playerColorsConfiguration object, via the cuePointColor field. If you do not specify one, the player uses white, which contrasts well against the default seek bar.
See Player Configurations for how to create/update a player configuration.
{
"playerColorsConfiguration": {
"base": "#1F1F1F",
"buffered": "#323232",
"played": "#0078D7",
"cuePointColor": "#FF3366"
}
}On hover, ticks brighten automatically via a CSS filter — regardless of the color you pick.
Hiding the Markers While Keeping the Events
If you want the events (cuePointReached, cuePointClicked) without drawing anything on the seek bar, set cuePointsVisibleOnTimeline to false in your player configuration:
{
"cuePointsVisibleOnTimeline": false
}If the player is configured with displayControls: false, the seek bar is not rendered and the cue point feature is inactive (no ticks, no events). Cue points require the standard UI.
Complete Example
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Cue Points Example</title>
</head>
<body>
<!-- Player container -->
<div
id="my-video-container"
data-token="YOUR_PLAYBACK_TOKEN"
data-config='{"autoPlay":"false"}'
></div>
<!-- Fastevo MP2 Player embedder -->
<script src="https://player.fastevo.net/release/index.js"></script>
<script>
var container = document.getElementById("my-video-container");
// Wait for the player to be ready, then inject cue points.
container.addEventListener("playerInitialized", function (e) {
var player = window.players[e.detail.playerId];
player.sendCommand("setCuePoints", {
cuePoints: [
{ time: 5000, text: "Introduction" },
{ time: 15000, text: "Chapter 1" },
{ time: 30000, text: "Key takeaway" },
{ time: 45000, text: "Chapter 2" },
{ time: 60000, text: "Conclusion" }
]
});
});
// React when the playhead crosses a cue point.
container.addEventListener("cuePointReached", function (e) {
var sidebar = document.getElementById("current-note");
sidebar.textContent = e.detail.text;
});
// React when the viewer clicks a cue point tick.
container.addEventListener("cuePointClicked", function (e) {
console.log(
"Viewer jumped to",
e.detail.text,
"(was at",
e.detail.currentTimeAtClickInSeconds,
"s)"
);
});
</script>
<aside>
<h3>Current section</h3>
<p id="current-note">Waiting…</p>
</aside>
</body>
</html>Migrating from Radiant Media Player (RMP)
The injection shape ({ time, text }) and the cuePointsVisibleOnTimeline flag are intentionally compatible with RMP's cue-points API, so migration is mostly a rename:
| RMP | Fastevo MP2 Player |
|---|---|
cuePoints: [{ time, text }, …] setting | sendCommand("setCuePoints", { cuePoints: [...] }) |
cuePointsCallback function | cuePointReached event |
rmp.cuePointData getter | data payload on cuePointReached |
cuePointsVisibleOnTimeline setting | cuePointsVisibleOnTimeline player configuration field |
RMP does not define a click behavior on ticks; the Fastevo MP2 Player adds it as cuePointClicked.
Additional Resources
- Advanced Interactions with Fastevo MP2 Player — full list of commands you can send to the player.
- Understanding Media Player Events — full list of events you can listen to.
- Player Configurations — how to manage the color and visibility settings for cue points.