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

# Debugging compositions

> Tools and techniques for debugging Helios compositions and render issues

## Overview

Debugging video rendering can be challenging because issues may only appear during headless rendering or at specific frames. Helios provides multiple debugging tools to help diagnose problems.

## Diagnostics API

The `Helios.diagnose()` static method checks environment capabilities.

### Client-side diagnostics

```typescript theme={null}
import { Helios } from '@helios-project/core';

const report = await Helios.diagnose();

console.log(report);
// {
//   waapi: true,
//   webCodecs: true,
//   offscreenCanvas: true,
//   webgl: true,
//   webgl2: true,
//   webAudio: true,
//   colorGamut: 'p3',
//   videoCodecs: { h264: true, vp8: true, vp9: true, av1: false },
//   audioCodecs: { aac: true, opus: true },
//   videoDecoders: { h264: true, vp8: true, vp9: true, av1: false },
//   audioDecoders: { aac: true, opus: true },
//   userAgent: 'Mozilla/5.0...'
// }
```

### Diagnostic fields

**`waapi`** - Web Animations API support (required for CSS animations)

**`webCodecs`** - WebCodecs API support (required for canvas rendering)

**`offscreenCanvas`** - OffscreenCanvas support (improves performance)

**`webgl` / `webgl2`** - WebGL support (required for Three.js, Pixi.js)

**`webAudio`** - Web Audio API support (required for audio mixing)

**`colorGamut`** - Display color gamut (`'srgb'`, `'p3'`, `'rec2020'`)

**`videoCodecs`** - Supported video encoders (H.264, VP8, VP9, AV1)

**`audioCodecs`** - Supported audio encoders (AAC, Opus)

**`videoDecoders`** - Supported video decoders

**`audioDecoders`** - Supported audio decoders

### Renderer diagnostics

For server-side rendering diagnostics:

```typescript theme={null}
import { Renderer } from '@helios-project/renderer';

const renderer = new Renderer({ mode: 'canvas' });
const diagnostics = await renderer.diagnose();

console.log(diagnostics);
// {
//   browser: {
//     webCodecs: true,
//     codecs: {
//       h264: { supported: true, hardware: true, alpha: false },
//       vp8: { supported: true, hardware: false, alpha: false },
//       vp9: { supported: true, hardware: false, alpha: false },
//       av1: { supported: false, hardware: false, alpha: false }
//     }
//   },
//   ffmpeg: {
//     version: '4.4.2',
//     encoders: ['libx264', 'libx265', 'libvpx', ...],
//     hwaccels: ['videotoolbox', 'cuda'],
//     filters: ['scale', 'overlay', ...]
//   }
// }
```

### Common issues

**WebCodecs not supported**

```typescript theme={null}
if (!report.webCodecs) {
  console.warn('WebCodecs not available. Use DOM rendering mode.');
  const renderer = new Renderer({ mode: 'dom' });
}
```

**No hardware acceleration**

```typescript theme={null}
const diagnostics = await renderer.diagnose();
const hasHardware = Object.values(diagnostics.browser.codecs)
  .some(codec => codec.hardware);

if (!hasHardware) {
  console.warn('No hardware encoders available. Rendering will be slower.');
}
```

**WebGL not available**

```typescript theme={null}
if (!report.webgl && !report.webgl2) {
  console.error('WebGL not supported. Three.js/Pixi.js will not work.');
}
```

## Headed mode

Run rendering in a visible browser window to see what's happening.

### Using CLI

```bash theme={null}
helios render composition.html --no-headless
```

This opens a browser window and shows the rendering process in real-time.

### Using API

```typescript theme={null}
import { Renderer } from '@helios-project/renderer';

const renderer = new Renderer({
  mode: 'canvas',
  browserConfig: {
    headless: false  // Show browser window
  }
});

await renderer.render('composition.html', 'output.mp4');
```

<Warning>
  Headed mode is slower than headless because it must render to the screen. Use only for debugging.
</Warning>

## Remote debugging

Connect Chrome DevTools to the headless browser for live debugging.

### Enable remote debugging

```typescript theme={null}
import { Renderer } from '@helios-project/renderer';

const renderer = new Renderer({
  mode: 'canvas',
  browserConfig: {
    headless: true,
    args: [
      '--remote-debugging-port=9222'  // Enable DevTools Protocol
    ]
  }
});
```

### Connect DevTools

1. Start the render
2. Open Chrome and navigate to `chrome://inspect`
3. Click "Configure" and add `localhost:9222`
4. Click "inspect" under "Remote Target"
5. Use Console, Network, Performance tabs as normal

### Debugging tips

**Inspect DOM state**

```javascript theme={null}
// In DevTools console
document.getAnimations().forEach(a => {
  console.log(a.id, a.currentTime, a.playState);
});
```

**Check canvas output**

```javascript theme={null}
const canvas = document.querySelector('canvas');
canvas.toBlob(blob => {
  const url = URL.createObjectURL(blob);
  console.log('Canvas frame:', url);
});
```

**Monitor memory**

```javascript theme={null}
if (performance.memory) {
  console.log('Heap:', performance.memory.usedJSHeapSize / 1024 / 1024, 'MB');
}
```

## Playwright trace viewer

Playwright can record a complete trace of the rendering session.

### Enable trace recording

```typescript theme={null}
import { Renderer } from '@helios-project/renderer';

const renderer = new Renderer({ mode: 'dom' });

await renderer.render('composition.html', 'output.mp4', {
  tracePath: 'trace.zip'  // Save trace
});
```

### View the trace

```bash theme={null}
npx playwright show-trace trace.zip
```

The trace viewer shows:

* **Timeline** - Frame-by-frame rendering progress
* **Screenshots** - Visual output at each step
* **Network** - Asset loading and requests
* **Console** - Log messages and errors
* **Source** - Code execution with source maps

### Debugging with traces

**Find slow frames**

Look for gaps in the timeline where rendering takes longer than expected.

**Check asset loading**

Verify fonts, images, and videos load before rendering starts.

**Inspect console errors**

Trace viewer captures all console output, including warnings and errors.

## Frame-by-frame debugging

Inspect output at specific frames.

### Export frames for inspection

```typescript theme={null}
import { Helios } from '@helios-project/core';

const helios = new Helios({ duration: 5, fps: 30 });

helios.subscribe((state) => {
  // Render frame
  renderer.render(scene, camera);
  
  // Export specific frames
  if ([0, 30, 60, 90].includes(state.currentFrame)) {
    exportFrame(state.currentFrame);
  }
});

function exportFrame(frame: number) {
  canvas.toBlob((blob) => {
    const url = URL.createObjectURL(blob!);
    console.log(`Frame ${frame}:`, url);
    
    // Download for inspection
    const a = document.createElement('a');
    a.href = url;
    a.download = `frame-${frame}.png`;
    a.click();
  });
}
```

### Seek to specific frame

```typescript theme={null}
const helios = new Helios({ duration: 10, fps: 30 });

// Jump to frame 150 (5 seconds at 30fps)
helios.seek(150);

// Wait for assets to stabilize
await helios.waitUntilStable();

// Inspect state
console.log('Frame 150 state:', helios.currentFrame.value);
```

## Console logging

Use console logs strategically to track state.

### Log frame state

```typescript theme={null}
helios.subscribe((state) => {
  if (state.currentFrame % 30 === 0) {
    console.log('Frame:', state.currentFrame);
    console.log('Time:', state.currentTime);
    console.log('Playing:', state.isPlaying);
  }
});
```

### Log animation state

```typescript theme={null}
helios.subscribe(() => {
  const animations = document.getAnimations();
  animations.forEach((anim, i) => {
    console.log(`Animation ${i}:`, {
      currentTime: anim.currentTime,
      playState: anim.playState,
      playbackRate: anim.playbackRate
    });
  });
});
```

### Log driver activity

Create a debug driver wrapper:

```typescript theme={null}
import { TimeDriver, DomDriver } from '@helios-project/core';

class DebugDriver implements TimeDriver {
  private inner: TimeDriver;

  constructor(inner: TimeDriver) {
    this.inner = inner;
  }

  init(scope: unknown) {
    console.log('[Driver] init', scope);
    this.inner.init(scope);
  }

  update(timeInMs: number, options: any) {
    console.log('[Driver] update', timeInMs, options);
    this.inner.update(timeInMs, options);
  }

  async waitUntilStable() {
    console.log('[Driver] waitUntilStable');
    await this.inner.waitUntilStable();
    console.log('[Driver] stable');
  }
}

const helios = new Helios({
  duration: 10,
  fps: 30,
  driver: new DebugDriver(new DomDriver())
});
```

## Common rendering issues

### Animations don't sync

**Symptom:** CSS animations play independently of Helios timeline

**Solution:** Enable `autoSyncAnimations`

```typescript theme={null}
const helios = new Helios({
  duration: 10,
  fps: 30,
  autoSyncAnimations: true  // Automatically pause and sync
});
```

### Fonts not loading

**Symptom:** Text renders with fallback fonts

**Solution:** Wait for fonts to load

```typescript theme={null}
// Wait for fonts
await document.fonts.ready;

// Or use waitUntilStable
await helios.waitUntilStable();

helios.play();
```

### Images appear blank

**Symptom:** Images don't render or show as broken

**Solution:** Preload images

```typescript theme={null}
const images = document.querySelectorAll('img');
const promises = Array.from(images).map(img => 
  img.complete ? Promise.resolve() : img.decode()
);

await Promise.all(promises);
```

### Canvas shows old frame

**Symptom:** Canvas doesn't update or shows stale content

**Solution:** Ensure you're rendering on every frame

```typescript theme={null}
helios.subscribe((state) => {
  // Clear canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  
  // Draw new frame
  drawFrame(state);
});
```

### Audio out of sync

**Symptom:** Audio doesn't match video timeline

**Solution:** Use `data-helios-offset` attribute

```html theme={null}
<audio 
  data-helios-track-id="bgm"
  data-helios-offset="2.5"
  src="music.mp3"
></audio>
```

### Memory leak during preview

**Symptom:** Browser slows down or crashes during long previews

**Solution:** Dispose and recreate Helios instance

```typescript theme={null}
let helios = new Helios({ duration: 10, fps: 30 });

// After some time
helios.dispose();
helios = new Helios({ duration: 10, fps: 30 });
```

## Performance debugging

### Measure frame render time

```typescript theme={null}
let totalTime = 0;
let frameCount = 0;

helios.subscribe((state) => {
  const start = performance.now();
  
  // Your render code
  renderer.render(scene, camera);
  
  const duration = performance.now() - start;
  totalTime += duration;
  frameCount++;
  
  if (state.currentFrame === state.duration * state.fps - 1) {
    console.log('Average frame time:', totalTime / frameCount, 'ms');
  }
});
```

### Identify bottlenecks

```typescript theme={null}
helios.subscribe((state) => {
  performance.mark('frame-start');
  
  performance.mark('physics-start');
  updatePhysics();
  performance.mark('physics-end');
  
  performance.mark('render-start');
  renderer.render(scene, camera);
  performance.mark('render-end');
  
  performance.measure('physics', 'physics-start', 'physics-end');
  performance.measure('render', 'render-start', 'render-end');
  performance.measure('total', 'frame-start', 'render-end');
  
  if (state.currentFrame % 30 === 0) {
    const entries = performance.getEntriesByType('measure');
    entries.forEach(entry => {
      console.log(entry.name, entry.duration.toFixed(2), 'ms');
    });
    performance.clearMarks();
    performance.clearMeasures();
  }
});
```

## Debug checklist

When debugging a render issue:

1. ✅ Run `Helios.diagnose()` to check environment
2. ✅ Enable headed mode to see visual output
3. ✅ Check browser console for errors
4. ✅ Verify assets load with `waitUntilStable()`
5. ✅ Test with simplified composition
6. ✅ Export specific frames for inspection
7. ✅ Use Playwright trace for detailed analysis
8. ✅ Profile with Chrome DevTools Performance tab

## Next steps

* Learn about [custom drivers](/advanced/custom-drivers) for specialized workflows
* Optimize [performance](/advanced/performance) for faster renders
* Explore [canvas and WebGL](/advanced/canvas-webgl) rendering patterns
