Blobメソッドによる動画再生

大容量の動画ファイルを一括で読み込むのを避けるため、プログレッシブローディング(Progressive Loading) の手法が利用できます。具体的には以下の方法があります:

動画をチャンク(分割データ)単位で動的にプレイヤーに読み込むことで、一括ダウンロードを防ぎます。大容量動画やストリーミング再生に最適な手法です。

サーバー側で動画を分割して返す(HTTPストリーミングのような方式)ことで、フロントエンドが部分ごとにリクエストし、再生できます。これにより、ユーザーは大容量ファイルの待ち時間なく視聴を開始できます。

実装コード:

<video id="videoPlayer" controls></video>

<script>
// 動画IDの例
const videoID = "1b7008c6-1951deb2b6d";

// 動画IDから実際のURLを取得するAPI(実際の実装に合わせて変更可能)
async function getVideoUrl(videoID) {
    const response = await fetch(`https://example.com/api/getVideoUrl?id=${videoID}`);
    const data = await response.json();
    return data.videoUrl;
}

// MediaSourceを使った動画のストリーミング再生
async function streamVideo(videoUrl) {
    const video = document.getElementById("videoPlayer");
    const mediaSource = new MediaSource();
    video.src = URL.createObjectURL(mediaSource);

    // MediaSourceの準備が完了した時
    mediaSource.addEventListener("sourceopen", () => {
        const sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.64001F, mp4a.40.2"');

        // 動画のセグメントをロードする関数
        function loadSegment(startByte, endByte) {
            fetch(videoUrl, {
                headers: {
                    Range: `bytes=${startByte}-${endByte}`  // Rangeリクエストで部分取得
                }
            })
            .then(response => response.blob())
            .then(blob => {
                sourceBuffer.appendBuffer(blob);
            });
        }

        // 初期セグメントのロード
        let segmentStart = 0;
        const segmentSize = 10 * 1024 * 1024;  // 10MB単位で分割ロード

        // 最初のセグメントを取得
        loadSegment(segmentStart, segmentStart + segmentSize);

        // バッファが不足したら次のセグメントをロード
        sourceBuffer.addEventListener('updateend', () => {
            segmentStart += segmentSize;
            loadSegment(segmentStart, segmentStart + segmentSize);
        });
    });
}

// 動画URLを取得して再生開始
async function playVideo(videoID) {
    const videoUrl = await getVideoUrl(videoID);  // URL取得
    streamVideo(videoUrl);  // ストリーミング再生開始
}

// 動画再生を実行
playVideo(videoID);
</script>