見出し画像

m3u8 ファイルをブラウザで再生するための JavaScript と HTML コード

・JavaScript コード

/**
 * HLSビデオストリーミングを管理するためのハンドラークラス
 * HLS.jsライブラリをラップし、ブラウザ互換性とフォールバック処理を提供します
 */
class HLSVideoHandler {
    /**
     * HLSVideoHandlerを初期化します
     * @param {Object} options - 設定オプション
     * @param {boolean} [options.debug=false] - デバッグモードを有効にするかどうか
     * @param {boolean} [options.enableWorker=true] - Web Workerを有効にするかどうか
     * @param {number} [options.maxRetries=3] - 再試行の最大回数
     * @param {number} [options.retryDelay=1000] - 再試行間の遅延(ミリ秒)
     */
    constructor(options = {}) {
        this.debug = options.debug || false;
        this.enableWorker = options.enableWorker || true;
        this.maxRetries = options.maxRetries || 3;
        this.retryDelay = options.retryDelay || 1000;
        this.initialized = false;
    }

    /**
     * HLS.jsライブラリを初期化します
     * @returns {Promise<void>} 初期化の完了を示すPromise
     * @throws {Error} HLS.jsの読み込みに失敗した場合
     */
    async initialize() {
        if (typeof Hls === 'undefined') {
            try {
                await this.loadHLSScript();
                this.initialized = true;
            } catch (error) {
                console.error('Failed to load HLS.js:', error);
                throw error;
            }
        } else {
            this.initialized = true;
        }
    }

    /**
     * HLS.jsスクリプトを動的に読み込みます
     * @returns {Promise<void>} スクリプト読み込みの完了を示すPromise
     */
    loadHLSScript() {
        return new Promise((resolve, reject) => {
            const script = document.createElement('script');
            script.src = 'https://cdnjs.cloudflare.com/ajax/libs/hls.js/1.4.10/hls.min.js';
            script.async = true;
            script.onload = () => resolve();
            script.onerror = () => reject(new Error('Failed to load HLS.js script'));
            document.head.appendChild(script);
        });
    }

    /**
     * HLSプレーヤーを設定し、指定されたビデオ要素に接続します
     * @param {HTMLVideoElement} videoElement - ビデオを再生するHTML要素
     * @param {string} playlistUrl - HLSプレイリストのURL
     * @returns {Promise<Hls|boolean>} HLSインスタンスまたはネイティブ再生の成否
     * @throws {Error} ビデオ要素が提供されていない場合
     */
    async setupPlayer(videoElement, playlistUrl) {
        if (!this.initialized) {
            await this.initialize();
        }

        if (!videoElement) {
            throw new Error('No video element provided');
        }

        if (!Hls.isSupported()) {
            return this.setupNativePlayer(videoElement, playlistUrl);
        }

        try {
            const hls = new Hls({
                debug: this.debug,
                enableWorker: this.enableWorker
            });

            hls.loadSource(playlistUrl);
            hls.attachMedia(videoElement);

            return hls;
        } catch (error) {
            console.error('Error setting up HLS:', error);
            return this.setupNativePlayer(videoElement, playlistUrl);
        }
    }

    /**
     * ネイティブHLS再生をサポートするブラウザ向けのフォールバックプレーヤーを設定します
     * @param {HTMLVideoElement} videoElement - ビデオを再生するHTML要素
     * @param {string} playlistUrl - HLSプレイリストのURL
     * @returns {boolean} ネイティブ再生のサポート状況
     */
    setupNativePlayer(videoElement, playlistUrl) {
        if (videoElement.canPlayType('application/vnd.apple.mpegurl')) {
            videoElement.src = playlistUrl;
            return true;
        }
        return false;
    }
}

// グローバルスコープで利用可能にする
window.HLSVideoHandler = HLSVideoHandler;

・HTML コード

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HLS Video Player Demo</title>
    <style>
        .video-container {
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        video {
            width: 100%;
        }
    </style>
</head>
<body>
    <div class="video-container">
        <h1>HLS Video Player デモ</h1>
        <video id="video" controls playsinline></video>
    </div>

    <script src="hls-video-handler.js"></script>
    <script>
    document.addEventListener('DOMContentLoaded', async () => {
        const videoElement = document.getElementById('video');
        const hlsHandler = new HLSVideoHandler({ debug: true });
        
        try {
            await hlsHandler.setupPlayer(videoElement, 'https://video.bsky.app/watch/did%3Aplc%3A47ssgpmbvhxr2ia2hy4rsan3/bafkreiepps3hzer26qun2ywbnepacftgy4vf32extbnaqzufgfrukllata/playlist.m3u8');
        } catch (error) {
            console.error('Failed to initialize video player:', error);
        }
    });
    </script>
</body>
</html>

いいなと思ったら応援しよう!