> ## 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.

# Helios Player

> Web component for previewing and exporting Helios compositions

The `<helios-player>` web component provides a drop-in UI for reviewing and exporting Helios compositions. It implements a subset of the HTMLMediaElement interface for familiar programmatic control.

## Installation

```bash theme={null}
npm install @helios-project/player
```

## Usage

### Basic setup

Import the player and use the custom element in your HTML:

```html theme={null}
<script type="module">
  import "@helios-project/player";
</script>

<helios-player
  src="path/to/composition.html"
  width="1920"
  height="1080"
  controls
  autoplay
></helios-player>
```

### Connecting the composition

For the player to control your composition, the composition page must connect to the parent window.

**Using `@helios-project/core`:**

```javascript theme={null}
import { Helios } from "@helios-project/core";
import { connectToParent } from "@helios-project/player/bridge";

const helios = new Helios({ /* config */ });

// Initialize the bridge
connectToParent(helios);
```

**Legacy mode (same-origin only):**

The player will automatically access `window.helios` on the iframe's content window if available. However, `connectToParent` is recommended for cross-origin support and sandboxing.

## Attributes

| Attribute                 | Description                                    | Default                           |
| ------------------------- | ---------------------------------------------- | --------------------------------- |
| `src`                     | URL of the composition page to load            | (Required)                        |
| `width`                   | Width for aspect ratio calculation             | -                                 |
| `height`                  | Height for aspect ratio calculation            | -                                 |
| `autoplay`                | Auto-start playback when connected             | `false`                           |
| `loop`                    | Loop playback at the end                       | `false`                           |
| `controls`                | Show UI controls overlay                       | `false`                           |
| `export-mode`             | Export strategy: `auto`, `canvas`, or `dom`    | `auto`                            |
| `canvas-selector`         | CSS selector for canvas element                | `canvas`                          |
| `export-format`           | Output format: `mp4`, `webm`, `png`, `jpeg`    | `mp4`                             |
| `poster`                  | Image URL to display before playback           | -                                 |
| `preload`                 | `auto` or `none` (defers iframe loading)       | `auto`                            |
| `input-props`             | JSON string of composition properties          | -                                 |
| `interactive`             | Enable direct composition interaction          | `false`                           |
| `controlslist`            | Disable features: `nodownload`, `nofullscreen` | -                                 |
| `sandbox`                 | Security flags for the iframe                  | `allow-scripts allow-same-origin` |
| `export-width`            | Target width for export                        | -                                 |
| `export-height`           | Target height for export                       | -                                 |
| `export-bitrate`          | Target bitrate for export (bps)                | -                                 |
| `export-filename`         | Filename for export (no extension)             | `video`                           |
| `export-caption-mode`     | Caption strategy: `burn-in` or `file`          | `burn-in`                         |
| `disablepictureinpicture` | Hide Picture-in-Picture button                 | `false`                           |
| `media-title`             | Title for OS Media Session                     | -                                 |
| `media-artist`            | Artist name for OS Media Session               | -                                 |
| `media-album`             | Album name for OS Media Session                | -                                 |
| `media-artwork`           | Artwork URL for OS Media Session               | -                                 |

## User interface

The player includes comprehensive controls:

* **Playback** - Play/Pause, scrubber, time display
* **Audio** - Volume, mute, and track menu for individual track control
* **Settings menu** (gear icon):
  * Speed adjustment (0.25x - 2x)
  * Loop toggle
  * Playback range (In/Out points)
  * Diagnostics (WebCodecs support)
  * Shortcuts reference
* **Tools** - Fullscreen, Picture-in-Picture, captions (CC), export

### Keyboard shortcuts

| Key                 | Action               |
| ------------------- | -------------------- |
| `Space` / `K`       | Play / Pause         |
| `F`                 | Toggle Fullscreen    |
| `M`                 | Mute / Unmute        |
| `C`                 | Toggle Captions      |
| `?`                 | Show Shortcuts Help  |
| `←` / `→`           | Seek 1 frame         |
| `Shift` + `←` / `→` | Seek 10 frames       |
| `Home`              | Go to Start          |
| `End`               | Go to End            |
| `I`                 | Set In Point         |
| `O`                 | Set Out Point        |
| `X`                 | Clear Playback Range |
| `Shift` + `D`       | Toggle Diagnostics   |
| `0-9`               | Seek to 0-90%        |

## API reference

The `<helios-player>` element implements a subset of the HTMLMediaElement interface.

### Methods

#### `play(): Promise<void>`

Starts playback.

```javascript theme={null}
const player = document.querySelector('helios-player');
await player.play();
```

#### `pause(): void`

Pauses playback.

#### `load(): void`

Reloads the iframe (useful if `src` changed or to retry connection).

#### `export(options?: HeliosExportOptions): Promise<void>`

Programmatically trigger client-side export.

```javascript theme={null}
await player.export({
  format: 'webm',
  filename: 'my-video',
  mode: 'dom',
  width: 1920,
  height: 1080
});
```

#### `diagnose(): Promise<DiagnosticReport>`

Runs environment diagnostics (WebCodecs, WebGL) and returns a report.

#### `requestPictureInPicture(): Promise<PictureInPictureWindow>`

Requests Picture-in-Picture mode for the player.

#### `addTextTrack(kind: string, label?: string, language?: string): TextTrack`

Adds a new text track to the media element.

#### `fastSeek(time: number): void`

Seeks to the specified time as fast as possible (currently equivalent to setting `currentTime`).

### Properties

| Property                  | Type                        | Description                          |
| ------------------------- | --------------------------- | ------------------------------------ |
| `currentTime`             | `number`                    | Current playback position (seconds)  |
| `duration`                | `number` (read-only)        | Total duration (seconds)             |
| `paused`                  | `boolean` (read-only)       | Whether playback is paused           |
| `ended`                   | `boolean` (read-only)       | Whether playback has ended           |
| `volume`                  | `number`                    | Audio volume (0.0 to 1.0)            |
| `muted`                   | `boolean`                   | Audio mute state                     |
| `playbackRate`            | `number`                    | Playback speed (default 1.0)         |
| `width`                   | `number`                    | Reflected width attribute            |
| `height`                  | `number`                    | Reflected height attribute           |
| `videoWidth`              | `number` (read-only)        | Intrinsic video width                |
| `videoHeight`             | `number` (read-only)        | Intrinsic video height               |
| `buffered`                | `TimeRanges` (read-only)    | Buffered content (always 0-duration) |
| `seekable`                | `TimeRanges` (read-only)    | Seekable content (always 0-duration) |
| `seeking`                 | `boolean` (read-only)       | Whether currently seeking/scrubbing  |
| `readyState`              | `number` (read-only)        | Readiness state (0-4)                |
| `networkState`            | `number` (read-only)        | Network state (0-3)                  |
| `fps`                     | `number` (read-only)        | Frames per second                    |
| `currentFrame`            | `number`                    | Current frame index                  |
| `inputProps`              | `object`                    | Composition input properties         |
| `playsInline`             | `boolean`                   | Reflected playsinline attribute      |
| `disablePictureInPicture` | `boolean`                   | Hide PiP button                      |
| `textTracks`              | `TextTrackList` (read-only) | Text tracks                          |

### Events

The element dispatches standard media events:

* `play` - Playback starts
* `pause` - Playback paused
* `ended` - Playback completed
* `timeupdate` - Current time/frame changed
* `volumechange` - Volume or mute state changed
* `ratechange` - Playback rate changed
* `durationchange` - Duration changed
* `loadstart` - Browser begins looking for media
* `loadedmetadata` - Duration and dimensions determined
* `loadeddata` - Data for current frame available
* `canplay` - Browser can resume playback
* `canplaythrough` - Browser can play through without buffering

## Controllers

The player uses two controller patterns for managing compositions:

### DirectController

For same-origin compositions with direct access to the `Helios` instance.

See `/home/daytona/workspace/source/packages/player/src/controllers.ts:38`

### BridgeController

For cross-origin or sandboxed compositions using `postMessage` communication.

See `/home/daytona/workspace/source/packages/player/src/controllers.ts:245`

## Client-side export

The player supports browser-based export to video (MP4/WebM) or image snapshots (PNG/JPEG) using WebCodecs.

### Export modes

* **`canvas`** - Captures frames from a `<canvas>` element. Fast and efficient.
* **`dom`** - Captures the entire DOM using `foreignObject` SVG serialization. For compositions using DOM elements.
* **`auto`** - Automatically detects the best strategy.

### Configuration example

```html theme={null}
<helios-player
  src="composition.html"
  export-mode="dom"
  export-format="webm"
  export-width="1920"
  export-height="1080"
></helios-player>
```

### Image snapshots

Set `export-format="png"` or `export-format="jpeg"` to capture a single frame instead of rendering video.

### Audio fades

Apply audio fades during export by adding `data-helios-fade-in` and `data-helios-fade-out` attributes to audio elements:

```html theme={null}
<audio src="music.mp3" data-helios-fade-in="2" data-helios-fade-out="3"></audio>
```

Values are in seconds.

## CSS variables

Customize the player controls with CSS variables:

| Variable                     | Default              | Description                |
| ---------------------------- | -------------------- | -------------------------- |
| `--helios-controls-bg`       | `rgba(0, 0, 0, 0.6)` | Controls bar background    |
| `--helios-text-color`        | `white`              | Text and icon color        |
| `--helios-accent-color`      | `#007bff`            | Accent for active elements |
| `--helios-range-track-color` | `#555`               | Scrubber track background  |
| `--helios-font-family`       | `sans-serif`         | UI font family             |

## Verification

Run the E2E verification suite:

```bash theme={null}
npx tsx tests/e2e/verify-player.ts
```

This uses Playwright to verify core functionality (playback, scrubber, menus, volume) with a dependency-free mock composition.
