Markers allow you to add named points on the timeline for navigation and organization.
Marker
Interface representing a timeline marker.
interface Marker {
id: string;
time: number; // seconds
label?: string;
color?: string; // hex code
metadata?: Record<string, any>;
}
validateMarker()
Validates a single marker.
const validated = validateMarker(marker);
Marker object to validate
Validated marker (throws error if invalid)
Example
import { validateMarker } from '@heliosvideo/core';
const marker = validateMarker({
id: 'intro-end',
time: 5.5,
label: 'End of intro',
color: '#3b82f6',
});
// Throws if invalid:
// - Missing or empty ID
// - Negative time
validateMarkers()
Validates an array of markers.
const validated = validateMarkers(markers);
Array of markers to validate
Validated and sorted markers (throws error if invalid or duplicate IDs)
Example
import { validateMarkers } from '@heliosvideo/core';
const markers = validateMarkers([
{ id: 'scene-2', time: 10, label: 'Scene 2' },
{ id: 'intro', time: 0, label: 'Intro' },
{ id: 'outro', time: 25, label: 'Outro' },
]);
// Returns sorted by time:
// [
// { id: 'intro', time: 0, label: 'Intro' },
// { id: 'scene-2', time: 10, label: 'Scene 2' },
// { id: 'outro', time: 25, label: 'Outro' },
// ]
Using markers with Helios
Setting markers
import { Helios } from '@heliosvideo/core';
const helios = new Helios({
duration: 30,
fps: 30,
markers: [
{ id: 'intro', time: 0, label: 'Intro', color: '#3b82f6' },
{ id: 'main', time: 5, label: 'Main Content', color: '#10b981' },
{ id: 'outro', time: 25, label: 'Outro', color: '#f59e0b' },
],
});
Adding markers dynamically
helios.addMarker({
id: 'highlight',
time: 15.5,
label: 'Important moment',
color: '#ef4444',
metadata: {
importance: 'high',
notes: 'Key talking point',
},
});
Removing markers
helios.removeMarker('highlight');
Seeking to markers
helios.seekToMarker('intro');
helios.seekToMarker('outro');
Accessing markers
// Get all markers
const allMarkers = helios.markers.value;
// Subscribe to marker changes
helios.markers.subscribe((markers) => {
console.log('Markers updated:', markers);
});
// Find marker by ID
const introMarker = allMarkers.find(m => m.id === 'intro');
Complete example
import { Helios } from '@heliosvideo/core';
const helios = new Helios({
duration: 60,
fps: 30,
markers: [
{
id: 'chapter-1',
time: 0,
label: 'Chapter 1: Introduction',
color: '#3b82f6',
metadata: { chapter: 1 },
},
{
id: 'chapter-2',
time: 20,
label: 'Chapter 2: Main Content',
color: '#10b981',
metadata: { chapter: 2 },
},
{
id: 'chapter-3',
time: 45,
label: 'Chapter 3: Conclusion',
color: '#f59e0b',
metadata: { chapter: 3 },
},
],
});
// Render timeline with markers
function renderTimeline() {
const markers = helios.markers.value;
const duration = helios.duration.value;
markers.forEach((marker) => {
const position = (marker.time / duration) * 100;
createMarkerElement({
position: `${position}%`,
color: marker.color,
label: marker.label,
onClick: () => helios.seekToMarker(marker.id),
});
});
}
// Navigate between chapters
function nextChapter() {
const markers = helios.markers.value;
const currentTime = helios.currentTime.value;
const nextMarker = markers.find(m => m.time > currentTime);
if (nextMarker) {
helios.seekToMarker(nextMarker.id);
}
}
function previousChapter() {
const markers = helios.markers.value;
const currentTime = helios.currentTime.value;
const previousMarker = markers
.reverse()
.find(m => m.time < currentTime);
if (previousMarker) {
helios.seekToMarker(previousMarker.id);
}
}
The metadata field can store arbitrary data:
helios.addMarker({
id: 'scene-change',
time: 12.5,
label: 'Scene Change',
metadata: {
sceneId: 'beach-scene',
camera: 'wide-shot',
notes: 'Transition to beach',
tags: ['outdoor', 'sunset'],
},
});
// Access metadata
const marker = helios.markers.value.find(m => m.id === 'scene-change');
const sceneId = marker?.metadata?.sceneId;