Using the Screen Capture API to record a browser window – alexwlchanSkip to main contentUsing the Screen Capture API to record a browser window<br>Posted 7 June 2026<br>I was on the Lego website recently, and I enjoyed their animation on their age picker – rather than a plain text field, the numbers are made of Lego bricks that animate into view, accompanied by the sound of bricks snapping together:<br>Recorded from identity.lego.com/en-GB/age, 6 June 2026. Lego was founded in 1932 by Ole Kirk Christiansen. He purchased the first plastic moulding machine in 1947, and patented the stub-and-tube coupling system in 1958.I don’t know if this age picker is visible everywhere, or if it’s specifically to deal with online age verification laws in the UK; whatever the purpose, I thought it was cute.<br>I wanted to save a copy of it, and because it has animation and audio, a static screenshot wouldn’t be enough. It took me a couple of attempts to record it as a video, and in doing so I learnt several new web APIs.<br>Rejected option #1: use QuickTime screen recording<br>On macOS, QuickTime Player can make a video recording of your screen. You can select the entire screen, a single window, or a specific area of the screen. I’ve used this a couple of times for bug reports and quick videos, and it works pretty well.<br>Unfortunately, QuickTime Player isn’t able to record the audio, so it only creates a silent version of the animation. The sounds of bricks snapping together is half the fun!<br>A quick search suggests there are ways to record screen audio in QuickTime Player, but they all require installing third-party plugins to make my Mac’s audio available as a pseudo-microphone. I’m very picky about what I install, and making a fun video doesn’t justify a new app.<br>Rejected option #2: use Playwright video recording<br>One tool I have installed already is Playwright, a framework for automating browsers. I use it to take screenshots and test my websites, and it turns out you can also use it to record videos.<br>To record a video, you create a new browser context which sets a video directory, interact with the page as normal, then close the context to save the video. Here’s an example using Playwright’s Python library to open my list of articles, then scrolls three times:<br>from playwright.sync_api import sync_playwright<br>import time
with sync_playwright() as p:<br>browser = p.chromium.launch()
# Create a new context that sets a video directory<br>context = browser.new_context(record_video_dir="videos/")
# Open my list of articles, then scroll down the page three times<br>page = context.new_page()<br>page.goto("https://alexwlchan.net/articles/")
for _ in range(3):<br>time.sleep(0.5)<br>page.mouse.wheel(0, 250)<br>time.sleep(0.5)
# Close the context, which causes the video to be saved<br>context.close()When you run this script, you get a video in the videos/ directory.<br>I can imagine this might be useful in a large test suite, especially in a complex multi-step test. When a test fails, you can watch a screen recording of the browser during the test, which could be more informative than a textual log. (Indeed, Playwright has a video=retain-on-failure option which only preserves videos created during failing tests, for precisely this use case.)<br>I ran into two problems with this approach: like QuickTime, you can’t record screen audio; and you can only record videos at 1× pixel density, which makes a very low-resolution and blurry-looking video on modern screens.<br>Option #3: use the web’s Screen Capture API<br>Once again I am reminded that modern web tech is amazing, and web browsers are incredibly capable.<br>There’s a Screen Capture API to record the screen. You can select a tab, a window, or the entire screen. The feature has limited browser support so I don’t think I’d use it in a big web app, but it’s fine for a one-off screen recording. (I wonder how browser-based video conference apps like Google Meet do screen sharing? Do they use this API, or do they use something with wider support?)<br>To record video, first we call getDisplayMedia() to get the contents of a tab as a MediaStream. Using the example from the MDN docs:<br>async function startCapture(displayMediaOptions) {<br>let captureStream;
try {<br>captureStream =<br>await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);<br>} catch (err) {<br>console.error(`Error: ${err}`);<br>return captureStream;
const displayMediaOptions = {<br>// Only allow the user to select a single browser tab<br>video: { displaySurface: 'browser' },
// Include the audio from the tab<br>audio: true,
// Offer the current tab as the default capture source<br>preferCurrentTab: true,<br>};
const stream = await startCapture(displayMediaOptions);When you run this in the DevTools console, it triggers a permissions dialog to confirm you want to start recording the contents of the tab. The JavaScript is running on the current page, so it’s theoretically able to see the stream you’re creating. You have to confirm you’re willing to share the website with itself:<br>If we didn’t set...