HLS プラグイン

HLS プラグインは、W3C の Media Source Extensions(MSE)に依存して、ネイティブでサポートされていないプラットフォーム上でも HTTP Live Streaming(HLS)動画を再生できるようにする Brightcove Player プラグインです。HLS プラグインは、プレーヤーに自動的に含まれます。

HLS プラグインの基本

以下のポイントは、HLS プラグインを理解し、使用するうえで役立ちます。

  • 本ドキュメントの冒頭で述べたとおり、このプラグインは W3C の Media Source Extensions(MSE)に依存しています。MSE は、HTML5 動画をサポートする Web ブラウザ内のメディア コーデックに対して、JavaScript からバイト ストリームを送信できるようにする W3C の仕様です。これにより、ストリーミング メディア向けのクライアントサイドでの事前取得やバッファリング処理を、すべて JavaScript で実装することが可能になります。
  • このプラグインを使用すると、プレーヤーで HLS(m3u8)形式の動画コンテンツを利用できます。例えば、Media セクションに以下の設定を行うことで、プレーヤーを作成できます。
          "media":{
              "sources": [{
                  "src": "http://example.com/video.m3u8",
                  "type": "application/x-mpegURL"
              }]
          }
  • HLS を使用する際には、クロス オリジン リソース共有(CORS)が問題となる場合があります。CORS の利用に関する詳細は、CORS ガイド を参照してください。
  • HLS は、IE11 より前の Internet Explorer ではサポートされていません。

概要

HTTP Live Streaming(HLS)は、iOS や Android でネイティブにサポートされていることから、モバイル デバイスにおける動画ストリーミングの事実上の標準となっています。また、プラットフォームに依存しない観点から見ても、この形式を推奨できる理由がいくつかあります。

  • (クライアント主導による)アダプティブ ビットレート選択をサポート
  • 標準の HTTP ポートを使用して配信可能
  • シンプルなテキスト ベースのマニフェスト形式
  • 独自仕様のストリーミング サーバーが不要

しかしながら、Safari を除く主要なデスクトップ ブラウザでは HLS がサポートされていません。そのため、Web 開発者は同一動画の複数の代替形式を管理したり、最適なデスクトップ視聴体験を提供するために HTML ベースの動画利用を断念せざるを得ない状況に置かれてきました。

本プラグインは、Media Source Extensions または Flash をサポートするブラウザ向けに HLS のポリフィルを提供することで、この課題に対応します。単一の HLS ストリームを配信し、通常の HTML5 動画 API を用いて実装することで、主要な Web デバイス全体にわたり、高速かつ高品質な動画体験を実現できます。

現時点では、以下の機能は サポートされていません

  • 代替オーディオおよびビデオトラック
  • H.264 + AAC オーディオ 以外 のセグメント コーデック
  • Internet Explorer 11 未満

オプション

HLS プラグインを設定するために使用できるオプションがいくつかあります。

withCredentials

タイプ: boolean

使用方法:

  • ソースオプションとして
  • 初期化オプションとして

withCredentials プロパティを true に設定すると、マニフェストおよびセグメントに対するすべての XHR リクエストにおいても withCredentialstrue に設定されます。これにより、マニフェストやセグメントが配置されているサーバーからの Cookie の保存および送信が有効になります。この設定は CORS に影響を及ぼします。具体的には、この設定が有効な場合、Access-Control-Allow-Origin ヘッダーに * を指定することはできず、レスポンス ヘッダーには Access-Control-Allow-Credentials ヘッダーを追加し、true に設定する必要があります。詳細については、HTML5Rocks の記事を参照してください。

Player Management API を使用し、HTTP の PATCH メソッドで、以下のようにプラグインを設定できます。

        curl \
            --header "Content-Type: application/json" \
            --user YOUR_EMAIL \
            --request PATCH \
            --data '{ "hls": { "withCredentials": true } }' \
        https://players.api.brightcove.com/v2/accounts/YOUR_ACCOUNT_ID/players/YOUR_PLAYER_ID/configuration

上記のようにプレーヤー単位で設定するだけでなく、ソースごとに withCredentials オプションを設定することもできます。例えば、ソース設定時に次のように withCredentials を含めることができます。

        curl \
          --header "Content-Type: application/json" \
          --user $EMAIL \
          --request POST \
          --data '{
              "name": "MySamplePlayer",
              "configuration": {
                "media": {
                  "sources": [{
                    "src":"http://solutions.brightcove.com/bcls/assets/videos/Tiger.mp4",
                    "type":"video/mp4",
                    "withCredentials": true
                  }]
                }
              }
            }' \
        https://players.api.brightcove.com/v2/accounts/$ACCOUNT_ID/players

実行時設定

実行時に withCredentials を設定することもできます。以下に 2 つの実装方法を示します。

  • player.hls.xhr.beforeRequest を使用する方法
  • player.src() を使用する方法

次のコードでは、player.hls.xhr.beforeRequest を使用して、xhr リクエスト作成時に使用されるオプションを含むオブジェクトを引数として受け取る関数を割り当てています。この例では、withCredentials のみを設定しています。

        if (videojs.Hls) {
          videojs.Hls.xhr.beforeRequest = function (options) {
            options.withCredentials = true;
          }
        }

動画ソースを設定する際に、player.src() メソッドを使用して withCredentials オプションを指定することもできます。例を以下に示します。

        player.src({
          src: 'https://adomain.com/bipbop_16x9_variant.m3u8',
          type: 'application/x-mpegURL',
          withCredentials: true
        });

enableLowInitialPlaylist

タイプ: boolean

デフォルト: undefined(ただし、Android デバイスでブラウザを表示している場合は true に設定されます)。この挙動は、以下のようにプレーヤーを false でパッチすることで、Android デバイス向けにも変更できます。

使用方法:

  • 初期化オプションとして

enableLowInitialPlaylist を true に設定すると、初期再生時に最も低いビットレートのプレイリストが選択されます。これにより、再生開始までの時間を短縮できます。

Player Management API を使用し、HTTP の PATCH メソッドで、以下のようにプラグインを設定できます。

        curl \
            --header "Content-Type: application/json" \
            --user YOUR_EMAIL \
            --request PATCH \
            --data '{ "hls": { "enableLowInitialPlaylist": true } }' \
        https://players.api.brightcove.com/v2/accounts/YOUR_ACCOUNT_ID/players/YOUR_PLAYER_ID/configuration

実行時プロパティ

一般的に、HLS オブジェクトには次の方法でアクセスできます。

  • Brightcove Player v5: player.hls
  • Brightcove Player v6: player.tech().hls

player.hls.playlists.master

タイプ: object

パースされたマスタープレイリストを表すオブジェクトです。メディア プレイリストが直接読み込まれた場合は、1 つのエントリのみを含むマスタープレイリストが作成されます。

player.hls.playlists.media

タイプ: function

現在アクティブなメディア プレイリストを取得または変更するために使用できる関数です。アクティブなメディア プレイリストは、追加の動画データをダウンロードする際に参照されます。この関数を引数なしで呼び出すと、アクティブなメディア プレイリストのパース済みオブジェクトが返されます。マスタープレイリスト内のプレイリスト オブジェクト、またはマスタープレイリストで指定されている URI 文字列を指定してこの関数を呼び出すと、指定されたメディア プレイリストの非同期読み込みが開始されます。取得完了後、そのプレイリストがアクティブなメディア プレイリストとなります。

player.hls.bandwidth

タイプ: number

直近のセグメント ダウンロードにおける、1 秒あたりにダウンロードされたビット数です。この値は、デフォルト実装の selectPlaylist によって、再生に適したビットレートを選択するために使用されます。最初の動画セグメントがダウンロードされる前は、帯域幅を正確に見積もることは困難です。HLS tech では、デフォルトでプレイリストのダウンロード時間に基づくヒューリスティックを使用して帯域幅を推定します。より正確な帯域幅情報源がある場合は、HLS tech の読み込み完了後すぐにこの値を上書きし、初期帯域幅の推定値を提供することができます。

player.hls.stats.bytesReceived

タイプ: number

HLS tech によってダウンロードされたコンテンツ バイト数の合計です。

player.hls.selectPlaylist

タイプ: function

次にダウンロードするセグメントに使用するメディア プレイリスト オブジェクトを返す関数です。この関数は、新しいセグメントがダウンロードされる直前にプラグインから呼び出されます。独自のアダプティブストリーミング ロジックを提供するために、この関数を上書きすることができます。ただし、player.hls.playlists.master に存在する有効なメディア プレイリスト オブジェクトを必ず返す必要があります。

イベント

loadedmetadata

ストリームに対して最初のメディア プレイリストがダウンロードされた後に発火されます。

loadedplaylist

新しいマスターまたはメディア プレイリストがダウンロードされた直後に発火されます。デフォルトでは、プラグインは必要になった時点でのみプレイリストをダウンロードします。

mediachange

新しいプレイリストがアクティブなメディア プレイリストになったときに発火されます。なお、実際の描画品質の変更はこのイベントと同時には行われません。新しいセグメントがリクエストされ、既存のバッファが消費された後に反映されます。

エラー発生時のソース再読み込み

HLS プラグインを使用している場合、プレーヤーでエラーが発生した際に、現在の再生位置からソースを再読み込みするためのメソッドを呼び出すことができます。この機能を有効にするには、reloadSourceOnError() メソッドを呼び出します。以下の短い動画では、このメソッドの動作を確認できます。動画内で示されているコードは、すべて本セクションの後半で説明しています。

reloadSourceOnError() メソッドの構文は次のとおりです。

        reloadSourceOnError(optionsObject)

オプションの optionsObject には、次のプロパティがあります。

プロパティ データ型 デフォルト値 説明
errorInterval Number 30 再読み込みがトリガーされるまでに、2 回のエラー間で経過する必要がある最小時間(秒)。たとえば、この値を 10 に設定した場合、エラーが発生するたびに、直近の再読み込みから 10 秒未満しか経過していないかを確認します。指定した時間間隔より短い場合は、ソースは再読み込みされません(エラーのあるコンテンツが継続的に再読み込みされるのを防ぐためです)。指定した時間間隔より長く経過している場合は、エラーが発生した時点から動画が再読み込みされます。
getSource() Function 現在のソースを取得 読み込みまたは再読み込みするソース オブジェクトを取得するために呼び出される関数です。デフォルトでは、プレーヤーの現在のソースを取得します。

以下は、上記のデモ動画で使用されているコードの詳細です。

  • 1〜9 行目: プレーヤーの id を追加した、標準的なインページ埋め込みコード。
  • 11 行目: 手動でエラーを発生させるためのボタン。
  • 22〜24 行目: ボタンクリック時に呼び出され、エラーを送出する関数。
  • 19 行目: 設定オプションを格納するオブジェクトを作成。
  • 20 行目: 設定オブジェクト内で errorInterval プロパティを作成し、値を割り当て。
  • 21 行目: 設定オブジェクトを引数として reloadSourceOnError() メソッドを呼び出し。
        <video-js id="myPlayerID"
          data-video-id="4607746980001"
          data-account="1507807800001"
          data-player="HJLp3Hvmg"
          data-embed="default"
          data-application-id=""
          controls=""
        ></video-js>
        
        <p><button onclick="createError()">createError</button></p>
        
        <script src="https://players.brightcove.net/1507807800001/HJLp3Hvmg_default/index.min.js"></script>
        
        <script type="text/javascript">
          var createError;
          videojs.getPlayer('myPlayerID').ready(function() {
            var myPlayer = this,
              reloadOptions = {};
            reloadOptions.errorInterval = 10;
            myPlayer.reloadSourceOnError(reloadOptions);
            createError = function(){
              myPlayer.error({code:'2'});
            }
          });
        </script>

マニフェスト内 WebVTT

HLS プラグインは、マニフェスト内 WebVTT をサポートしています。この機能はプラグインの標準機能であるため、有効化のために特別な設定を行う必要はありません。動画は、マニフェスト内 WebVTT を考慮して取り込まれている必要があります。例えば、Brightcove の Dynamic Ingest API を使用すると、動画を取り込み、キャプションをマニフェスト内として設定できます。詳細については、概要: Dynamic Delivery 向け Dynamic Ingest API のドキュメントを参照してください。

以下のプレーヤーでは、マニフェスト内 WebVTT キャプションを含む動画が再生されています。次の例に示すように、キャプション アイコンからキャプションを選択できます。

display captions icon

動画の再生を開始すると、表示したいキャプションを選択できるようになります。

参考までに、通常は自分で作成することはありませんが、上記のプレーヤーで使用されている動画のマニフェストを以下に示します。

        #EXTM3U
        #EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Woofer",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,LANGUAGE="en",URI="subtitles/en/index.m3u8"
        #EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Woofer (Forced)",DEFAULT=NO,AUTOSELECT=NO,FORCED=YES,LANGUAGE="en",URI="subtitles/en_forced/index.m3u8"
        #EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Spanish",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,LANGUAGE="es",URI="subtitles/es/index.m3u8"
        #EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Spanish (Forced)",DEFAULT=NO,AUTOSELECT=NO,FORCED=YES,LANGUAGE="es",URI="subtitles/es_forced/index.m3u8"
        #EXT-X-STREAM-INF:BANDWIDTH=865000,CODECS="mp4a.40.2, avc1.42001e",RESOLUTION=640x360,SUBTITLES="subs"
        865/prog_index.m3u8
        #EXT-X-STREAM-INF:BANDWIDTH=12140000,CODECS="mp4a.40.2, avc1.42001e",RESOLUTION=1280x720,SUBTITLES="subs"
        12140/prog_index.m3u8

この中で、キャプション ファイルへの参照を確認できます。

アダプティブ切り替え

HLS レンディションの選択

再生中、プレーヤーはアルゴリズムに基づいて、より高い、または低いレンディションへ切り替えます。このアルゴリズムへの入力要素は次のとおりです。

  • 利用可能な帯域幅
  • プレーヤーの表示サイズ

レンディション選択の詳細については、どのレンディションが再生されるかの決定 のドキュメントを参照してください。

MP4 レンディションの選択

何らかの理由で Brightcove Player が HLS ソースを再生できない場合、MP4 再生にフォールバックします。この場合、モバイル デバイスで MP4 を再生する際には、プレーヤーは約 0.5 MB/秒 に最も近いビットレートの MP4 を選択します。デスクトップまたはノート PC の場合は、約 3 MB/秒 に最も近い MP4 レンディションが選択されます。

インバンド メタデータ

Brightcove Player は、HLS 動画ストリームに埋め込まれた特定の種類の ID3 タグ情報を認識します。ID3 規格は、もともと MP3 オーディオトラックに関するメタデータを提供するために使用されていました(この略称は IDentify MP3 に由来します)。メタデータが埋め込まれたストリームが検出されると、インバンドメタデータ用のテキストトラックが自動的に作成され、ストリーム内で検出されたタイミングに応じてキューが追加されます。一般的なユースケースとしては、ID3 データを使用してライブストリーム内で広告を表示するタイミングを制御することが挙げられます。

ID3 規格では多数のフレームタイプが定義されていますが、キューポイントにマッピングされ、値がキューテキストとして設定されるのは、以下の UTF-8 エンコードされた 2 種類のフレームのみです。

  • WXXX - ユーザー定義 URL リンクフレーム
  • TXXX - ユーザー定義テキスト情報フレーム

その他すべてのフレーム タイプについてもキューは作成され、そのデータは生成されたキューに付加されます。

        cue.frame.data

テキストトラック全般についての詳細は、Getting Started With the Track Element を参照してください。Brightcove Player とキューポイントに関する情報については、広告キューポイントを使用した広告表示 を参照してください。

デバッグ

このセクションの情報は、HLS に関する問題の解決に役立てるため、Brightcove Support に提供できる情報を収集する目的で用意されています。ただし、ここで報告されるデータの一部は、お客様にとっても有用な場合があります。

HLS のデバッグに役立つ 2 つのメソッドと 1 つのプロパティについて説明します。

メソッド: videojs.log.level()

videojs.log.level() メソッドは、現在のログレベルを取得または設定します。デバッグを有効にするには、次を使用します。

videojs.log.level('debug');

メソッド: videojs.log.history()

history() メソッドは、履歴に記録されたすべてのログを含む配列を返します。

videojs.log API を通じて記録されたメッセージはすべて、history 配列に追加されます。配列に格納される情報は、この API を使用するプラグインの種類や、プレーヤーの状態によって異なります。そのため、履歴には HLS と直接関係のない情報が含まれる場合があります。以下は、コンソール上で history 配列を表示した例です。

console display of history array

history 配列を Support に送付する必要がある場合は、コンソールで次を入力するのが最適です。

JSON.stringify(videojs.log.history())

次に示すような情報が得られます。

console display of history stringified

生成された JSON をコピーし、そのまま Support に送付してください。

プロパティ: player.tech().hls.stats

このオブジェクトには、HLS およびプレーヤーに関連する統計情報の要約が含まれます。利用可能なプロパティを次の表に示します。

プロパティ名 タイプ 説明
bandwidth number 直近のセグメント ダウンロードのレート(ビット/秒)
buffered array SourceBuffer に格納されているコンテンツの時間範囲の一覧
currentSource object ソース オブジェクト(構造は {src: 'url', type: 'mimetype'}
currentTech string 使用中の tech の名称
currentTime number プレーヤーの現在位置
duration number 動画の長さ(秒)
master object マスタープレイリスト オブジェクト
mediaBytesTransferred number ダウンロードされたコンテンツ バイト数の合計
mediaRequests number メディア セグメント リクエスト数の合計
mediaRequestsAborted number 中断されたメディア セグメント リクエスト数の合計
mediaRequestsErrored number エラーとなったメディア セグメント リクエスト数の合計
mediaRequestsTimeout number タイムアウトしたメディア セグメント リクエスト数の合計
mediaSecondsLoaded number ダウンロードされたコンテンツ秒数の合計
mediaTransferDuration number メディア セグメントのダウンロードに費やした合計時間(ミリ秒)
playerDimensions object プレーヤーの幅と高さを含みます
seekable array プレーヤーがシーク可能な時間範囲の一覧
timestamp number hls.stats にアクセスした時点のタイムスタンプ
videoPlaybackQuality object W3C の Media Playback Quality API で定義されているメディア再生品質メトリクス

stats オブジェクトをコンソールに表示した例を以下に示します。

console display of stats object

コード例

これらのデバッグ機能を試してみたい場合は、以下のコードを出発点として利用できます。

<video-js id="myPlayerID" data-video-id="5622718636001"
  data-account="1507807800001"
  data-player="SkxERgnQM"
  data-embed="default"
  data-application-id=""
  controls=""
  width="640"
  height="360"></video-js>
<script src="https://players.brightcove.net/1507807800001/SkxERgnQM_default/index.min.js"></script>

<script type="text/javascript">
  videojs.getPlayer('myPlayerID').ready(function() {
    var myPlayer = this;

    videojs.log.level('debug');

    myPlayer.on('ended', function(){
      console.log('videojs.log.history(): ', videojs.log.history());
      console.log('videojs.log.level(): ', videojs.log.level());
      console.log('videojs.hls.stats: ', player.tech().hls.stats);
    });
  });
</script>

608 キャプション

Brightcove の HLS プラグインは 608 キャプションをサポートしています。608 キャプションは、CEA-608 キャプション、EIA-608 キャプション、または Line 21 キャプションとも呼ばれ、米国およびカナダにおける NTSC アナログテレビ放送用のクローズド キャプションの標準です。608 キャプションはライブストリームに挿入することができ、HLS の ts(トランスポート ストリーム)ファイル内に組み込まれます。

ホスティングに関する問題

ネイティブの HLS 実装とは異なり、HLS プラグインはブラウザのセキュリティポリシーに準拠する必要があります。そのため、ストリームを構成するすべてのファイルは、動画プレーヤーをホストしているページと同一ドメイン、または適切な CORS ヘッダー が設定されたサーバーから配信される必要があります。一般的な Web サーバー向けには簡単な手順が公開されており、ほとんどの CDN でもアカウントに対して CORS を有効化することは容易です。

エラー

HLS 再生中のエラーは、APPEND_BUFFER_ERR タイプとして報告されます。メッセージには、ブラウザのネイティブ エラーから取得された内容が表示されます。例えば、The quota has been exceeded などです。

変更履歴

HLS は現在プレーヤーに統合されており、プラグイン機能に関する変更は Brightcove Player のリリースノートで報告されます。

過去のリリースノートについては、こちらの変更履歴を参照してください。