> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/BintzGavin/helios/llms.txt
> Use this file to discover all available pages before exploring further.

# Markers API

> Timeline markers for navigation and annotations

Markers allow you to add named points on the timeline for navigation and organization.

## Marker

Interface representing a timeline marker.

```typescript theme={null}
interface Marker {
  id: string;
  time: number;              // seconds
  label?: string;
  color?: string;            // hex code
  metadata?: Record<string, any>;
}
```

## validateMarker()

Validates a single marker.

```typescript theme={null}
const validated = validateMarker(marker);
```

<ParamField path="marker" type="Marker" required>
  Marker object to validate
</ParamField>

<ResponseField name="validated" type="Marker">
  Validated marker (throws error if invalid)
</ResponseField>

### Example

```typescript theme={null}
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.

```typescript theme={null}
const validated = validateMarkers(markers);
```

<ParamField path="markers" type="Marker[]" required>
  Array of markers to validate
</ParamField>

<ResponseField name="validated" type="Marker[]">
  Validated and sorted markers (throws error if invalid or duplicate IDs)
</ResponseField>

### Example

```typescript theme={null}
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

```typescript theme={null}
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

```typescript theme={null}
helios.addMarker({
  id: 'highlight',
  time: 15.5,
  label: 'Important moment',
  color: '#ef4444',
  metadata: {
    importance: 'high',
    notes: 'Key talking point',
  },
});
```

### Removing markers

```typescript theme={null}
helios.removeMarker('highlight');
```

### Seeking to markers

```typescript theme={null}
helios.seekToMarker('intro');
helios.seekToMarker('outro');
```

### Accessing markers

```typescript theme={null}
// 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

```typescript theme={null}
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);
  }
}
```

## Marker metadata

The `metadata` field can store arbitrary data:

```typescript theme={null}
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;
```
