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>