javascript、パソコンの画面を録画、キャプチャする

javascript

画面キャプチャ機能は、コンピュータの画面やウェブカメラの映像を録画する技術です。これにより、ユーザーは作業手順の記録やビデオチュートリアルの作成、プレゼンテーションの準備など様々な用途に活用できます。

一般的な実装では、ブラウザを通じてウェブカメラやディスプレイのストリームを取得し、それをビデオファイルとして保存します。この機能は教育、技術サポート、クリエイティブなコンテンツ制作などで特に重宝されています。

全体のコード

全体のコードを実装するだけで使えます。【録画開始】を押すと、Chromeタブウィンドウ画面全体。3ついずれか選択できます。お好みの場所を選択して、共有で録画が開始です。

<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>録画機能デモ</title>
  <style>
    div {
      width: 80vw;
      background-color: rgb(0, 22, 95);
      margin: 0 auto;
    }

    video {
      width: 100%;
    }
  </style>
</head>

<body>
  <!-- 録画中の映像を表示する要素 -->
  <div>
    <video id="recordVideo" autoplay muted style="display:block;"></video>
  </div>
  <!-- リプレイを表示する要素 -->
  <video id="replayVideo" autoplay controls width="800" height="600" style="display:none;"></video>
  <!-- 録画を動作するボタン -->
  <button id="start">録画開始</button>
  <button id="stop" disabled>録画停止</button>
  <button id="save" disabled>動画保存</button>

  <script>
    const recordVideo = document.getElementById('recordVideo');
    const replayVideo = document.getElementById('replayVideo');
    const startButton = document.getElementById('start');
    const stopButton = document.getElementById('stop');
    const saveButton = document.getElementById('save');
    let mediaRecorder;
    const recordedBlobs = []; // 録画されたデータを格納する配列

    // 録画を開始する関数
    async function startRecording() {
      // スクリーンのメディアストリームを取得
      const screenStream = await navigator.mediaDevices.getDisplayMedia({ video: true }).catch(err => console.error('スクリーン取得エラー', err));
      // 音声のメディアストリームを取得
      const audioStream = await navigator.mediaDevices.getUserMedia({ audio: true }).catch(err => console.error('音声取得エラー', err));
      // スクリーンのメディアストリームと音声のメディアストリームをマージする
      const stream = new MediaStream([...screenStream.getTracks(), ...audioStream.getTracks()]);
      // video要素にstreamを入れ込む
      recordVideo.srcObject = stream;
      // mimeTypeを設定
      const options = { mimeType: 'video/webm;codecs=vp9,opus' };
      mediaRecorder = new MediaRecorder(stream, options);
      mediaRecorder.ondataavailable = (event) => {
        if (event.data && event.data.size > 0) {
          // 録画データが格納される
          recordedBlobs.push(event.data);
        }
      };

      mediaRecorder.start();
      console.log('録画開始');
      startButton.disabled = true;
      stopButton.disabled = false;
    }

    // リプレイを再生
    function replay() {
      const blob = new Blob(recordedBlobs, { type: 'video/webm' });
      replayVideo.src = URL.createObjectURL(blob);
      replayVideo.style.display = 'block';
      replayVideo.controls = true;
      recordVideo.style.display = 'none';
      saveButton.disabled = false;
    }

    // 動画を保存
    function saveRecording() {
      const blob = new Blob(recordedBlobs, { type: 'video/webm' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.style.display = 'none';
      a.href = url;
      a.download = '録画ファイル.webm';
      document.body.appendChild(a);
      a.click();
      setTimeout(() => {
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
      }, 100);
    }

    // 録画を停止
    function stopRecording() {
      mediaRecorder.stop();
      console.log('録画停止');
      mediaRecorder.onstop = () => {
        replay();
        startButton.disabled = false;
        stopButton.disabled = true;
        recordVideo.srcObject.getTracks().forEach(track => track.stop());
      };
    }

    // イベントリスナーの設定
    startButton.addEventListener('click', () => {
      startRecording();
      startButton.disabled = true;
      stopButton.disabled = false;
    });

    stopButton.addEventListener('click', stopRecording);
    saveButton.addEventListener('click', saveRecording);
  </script>
</body>

</html>
HTML

変数の初期化と要素の取得

recordVideo、replayVideo、startButton、stopButton、saveButtonはそれぞれHTMLから対応する要素を取得します。
mediaRecorderは録画機能を管理するためのMediaRecorderオブジェクトです。
recordedBlobsは録画されたデータの配列で、mediaRecorder.ondataavailableイベントハンドラーでデータが追加されます。

const recordVideo = document.getElementById('recordVideo');
const replayVideo = document.getElementById('replayVideo');
const startButton = document.getElementById('start');
const stopButton = document.getElementById('stop');
const saveButton = document.getElementById('save');
let mediaRecorder;
const recordedBlobs = [];
JavaScript

録画を開始する関数

getDisplayMedia()を使用して画面キャプチャ用のストリームを取得し、getUserMedia()を使用して音声用のストリームを取得します。
MediaStreamオブジェクトを作成し、それをrecordVideoのsrcObjectに設定します。
MediaRecorderオブジェクトを作成し、指定したオプションで録画を開始します。
mediaRecorder.ondataavailableで録画データが利用可能になった際に、そのデータをrecordedBlobsに追加します。

async function startRecording() {
  const screenStream = await navigator.mediaDevices.getDisplayMedia({ video: true }).catch(err => console.error('スクリーン取得エラー', err));
  const audioStream = await navigator.mediaDevices.getUserMedia({ audio: true }).catch(err => console.error('音声取得エラー', err));
  const stream = new MediaStream([...screenStream.getTracks(), ...audioStream.getTracks()]);
  recordVideo.srcObject = stream;
  const options = { mimeType: 'video/webm;codecs=vp9,opus' };
  mediaRecorder = new MediaRecorder(stream, options);
  mediaRecorder.ondataavailable = (event) => {
    if (event.data && event.data.size > 0) {
      recordedBlobs.push(event.data);
    }
  };
  mediaRecorder.start();
  console.log('録画開始');
  startButton.disabled = true;
  stopButton.disabled = false;
}
JavaScript

動画を保存する関数

Blobオブジェクトを作成し、それをURLに変換してダウンロード可能なリンクとして設定します。
a.click()を使用してダウンロードを開始し、完了後に一時的に生成した要素を削除します。

function saveRecording() {
  const blob = new Blob(recordedBlobs, { type: 'video/webm' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.style.display = 'none';
  a.href = url;
  a.download = '録画ファイル.webm';
  document.body.appendChild(a);
  a.click();
  setTimeout(() => {
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }, 100);
}
JavaScript

イベントリスナーの設定

startButtonがクリックされた時、startRecording()関数が呼び出されます。これにより録画が開始されます。
startButton.disabled = true;により、startButtonが無効化され、二重での録画の開始を防止します。
stopButton.disabled = false;により、stopButtonが有効になり、録画を停止するオプションがユーザーに提供されます。

startButton.addEventListener('click', () => {
  startRecording();
  startButton.disabled = true;
  stopButton.disabled = false;
});
stopButton.addEventListener('click', stopRecording);
saveButton.addEventListener('click', saveRecording);
JavaScript

stopButtonがクリックされた時、stopRecording()関数が呼び出され、録画が停止します。
saveButtonがクリックされた時、saveRecording()関数が呼び出され、録画されたビデオを保存します。

まとめ

本記事では、画面キャプチャ機能を利用して、PC画面やブラウザタブ、ウィンドウの映像を録画・保存する方法を紹介しました。主なポイントは以下のとおりです。

  1. 画面および音声の取得
    • getDisplayMedia() を用いて画面(タブ・ウィンドウ・デスクトップ)をキャプチャし、
    • getUserMedia() を用いて音声を取得します。
    • 取得した2つのストリームを合成し、録画時に映像と音声を同時に記録します。
  2. MediaRecorderによる録画
    • 合成した MediaStream を MediaRecorder に渡すことで録画を開始します。
    • ondataavailable イベントで分割された録画データを配列に格納し、録画停止後にまとめて動画ファイルとして扱います。
  3. 録画の再生と保存
    • 録画したデータは Blob オブジェクトに変換し、URL.createObjectURL() でURLを生成してビデオ要素に再生させることが可能です。
    • 同じ仕組みを使ってアンカータグからダウンロードすれば、録画データをローカルファイルとして保存できます。
  4. UI(ボタン操作)
    • 「録画開始(Start)」「録画停止(Stop)」「動画保存(Save)」ボタンを用意し、それぞれの処理をイベントリスナーに実装することで、直感的に録画の開始・停止・保存ができます。

本サンプルを参考にすることで、ユーザーは簡単に画面録画・音声録画を行い、そのまま保存・再生まで完結できるWebアプリを作成できます。シンプルな実装ながらも、チュートリアル作成やプレゼン録画など、幅広い用途に応用できるのが大きな利点です。

コメント

タイトルとURLをコピーしました