ScreenshotNeo

BlogHow-to

How to Create a Screenshot Video of a Website

Learn when to use screen recording, getDisplayMedia, or Playwright to create a website screenshot video, with runnable code and editing tips.

By the ScreenshotNeo team1 October 20268 min read

1. Choose the right way to make a website video

The best method depends on what the video must show:

Goal Best method What you get Permission needed
Show a person scrolling or clicking once Windows Snipping Tool or another screen recorder A quick video file with optional editing Operating-system permission may apply
Record a browser tab from a web app getDisplayMedia() WebM stream saved by the browser The user must choose a tab, window, or screen
Produce repeatable developer demos Playwright video recording Scripted WebM recordings of browser actions Browser automation setup
Turn a tall static page into motion Capture screenshots, then assemble frames A pan or scroll-style video None for local files; follow site terms for remote pages

Use a still image when the page is static. Use video when scrolling, hover states, clicks, narration, or timing are part of the explanation.

2. Record a website with Windows Snipping Tool

  1. Open the site in a clean browser window. Close unrelated tabs, notifications, and any personal information.
  2. Press Windows logo key + Shift + R, or open Snipping Tool and select Record, then New. Microsoft documents this as the Video snip workflow.
  3. Drag around the browser region you want to show.
  4. Perform the scroll, clicks, or hover actions at a steady pace.
  5. Stop the recording and save the clip.
  6. Select Edit in Clipchamp if you need captions, audio, trimming, or other edits.

This is the fastest option for a one-off walkthrough. It records what is visible, so keep the browser zoom, window size, pointer position, and page state consistent.

Microsoft Edge also has a Screenshot command that can capture an entire webpage, a selected area, or moving content. Press Ctrl+Shift+S to open it, then copy or save the result. That produces still captures; use Snipping Tool or a browser recorder when you need motion.

3. Record a browser tab with getDisplayMedia()

A browser-native recorder calls navigator.mediaDevices.getDisplayMedia() after a user gesture. The browser then asks the user to select a tab, window, or screen. The returned video track can be previewed locally and recorded as WebM. Permission is mandatory.

Complete runnable example

<!doctype html>
<meta charset="utf-8">
<title>Website tab recorder</title>
<button id="start">Choose tab and start</button>
<button id="stop" disabled>Stop and download</button>
<video id="preview" autoplay muted playsinline style="max-width:100%"></video>
<script>
let stream;
let recorder;
let chunks = [];
const preview = document.querySelector('#preview');
const start = document.querySelector('#start');
const stop = document.querySelector('#stop');

start.addEventListener('click', async () => {
  try {
    stream = await navigator.mediaDevices.getDisplayMedia({
      video: { cursor: 'always' },
      audio: true
    });
    preview.srcObject = stream;
    chunks = [];
    recorder = new MediaRecorder(stream, { mimeType: 'video/webm' });
    recorder.ondataavailable = event => {
      if (event.data.size > 0) chunks.push(event.data);
    };
    recorder.onstop = () => {
      const blob = new Blob(chunks, { type: 'video/webm' });
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = 'website-recording.webm';
      link.click();
      URL.revokeObjectURL(url);
    };
    stream.getVideoTracks()[0].addEventListener('ended', stopRecording);
    recorder.start(1000);
    start.disabled = true;
    stop.disabled = false;
  } catch (error) {
    console.error(error);
    alert('Screen sharing was cancelled or is unavailable.');
  }
});

stop.addEventListener('click', stopRecording);
function stopRecording() {
  if (recorder && recorder.state !== 'inactive') recorder.stop();
  if (stream) stream.getTracks().forEach(track => track.stop());
  preview.srcObject = null;
  start.disabled = false;
  stop.disabled = true;
}
</script>

Run this from a secure context such as HTTPS or localhost. The user must click the start button; calling getDisplayMedia() on page load will be rejected by browsers. The cursor setting keeps the pointer visible when supported. Remove audio: true if you do not want system or tab audio.

The browser may return a different MIME type on a particular platform. If video/webm is rejected, inspect MediaRecorder.isTypeSupported() and choose a supported type before constructing the recorder.

4. Create repeatable videos with Playwright

Playwright can record browser automation sessions as WebM for debugging, documentation, or verification. Its video options support cursor rendering, target highlights, click-point markers, and chapter markers.

Install and record with Node.js

npm init -y
npm install -D playwright
npx playwright install chromium
// record-website.mjs
import { chromium } from 'playwright';

const browser = await chromium.launch({ headless: false });
const context = await browser.newContext({
  recordVideo: { dir: 'videos', size: { width: 1440, height: 900 } }
});
const page = await context.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle' });
await page.waitForTimeout(1000);
await page.mouse.wheel(0, 700);
await page.waitForTimeout(800);
await page.getByRole('link').first().click();
await page.waitForTimeout(1000);
await context.close(); // flushes the WebM file
await browser.close();

Use a fixed viewport, explicit waits, and deterministic test data so repeated runs produce comparable clips. Close the context before the process exits; Playwright finalizes the video at that point.

Python version

pip install playwright
playwright install chromium
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    context = browser.new_context(
        record_video_dir="videos",
        record_video_size={"width": 1440, "height": 900},
    )
    page = context.new_page()
    page.goto("https://example.com", wait_until="networkidle")
    page.wait_for_timeout(1000)
    page.mouse.wheel(0, 700)
    page.wait_for_timeout(800)
    page.get_by_role("link").first.click()
    page.wait_for_timeout(1000)
    context.close()  # flushes the WebM file
    browser.close()

Make scripted demos readable

  • Move the pointer slowly before clicking.
  • Pause after navigation and after major UI changes.
  • Use target highlighting or click-point decoration when your Playwright version supports it.
  • Split a long workflow into chapters so viewers can find each action.
  • Keep authentication and private data out of recordings; use a dedicated demo account.

5. Turn screenshots into a scrolling video

For a static page, capture several vertical sections or one full-page image, then animate a crop moving from top to bottom. This avoids recording network delays and gives you deterministic output.

  1. Capture the page at a fixed viewport and device scale.
  2. Remove cookie banners, chat widgets, and other overlays before capturing.
  3. Choose a video frame size and a constant pan speed.
  4. Animate the image in your editor, or render a sequence of frames.
  5. Add captions or a voiceover only after the motion is easy to follow.

A screenshot API can supply the frames, but it does not replace a video editor or encoder. For an interactive page, use Playwright or getDisplayMedia() so clicks and hover states are recorded.

6. Edit and export the recording

  • Trim setup time, loading delays, and accidental clicks.
  • Keep the pointer visible when it explains an action.
  • Add short captions for URLs, keyboard shortcuts, or expected results.
  • Record narration separately when the browser audio is noisy.
  • Export to the destination’s current resolution, frame-rate, and file-size requirements.

Always watch the exported file from start to finish. A source preview can look correct while the saved file has missing audio, a clipped ending, or an unflushed final second.

7. Or skip the browser setup

ScreenshotNeo is useful when you need clean website screenshots as repeatable frames. It accepts one GET request and returns PNG, JPEG, WebP, or PDF. Use the DIY recording methods above for motion; use ScreenshotNeo when you need consistent stills to place into a video timeline.

Before capture, ScreenshotNeo can accept cookie or consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets. Each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.

It also supports full-page capture with lazy images loaded, CSS element capture, dark mode, device presets, arbitrary viewports, retina scale, custom CSS and JavaScript, clicks, selector or network-idle waits, blocked resources, headers, cookies, user agents, authorization, timezone, geolocation, transparency, resizing, configurable caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. An MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the ScreenshotNeo documentation for the full parameter list and response headers. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots, and every feature is available on every plan. An MCP server lets AI agents take screenshots. Create a free ScreenshotNeo account.

8. Troubleshooting

Problem Likely cause Fix
No tab or window appears in the picker The call was not triggered by a user gesture, or the browser blocked it Start from a button click, use HTTPS or localhost, and check browser permissions.
Recording stops when the tab closes The captured video track ended Handle the track’s ended event and save the chunks already received.
WebM file is empty or truncated The recorder or Playwright context was not stopped cleanly Call recorder.stop(); close the Playwright context before exiting.
Playwright video has different timing each run Network and animations are nondeterministic Wait for a stable selector or network idle, fix the viewport, and use explicit pauses.
Cookie banner covers the page The page requires consent before content is usable Accept it during the script, hide it with an approved selector, or use ScreenshotNeo’s consent cleanup.
Audio is missing Tab audio was not shared or the export omitted it Request audio in getDisplayMedia(), select a tab that shares audio, and verify the exported file.
Private information appears A personal tab, notification, or account was captured Use a clean profile and dedicated demo account; review the entire clip before publishing.

9. Performance, reliability, and cost notes

  • Screen recording uses local CPU, GPU, and disk bandwidth. Lower the browser window size when full resolution is unnecessary.
  • getDisplayMedia() depends on an interactive permission prompt, so it is not suitable for unattended jobs.
  • Playwright is repeatable, but page changes, third-party scripts, and network latency can still alter timing. Wait on meaningful page state instead of fixed sleeps alone.
  • For many static pages, cache identical captures and assemble videos from frames. ScreenshotNeo lets you choose a cache TTL and reports whether a response was billed.
  • Budget storage for raw WebM files and edited exports. Delete intermediate recordings after publishing.
  • ScreenshotNeo pricing is Free: 1,000 shots/month; Starter: $5 for 3,000; Growth: $15 for 15,000; Pro: $39 for 60,000; Scale: $99 for 250,000; Business: $249 for 1,000,000. Yearly billing gives two months free.

10. FAQ

Can I record a website without installing software?

Yes. A page using getDisplayMedia() can record a selected tab in a supported browser, although the user must approve the share prompt.

What format does browser capture produce?

The documented browser example records and saves WebM. Check MIME support at runtime when targeting multiple browsers.

Is a full-page screenshot a video?

No. It is a still image. Add animated panning to create motion, or record the browser when interactions matter.

How do I make a demo repeatable?

Use Playwright with a fixed viewport, deterministic data, explicit waits, and a clean browser context. Save the video only after closing the context.

Can ScreenshotNeo create the video file?

ScreenshotNeo returns screenshots or PDFs. Use its consistent screenshots as frames, then assemble and edit them with your video tooling.