How the ego-lite Screencast Driver Captures Video and Manages Quality Settings
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 and the encoding wrapper in 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 (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. 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 (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). 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
qualityoption (0-100) passed toPage.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
VideoRecorderconstructor (lines 66-76 invideo-recorder.ts), where parameters like-crf 8control 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. 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:
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:
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.tsorchestrates CDPPage.startScreencastcommands 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 (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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →