4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

シンプルで使いやすいブラウザ画面の録画ツール。

Last updated at Posted at 2024-11-06

スクリーンショット 2024-11-07 054138.png

image.png

image.png

コードをメモ帳などのテキストエディタに貼り付け、ファイル名を「index.html」として保存します。その後、保存したファイルをブラウザで開けば、コードが実行されます。

機能の流れ
ページが読み込まれると、録画開始ボタンが表示されます。
「録画開始」をクリックすると、画面録画が始まります。共有するページを選択。

共有停止で録画終了。

再度「録画終了」をクリックすると録画が終了し、録画した内容がMP4ファイルとしてダウンロードフォルダにダウンロードされます。
シンプルで使いやすいブラウザ画面の録画ツールが実現しました!

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>画面録画</title>
    <style>
        /* ページ全体のスタイル */
        body {
            font-family: 'Arial', sans-serif;
            background-color: #f4f7fa;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }

        /* 録画ボタンのスタイル */
        #recordButton {
            padding: 15px 30px;
            font-size: 18px;
            cursor: pointer;
            border: none;
            border-radius: 8px;
            background-color: #007bff;
            color: white;
            transition: background-color 0.3s ease, transform 0.3s ease;
        }

        /* ボタンのホバー時の効果 */
        #recordButton:hover {
            background-color: #0056b3;
            transform: scale(1.05); /* 少し大きくなる */
        }

        /* ボタンをクリックしたときの効果 */
        #recordButton:active {
            background-color: #004080;
        }

        /* 録画停止時の無効状態 */
        #recordButton:disabled {
            background-color: #cccccc;
            cursor: not-allowed;
        }

        /* 使い方説明のスタイル */
        #instruction {
            margin-top: 20px;
            background-color: #ffffff;
            border: 1px solid #ddd;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            width: 300px;
            text-align: center;
        }

        #instruction h3 {
            margin: 0 0 10px;
            font-size: 20px;
            color: #333;
        }

        #instruction p {
            font-size: 16px;
            color: #555;
        }

        /* ボタンと使い方説明を縦並びに配置 */
        .btn-container {
            display: flex;
            flex-direction: column;
            align-items: center;
        }
    </style>
</head>
<body>

<!-- 録画ボタンと使い方説明のコンテナ -->
<div class="btn-container">
    <!-- 録画開始/停止ボタン -->
    <button id="recordButton">録画開始</button>

    <!-- 使い方説明 -->
    <div id="instruction">
        <h3>使い方</h3>
        <p>録画を開始するには「録画開始」ボタンをクリックしてください。</p>
        <p>もう一度録画停止をクリックすると録画が終了し、ファイルとして保存されます。</p>
    </div>
</div>

<script>
    // 録画開始/停止ボタンの要素を取得
    let recordButton = document.getElementById('recordButton');
    let mediaRecorder, recordedChunks = []; // 録画データを格納するための変数
    let isRecording = false; // 録画中かどうかを判定するフラグ

    // 録画開始/停止ボタンがクリックされたときの処理
    recordButton.addEventListener('click', async () => {
        if (!isRecording) {
            // 録画が開始されていない場合

            try {
                // 画面のキャプチャストリームを取得
                const stream = await navigator.mediaDevices.getDisplayMedia({
                    video: {
                        cursor: 'always' // カーソルも録画対象にする
                    }
                });

                // 録画データを格納するための配列を初期化
                recordedChunks = [];
                // MediaRecorderを使って録画を開始
                mediaRecorder = new MediaRecorder(stream, { mimeType: 'video/webm; codecs=vp9' });
                
                // 録画データが生成される度に呼ばれる
                mediaRecorder.ondataavailable = (event) => {
                    if (event.data.size > 0) {
                        // 録画データがある場合、配列に追加
                        recordedChunks.push(event.data);
                    }
                };

                // 録画が停止したときの処理
                mediaRecorder.onstop = saveRecording;

                // 録画を開始
                mediaRecorder.start();
                isRecording = true; // 録画中フラグを立てる
                recordButton.textContent = '録画終了'; // ボタンのテキストを変更

            } catch (err) {
                // 画面録画の権限を拒否された場合やエラー時の処理
                console.error('Error: ' + err);
            }
        } else {
            // 録画が開始されている場合、録画を停止
            mediaRecorder.stop();
            isRecording = false; // 録画終了フラグを下げる
            recordButton.textContent = '録画開始'; // ボタンのテキストを戻す
        }
    });

    // 録画停止後にファイルとして保存する処理
    function saveRecording() {
        // 録画データをBlobオブジェクトに変換
        const blob = new Blob(recordedChunks, { type: 'video/mp4' });
        // Blob URLを作成
        const url = URL.createObjectURL(blob);
        // ダウンロード用のリンクを作成
        const a = document.createElement('a');
        a.style.display = 'none'; // 表示しない
        a.href = url; // 作成したURLを設定
        a.download = 'recording.mp4'; // ダウンロードファイル名を指定
        document.body.appendChild(a); // ダウンロードリンクをDOMに追加
        a.click(); // ダウンロードリンクをクリック(自動的にダウンロードが開始)
        URL.revokeObjectURL(url); // 使用後にBlob URLを解放
    }
</script>

</body>
</html>

「本記事は、技術的な視点から情報を提供することを目的としております。内容については可能な限り正確性を期しておりますが、記事内の見解は執筆者の意見や理解に基づいており、すべての方にとって普遍的な結論を示すものではありません。技術の分野は常に進化し、新たな知見が追加されることもあります。ご意見がある場合には、建設的な対話を歓迎いたしますが、批判的な意見を展開する際も、お互いの尊重を大切にしたコミュニケーションを心がけていただけると幸いです。」

4
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?