JavaScript
Chrome
headless

ヘッドレスブラウザ Chrome + Chromy で操作した内容を録画する

Chromeのブラウザ内(もしくはデスクトップ)操作をJavaScriptで録画するに続いて、今度はヘッドレスブラウザ (Chrome) で操作した内容をビデオ録画する方法を紹介します。今回は Chromy というライブラリを利用します。

機能的には Chrome DevTool に用意されている startScreencast を利用します。Chrome ヘッドレスブラウザのライブラリといえば puppeteer という感じがあるのですが、 Chromy は startScreencast のラッパーを用意してくれているので、サクッと使えるのが良いところです。

サンプルコード

指定のページを開いて startScreencast をした後、なんらかの操作をします。その後、 stopScreencast で処理を終了すると startScreencast コールバックで受け取ったキャプチャデータを画像ファイルとして保存してあげているだけです。この時点では単なる画像ファイルです。

const Chromy = require('chromy')
const fs = require('fs')

let chromy = new Chromy()
let frameNum = 0
chromy.chain()
      .goto('https://noco.fun/b/vjhqmkzFIDjJNLuLDGrj/e/vgCqD11cYntd173Y4JvB/?scene=0')
      .startScreencast(async (payload) => {
        frameNum++
        fs.writeFileSync(
          `./frame${String(frameNum).padStart(5, '0')}.png`,
          payload.data, { encoding: 'base64' })
      }, {format: 'png'})
      .sleep(5000)
      .evaluate(_ => {
        document.querySelector('.episode-player__goto-nextframe-button').click()
      })
      .sleep(1000)
      .evaluate(_ => {
        document.querySelector('.episode-player__goto-nextframe-button').click()
      })
      .sleep(1000)
      .evaluate(_ => {
        document.querySelector('.episode-player__goto-nextframe-button').click()
      })
      .sleep(1000)
      .evaluate(_ => {
        document.querySelector('.episode-player__goto-nextframe-button').click()
      })
      .sleep(1000)
      .stopScreencast()
      .sleep(3000)
      .end()
      .then(_ => chromy.close())
      .catch(_ => { console.log(_); chromy.close() })

ffmpeg で動画へ結合

このままだと単なるパラパラマンガになってしまうので ffmpeg コマンドで結合します。フレームレートは適当です。

ffmpeg -r 6 -i frame%05d.png -pix_fmt yuv420p -r 10 output.mp4

これで晴れて mp4 ファイルになって操作の様子を動画に録画することができました。ヘッドレスブラウザなので裏で何かの処理を再現したりするのに使えそうです。

デモ

さすがに 60fps のようなヌルヌル感はないですが、ぎりぎり使えるくらいの感じにはなってるかなと思います。ただクオリティ重視の場合はちょっと厳しいかな。

output.gif

mp4 をアニメーション GIF に変換したので画質はあれですが再生感はこんな感じです。