# How the ego-lite Screencast Driver Captures Video and Manages Quality Settings

> Discover how the ego-lite screencast driver captures video using CDP commands and manages quality settings from 0-100, encoding output as VP8 WebM.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: how-to-guide
- Published: 2026-08-07

---

**The ego-lite screencast driver captures viewport video by orchestrating Chrome DevTools Protocol (CDP) commands to stream JPEG frames into an ffmpeg-backed VideoRecorder, validating quality settings between 0-100 for source compression while encoding final output as VP8 WebM.**

The screencast functionality in the citrolabs/ego-lite repository enables automated recording of browser sessions through a TypeScript driver that bridges CDP events with ffmpeg encoding. Understanding how the ego-lite screencast driver handles video capture and quality configuration requires examining the interaction between frame acquisition pipelines and the underlying encoding parameters.

## Architecture Overview

The implementation spans two primary modules within `package/ego-browser/src/`: the orchestration logic in [`driver/screencast.ts`](https://github.com/citrolabs/ego-lite/blob/main/driver/screencast.ts) and the encoding wrapper in [`video-recorder.ts`](https://github.com/citrolabs/ego-lite/blob/main/video-recorder.ts). When invoked, the driver establishes a CDP session to capture raw frames from the Chrome viewport and pipes them through an ffmpeg process configured for VP8 WebM output with specific quality constraints.

## Initializing the Screencast Session

### Quality Validation

The `startScreencast()` function accepts a `quality` parameter that defaults to **90** if omitted. According to the source code in [`package/ego-browser/src/driver/screencast.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/screencast.ts) (lines 43-46), the driver enforces strict validation that the value must be an integer between **0 and 100**, rejecting out-of-range requests before initiating the capture pipeline.

### VideoRecorder Instantiation

Upon successful validation, the driver creates a `VideoRecorder` instance defined in [`package/ego-browser/src/video-recorder.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/video-recorder.ts). This class spawns an **ffmpeg** child process configured to receive raw JPEG frames via stdin and encode them into a silent VP8 WebM file. The constructor initializes ffmpeg with specific quality arguments including `-qmin 0`, `-qmax 50`, `-crf 8`, and `-speed 8` to balance encoding speed and output quality.

## Frame Capture Pipeline

### CDP Screencast Commands

The driver initiates capture by sending the `Page.startScreencast` command through the Chrome DevTools Protocol, as implemented in [`package/ego-browser/src/driver/screencast.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/screencast.ts) (lines 106-108). This request includes the validated `quality` value—controlling JPEG compression levels—and maximum viewport dimensions rounded to even numbers. The driver subscribes to the `Page.screencastFrame` event to receive incoming frame data.

### Frame Processing and Timestamps

Each incoming `Page.screencastFrame` event delivers base64-encoded JPEG data representing the current viewport state. The driver decodes this data and passes it to `VideoRecorder.writeFrame()`, which timestamps the frame using CDP metadata when available, or falls back to `Date.now()` if the metadata is missing (see lines 83-88 in [`screencast.ts`](https://github.com/citrolabs/ego-lite/blob/main/screencast.ts)). The recorder queues these timestamped frames for ffmpeg consumption, maintaining temporal accuracy in the final video.

## Stopping and Finalizing Recordings

The `stopScreencast()` method handles graceful session termination. If the driver received no frames during the recording session—such as when a page fails to render—it automatically falls back to capturing a single screenshot using the same `quality` setting (lines 138-142). The driver then sends `Page.stopScreencast` to halt CDP events, signals the `VideoRecorder` to close the ffmpeg process via its cleanup routines, and resolves the disposable resource to finalize the WebM file.

## Configuring Video Quality

### Input vs. Output Quality

The screencast driver operates with two distinct quality domains that developers must distinguish:

- **Input JPEG Quality**: Controlled by the `quality` option (0-100) passed to `Page.startScreencast`, affecting compression artifacts and file size of individual source frames captured from Chrome
- **Output WebM Quality**: Determined by ffmpeg encoding flags baked into the `VideoRecorder` constructor (lines 66-76 in [`video-recorder.ts`](https://github.com/citrolabs/ego-lite/blob/main/video-recorder.ts)), where parameters like `-crf 8` control the final VP8 bitrate and visual fidelity regardless of the input JPEG quality

### Customizing Encoding Parameters

While the `quality` option adjusts source JPEG compression for frames transmitted over CDP, modifying the final WebM bitrate or codec requires editing the ffmpeg argument array in [`package/ego-browser/src/video-recorder.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/video-recorder.ts). The default configuration prioritizes encoding speed and reasonable file sizes, but developers can adjust `-crf` values or add bitrate limits to suit specific archival requirements.

## Code Examples

Start a screencast at 720 × 480 with JPEG quality 80:

```javascript
const { dispose } = await page.screencast.start({
  path: '/tmp/demo.webm',
  size: { width: 720, height: 480 },
  quality: 80,           // ← JPEG quality (0‑100)
});

// …do whatever you need while the page is being recorded…

// Stop and finalize the recording
await dispose();   // also works via `await page.screencast.stop()`

```

Using the low-level driver directly for custom pipelines:

```javascript
import { startScreencast, stopScreencast } from './driver/screencast.js';

await startScreencast({ path: 'out.webm', quality: 70 });
/* … page interactions … */
await stopScreencast();   // finalizes the WebM file

```

## Summary

- The **ego-lite screencast driver** in [`package/ego-browser/src/driver/screencast.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/screencast.ts) orchestrates CDP `Page.startScreencast` commands to capture viewport frames.
- **Quality validation** enforces integers between 0-100, defaulting to 90, which controls JPEG compression of source frames.
- The **VideoRecorder** class spawns ffmpeg with VP8 encoding parameters (`-qmin 0 -qmax 50 -crf 8`) to produce WebM output from raw JPEG streams.
- **Timestamp handling** uses CDP metadata when available, falling back to system time for frame synchronization.
- A **fallback screenshot mechanism** captures a single frame if no screencast events occur during the recording session.

## Frequently Asked Questions

### What quality values does the ego-lite screencast driver support?

The driver accepts integer values between **0 and 100** for the `quality` parameter, defaulting to **90** if not specified. This value controls the JPEG compression quality of individual frames captured via Chrome DevTools Protocol before they are encoded into the final WebM video.

### How does ego-lite encode the captured video?

The driver utilizes a `VideoRecorder` class that spawns an **ffmpeg** process configured with VP8 codec parameters. The encoder receives raw JPEG frames via pipe and outputs a silent WebM file using arguments including `-qmin 0 -qmax 50 -crf 8 -speed 8`, which balances encoding speed with visual quality independent of the source JPEG quality setting.

### What happens if no frames are captured during a recording session?

If the `stopScreencast()` method detects that no frames were received—such as when a page fails to render content—the driver automatically falls back to capturing a single screenshot using the same `quality` setting before finalizing the output file, ensuring the recording contains at least one visual frame.

### Can I customize the output format or encoding settings?

While the default output is VP8 WebM, you can modify the encoding parameters by editing the ffmpeg argument list in the `VideoRecorder` constructor located at [`package/ego-browser/src/video-recorder.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/video-recorder.ts) (lines 66-76). Changing the `quality` option only affects input JPEG compression; adjusting the final video bitrate or codec requires modifying these ffmpeg flags directly.