Experiments >

Code animation: Rendering server

Experiment #176 ā— 6th May, 2021 ā— by Joshua Nussbaum

Back in experiment #7, I looked into rendering video with playwright.

But that experiment used a local script.

What Iā€™d prefer, is rendering the video on demand via an endpoint on the server, or maybe even in a lambda function.


This example comunicates with chromium during the request. It would be better to use a background job, since this could take time.

import express from 'express'
import bodyParser from 'body-parser'
import {chromium} from 'playwright'
import path from 'path'
import fs from 'fs'

const app = express()


app.post('/render', async (req, res) => {
  const file = await run(req.body)
  const absPath = path.resolve(file, "./")

  console.log(await fs.promises.readFile(absPath, 'utf-8'))


app.listen(process.env.PORT || 3000)

const run = async ({viewport, dimensions, duration, url}) => {
  const browser = await chromium.launch()
  const context = await browser.newContext({
    recordVideo: {
      dir: 'videos/',
      size: dimensions
  const page = await context.newPage()

  await page.goto(url)
  await page.waitForTimeout(duration)
  await context.close()
  await browser.close()

  return await page.video().path()

And a request is made like this:

curl localhost:3000/render 
  --header 'content-type: application/json' 
  --data '{"viewport": {"width": 1920, "height": 1080}, "dimensions": {"width": 1920, "height": 1080}, "duration": 3000, "url": "https://google.com"}' 
  --output example.webm

That saves the video to example.webm


  • Use a background job.
  • Synchronize the start time of the video. This has no control over how long chromium takes to start up, so the video size is variable. It will probably need to be cropped after this stage to remove the dead time at the beginning.
  • Does this work in the cloud? what setup is needed to run chromium/playright in the cloud?
view all experiments

Stay tuned in

Learn how to add more experimentation to your workflow