@browserless/screencast
Version:
Capture website interactions frame-by-frame to create videos and GIFs. Perfect for demos, tutorials, and automated testing.
211 lines (151 loc) • 6.46 kB
Markdown
<div align="center">
<img style="width: 500px; margin:3rem 0 1.5rem;" src="https://github.com/microlinkhq/browserless/raw/master/static/logo-banner.png#gh-light-mode-only" alt="browserless">
<img style="width: 500px; margin:3rem 0 1.5rem;" src="https://github.com/microlinkhq/browserless/raw/master/static/logo-banner-light.png#gh-dark-mode-only" alt="browserless">
<br><br>
<a href="https://microlink.io"><img src="https://img.shields.io/badge/powered_by-microlink.io-blue?style=flat-square&color=%23EA407B" alt="Powered by microlink.io"></a>
<img src="https://img.shields.io/github/tag/microlinkhq/browserless.svg?style=flat-square" alt="Last version">
<a href="https://coveralls.io/github/microlinkhq/browserless"><img src="https://img.shields.io/coveralls/microlinkhq/browserless.svg?style=flat-square" alt="Coverage Status"></a>
<a href="https://www.npmjs.org/package/browserless"><img src="https://img.shields.io/npm/dm/browserless.svg?style=flat-square" alt="NPM Status"></a>
<br><br>
</div>
> @browserless/screencast: Browserless video recording using puppeteer.
See the [screencast section](https://browserless.js.org/#/?id=screencast) on our website for more information.
## Install
Using npm:
```sh
npm install @browserless/screencast --save
```
## About
This package provides **frame-by-frame video capture** from browser page navigation using the Chrome DevTools Protocol. It allows you to capture individual frames during page interactions for creating GIFs, videos, or frame-by-frame analysis.
### What This Package Does
The `@browserless/screencast` package allows you to:
- **Capture frames** during browser navigation and interactions
- **Control recording** with start/stop methods
- **Process frames** individually via callback functions
- **Configure quality and format** for captured frames
- **Create animations** like GIFs from captured frames
### Usage
```js
const createScreencast = require('@browserless/screencast')
const createBrowser = require('browserless')
const browser = createBrowser()
const browserless = await browser.createContext()
const page = await browserless.page()
const createScreencast = require('@browserless/screencast')
const createBrowser = require('browserless')
const browser = createBrowser()
const browserless = await browser.createContext()
const page = await browserless.page()
// Create screencast instance
const screencast = createScreencast(page, {
maxWidth: 1280,
maxHeight: 800
})
// Collect frames
const frames = []
screencast.onFrame((data, metadata) => {
frames.push({ data, metadata })
})
// Record during navigation
screencast.start()
await browserless.goto(page, { url: 'https://example.com' })
await screencast.stop()
console.log(`Captured ${frames.length} frames`)
```
### API
#### `createScreencast(page, options)`
Creates a screencast instance for the given Puppeteer page.
**Returns** an object with:
| Method | Description |
|--------|-------------|
| `start()` | Begin capturing frames |
| `stop()` | Stop capturing frames |
| `onFrame(callback)` | Register frame handler |
### Options
All options are passed directly to [Page.startScreencast](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-startScreencast):
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `format` | `string` | `'jpeg'` | Image format: `'jpeg'` or `'png'` |
| `quality` | `number` | `80` | JPEG quality (0-100), ignored for PNG |
| `maxWidth` | `number` | — | Maximum width of captured frames |
| `maxHeight` | `number` | — | Maximum height of captured frames |
| `everyNthFrame` | `number` | `1` | Capture every Nth frame |
### Frame callback
The `onFrame` callback receives two arguments:
```js
screencast.onFrame((data, metadata) => {
// data: base64-encoded image string
// metadata: { timestamp, ... }
})
```
| Argument | Type | Description |
|----------|------|-------------|
| `data` | `string` | Base64-encoded frame image |
| `metadata` | `object` | Frame metadata including `timestamp` |
### Examples
#### Create a GIF from navigation
```js
const { GifEncoder } = require('@skyra/gifenc')
const { createCanvas, Image } = require('canvas')
const sharp = require('sharp')
const width = 640
const height = 400
const canvas = createCanvas(width, height)
const ctx = canvas.getContext('2d')
const encoder = new GifEncoder(width, height)
const screencast = createScreencast(page, {
maxWidth: width,
maxHeight: height
})
screencast.onFrame(async data => {
const frame = Buffer.from(data, 'base64')
const buffer = await sharp(frame).resize({ width, height }).toBuffer()
const img = new Image()
img.src = buffer
ctx.drawImage(img, 0, 0)
encoder.addFrame(ctx)
})
encoder.start()
screencast.start()
await browserless.goto(page, { url: 'https://example.com' })
encoder.finish()
await screencast.stop()
```
#### Capture specific frames
```js
const screencast = createScreencast(page, {
format: 'png',
quality: 100,
everyNthFrame: 5 // Capture every 5th frame
})
screencast.onFrame((data, metadata) => {
console.log(`Frame at ${metadata.timestamp}`)
// Save or process the frame
})
```
#### Save frames to disk
```js
const fs = require('fs/promises')
let frameCount = 0
screencast.onFrame(async data => {
const buffer = Buffer.from(data, 'base64')
await fs.writeFile(`frame-${frameCount++}.jpg`, buffer)
})
screencast.start()
await page.goto('https://example.com')
await screencast.stop()
```
### How it fits in the monorepo
This is an **extended functionality package** for video/animation capture:
| Consumer | Purpose |
|----------|---------|
| User applications | Creating GIFs, video recording, visual testing |
### Dependencies
| Package | Purpose |
|---------|---------|
| `null-prototype-object` | Clean objects without prototype chain |
## License
**@browserless/screencast** © [Microlink](https://microlink.io), released under the [MIT](https://github.com/microlinkhq/browserless/blob/master/LICENSE.md) License.<br>
Authored and maintained by [Microlink](https://microlink.io) with help from [contributors](https://github.com/microlinkhq/browserless/contributors).
The [logo](https://thenounproject.com/term/browser/288309/) has been designed by [xinh studio](https://xinh.studio).
> [microlink.io](https://microlink.io) · GitHub [microlinkhq](https://github.com/microlinkhq) · X [@microlinkhq](https://x.com/microlinkhq)