HLSのパフォーマンスの改善
Shaka Player、Hls.js、BitmovinなどのMedia Source Extensions(MSE)プレーヤーは、JavaScriptでCPU負荷の高いタスクを実行します。これには複数のHLSメディアマニフェストの解析が含まれ、UIの応答性やアプリの滑らかさに影響を及ぼす可能性があります。この影響は、大きいDVRウィンドウで、マニフェストサイズの大きいライブTVを再生している場合に特に顕著に現れます。このドキュメントでは、HLSプレイリストパーサーのネイティブ実装を利用してパフォーマンスを最適化する方法について説明します。
ネイティブ解析に移行するとパフォーマンスが大幅に向上しますが、すべてのアプリでネイティブHLSパーサーサポートへの切り替えが必要になるわけではありません。この最適化の効果が特に見込めるのは、大きいDVRウィンドウでライブTVの再生を処理するアプリです。このようなアプリでは、大きいマニフェストの更新と解析が頻繁に行われ、その結果JSスレッドのブロックが頻繁に発生し、キーイベントやUIの処理が遅延しやすいためです。また、アプリでこの最適化を使用して、ビデオの開始時のレイテンシを改善することもできます。
Vega向けReact Native API
以下で説明する関数を使用すると、HLSマニフェストの解析をネイティブレイヤーにオフロードできます。
手順1: ネイティブ解析を有効にする
ネイティブ解析を有効にするには、アプリでregisterNativePlayerUtils()を呼び出して、ネイティブ関数を登録する必要があります。デバイスがネイティブ関数をサポートしている場合、この呼び出しはtrueを返します。それ以外の場合はfalseを返します。この呼び出しによってアプリが登録され、ネイティブHLSパーサーの呼び出しが可能になります。
global.registerNativePlayerUtils();
手順2: HLSプレイリスト解析のネイティブサポートが利用可能かどうかを確認する
特定のプレーヤーとプレーヤーバージョンでHLSプレイリスト解析のネイティブサポートが利用可能かどうかを確認するには、isNativeHlsParserSupported()を呼び出して次のパラメーターを渡します。
playerName: プレーヤーの名前。サポートされている値は"shaka"と"hlsjs"です。playerVersion: プレーヤーのバージョン。"shaka"の場合は"4.6.18"または"4.3.6"です。"hlsjs"の場合は"1.5.11"です。
サポートされているプレーヤーのバージョンは次のとおりです。
- ネイティブHLSパーサーは現在、ShakaPlayerバージョン"4.6.18"と"4.3.6"でサポートされています。
- ネイティブHLSパーサーは現在、Hls.jsバージョン"1.5.11"でサポートされています。
#Shaka Player
if(global.isNativeHlsParserSupported("shaka", "4.3.6")) {
console.log('platform supports native parser for this version of shaka player');
}
#Hls.jsプレーヤー
if(global.isNativeHlsParserSupported("hlsjs", "1.5.11")) {
console.log('プラットフォームは、このバージョンのhls.jsプレーヤーでネイティブパーサーをサポートしています');
}
手順3: マニフェスト解析関数を呼び出す
HLSマニフェストの解析はglobal.parseHlsManifest関数に実装されています。アプリでは、まず自身を登録してから解析関数を呼び出す必要があります。
マニフェストを解析するには、parseHlsManifest()を呼び出して以下のパラメーターを渡します。
playerName: プレーヤー名を表す文字列。"shaka"を指定します。playerVersion: プレーヤーのバージョンを表す文字列。 "4.6.18"または"4.3.6"を指定します。absoluteUri: マニフェストの絶対URIを表す文字列。manifest: ダウンロードされたマニフェストを格納するArrayBuffer。shaka: ShakaPlayerの場合のみ、次のセクションに示すようにShakaオブジェクトを渡します。
global.parseHlsManifest(
playerName, playerVersion, absoluteuri, manifest, shaka);
マニフェストを解析するには、parseHlsManifest()を呼び出して以下のパラメーターを渡します。
playerName: プレーヤー名を表す文字列。"hlsjs"を指定します。playerVersion: プレーヤーのバージョンを表す文字列。 "1.5.11"を指定します。absoluteUri: マニフェストの絶対URIを表す文字列。manifest: ダウンロードされたマニフェストを格納するArrayBuffer。id: プレイリストレベルID。これは数値型です。type: インポートされたhlsplayerライブラリオブジェクトからのプレイリストレベルタイプ。HlsPlayerLib: Hls.mjsからインポートされたhlsplayerライブラリ。
global.parseHlsManifest(
playerName, playerVersion, absoluteuri, manifest, id, type, HlsPlayerLib);
次のセクションでは、これらの使用方法について詳しく説明します。
統合の変更
このセクションでは、前の手順で紹介した関数の使用方法について詳しく説明します。
ネイティブHLSパーサーは、Shaka Playerのバージョン4.6.18と4.3.6を対象にサポートされています。Shaka Playerに必要なすべてのパッチを適用し、それをアプリ内で使用する方法については、Shaka Playerを使用したアダプティブコンテンツ(HLS/DASH)の再生を参照してください。
注: プレーヤーをビルドする前に、Shaka PlayerのリリースtarballにShaka-Player-optimizations.patchファイルが含まれていて、そのパッチが適用されていることを確認してください。これにより、フックでHLS解析関数を登録できるようになります。このパッチは以下のバージョンから含まれています。
- ShakaPlayer v4.6.18: shaka-rel-v4.6.18-r2.9.tar.gz
- ShakaPlayer v4.3.6: shaka-rel-v4.3.6-r2.2.tar.gz
この機能を使用するには、アプリのsrc/shakaplayer/ShakaPlayer.tsファイルに次の変更を加えます。
-
src/shakaplayer/ShakaPlayer.tsで、Shaka Playerのバージョンを定義します。
const playerName: string = "shaka"; const playerVersion: string = "4.6.18"; -
ネイティブ解析を有効または無効にするフラグを定義することもできます。たとえば、次のフラグは手順4でネイティブ解析を有効にするために使用されます。
static readonly enableNativeParsing = true; -
parseHlsManifest()の呼び出しを追加します。import shaka from "./dist/shaka-player.compiled"; async nativeParsePlaylist( manifest: ArrayBuffer, absoluteuri:string) : Array<shaka.hls.Playlist> { console.log('shaka: nativeParsePlaylist+'); const playlist = await global.parseHlsManifest( playerName, playerVersion, absoluteuri, manifest, shaka); console.log('shaka: nativeParsePlaylist-'); return playlist; } -
Shaka Playerを読み込む前に、
parseHlsManifest()関数の実装を登録します。setNativeFunctions()関数を使用すると、アプリからネイティブのparseHlsManifest関数に実装を渡すことができます。これは引数として関数を受け取り、その関数がHLS解析中にShaka Playerから呼び出されます。override async load(content: any, autoplay: boolean): void { if (ShakaPlayer.enableNativeParsing) { // プラットフォームがネイティブプレーヤーユーティリティをサポートしているかどうかと、 // Shaka PlayerにHLSパーサー用のネイティブ関数を登録できるかどうかを確認します。 if (global.registerNativePlayerUtils && shaka.hls.HlsParser.setNativeFunctions) { console.log("shakaplayer:registerNativePlayerUtilsが見つかりました"); // ネイティブプレイヤーユーティリティを登録します。 if (!global.isNativeHlsParserSupported) { const ret = global.registerNativePlayerUtils(); console.log("shaka:ネイティブ関数が登録されました:" + ret); } // 次に、この特定のプレーヤーとプレーヤーバージョンで // ネイティブHLSパーサーがサポートされているかどうかを確認します。 if (global.isNativeHlsParserSupported && global.parseHlsManifest) { const nativeHlsParserSupported = global.isNativeHlsParserSupported(playerName, playerVersion); // このプレーヤーとプレーヤーバージョンでネイティブHLSパーサーがサポートされている場合、 // ラッパー関数をShakaに登録します。 if (nativeHlsParserSupported) { console.log('shaka:ネイティブ関数を設定します'); shaka.hls.HlsParser.setNativeFunctions(this.nativeParsePlaylist); } else { console.log('shaka:nativeHlsParserはこのプレーヤーバージョンではサポートされていません'); } } else { console.log('shaka:登録後、ネイティブ関数が設定されていません。スキップします'); } } else { console.log(`shakaplayer:ネイティブへのオフロードは使用できません registerNativePlayerUtils: ${!!global.registerNativePlayerUtils}, setNativeFunctions: ${!!shaka.hls.HlsParser.setNativeFunctions}`); } } else { console.log(`shaka:ネイティブのプレイリスト解析が無効になっています`); } }
これらの統合の変更は、外部リリースtarballに含まれているShakaPlayer.tsにも実装されており、参考として使用できます。
ネイティブHLSパーサーは、Hls.jsプレーヤーのバージョン1.5.11を対象にサポートされています。Hls.jsプレーヤーに必要なすべてのパッチを適用し、それをアプリ内で使用する方法については、Hls.jsプレーヤーを使用したアダプティブコンテンツの再生を参照してください。
注: プレーヤーをビルドする前に、hls.jsプレイヤーのリリースtarballにHLSJS-Nativize-HLS-manifest-parser-function.patchが含まれていて、そのパッチが適用されていることを確認してください。これにより、フックでHLS解析関数を登録できるようになります。このパッチは以下のバージョンのtarballから含まれています。
- Hls.js: hls-rel-v1.5.11-r1.4.tar.gz
アプリでsetNativeFunctionsを使用すると、Hls.jsプレーヤーからネイティブのparseHlsManifestを呼び出すための実装を渡すことができます。これは引数として関数を受け取り、その関数がHLS解析中にHls.jsプレーヤーから呼び出されます。
この機能を使用するには、アプリのsrc/hlsjsplayer/HlsJsPlayer.tsファイルに次の変更を加えます。
-
src/hlsjsplayer/HlsJsPlayer.tsで、hls.jsプレーヤーのバージョンを定義します。
const playerName: string = "hlsjs"; const playerVersion: string = "1.5.11"; -
ネイティブ解析を有効または無効にするフラグを定義することもできます。たとえば、次のフラグは手順5でネイティブ解析を有効にするために使用されます。
static readonly enableNativeParsing = true; - 必要なインポートを更新します。ここでは、./dist/hls.jsの代わりに./dist/hls.mjsに依存しています。それに応じてライブラリオブジェクトを更新します。更新が必要な行は「-」で示されています。それらを「+」で示す行に置き換えます。
##### import update ##### - import Hls from './dist/hls.js'; + import * as HlsPlayerLib from './dist/hls.mjs' ###### ライブラリオブジェクトの更新 ##### - this.hls = new Hls({ + this.hls = new HlsPlayerLib.Hls({ -
parseHlsManifest()の呼び出しを追加します。nativeParseLevelPlaylist( manifest: string, absoluteuri:string, id: number, type: HlsPlayerLib.PlaylistLevelType ) : HlsPlayerLib.LevelDetails { console.log('HlsJs: nativeParseLevelPlaylist +'); let levels: HlsPlayerLib.LevelDetails = global.parseHlsManifest( playerName, playerVersion, absoluteuri, manifest, id, type, HlsPlayerLib); console.log(`HlsJs: nativeParseLevelPlaylist -`); return levels; } -
プレーヤーを読み込む前に、この関数をHls.jsプレーヤーに登録します。
override async load(content: any, _autoplay: boolean): void { console.log("Hlsjs: 読み込み +"); if (HlsJsPlayer.enableNativeParsing) { if (global.registerNativePlayerUtils && HlsPlayerLib.M3U8Parser.setNativeFunctions) { console.log("Hlsjs:registerNativePlayerUtilsが見つかりました"); if (!global.isNativeHlsParserSupported) { const ret = global.registerNativePlayerUtils(); console.log("Hlsjs:ネイティブ関数が登録されました:" + ret); } if (global.isNativeHlsParserSupported && global.parseHlsManifest) { const nativeHlsParserSupported = global.isNativeHlsParserSupported(playerName, playerVersion); if (nativeHlsParserSupported) { console.log('Hlsjs:ネイティブ関数を設定します'); HlsPlayerLib.M3U8Parser.setNativeFunctions(this.nativeParseLevelPlaylist); } else { console.log('hlsjs:nativeHlsParserはこのプレーヤーバージョンではサポートされていません'); } } else { console.log('hlsjs:登録後、ネイティブ関数が設定されていません。スキップします'); } } else { console.log(`hlsjs:ネイティブへのオフロードは使用できません registerNativePlayerUtils: ${!!global.registerNativePlayerUtils}, setNativeFunctions: ${!!HlsPlayerLib.M3U8Parser.setNativeFunctions}`); } } else { console.log(`hlsjs:ネイティブのプレイリスト解析が無効になっています`); }
これらの統合の変更は、外部リリースtarballに含まれているHlsjsPlayer.tsにも実装されており、参考として使用できます。
サポートされるタグ
Shaka Player
- ShakaPlayer v4.6.18: ShakaPlayerバージョンv4.6.18では、すべてのタグがサポートされます。
- ShakaPlayer v4.3.6: ShakaPlayerバージョンv4.3.6では、すべてのタグがサポートされます。
Hls.jsプレーヤー
以下の一覧のタグがサポートされます。
メディアプレイリスト
- EXT_X_VERSION
- EXT_X_TARGETDURATION
- EXT_X_MEDIA_SEQUENCE
- EXT_X_DISCONTINUITY_SEQUENCE
- EXT_X_PLAYLIST_TYPE
- EXT_X_ENDLIST
メディアセグメント
- EXTINF
- EXT_X_BYTERANGE
- EXT_X_DISCONTINUITY
- EXT_X_PROGRAM_DATE_TIME
- EXT_X_KEY
- EXT_X_MAP
これらのタグの説明については、RFC 8216(英語のみ)を参照してください。
トラブルシューティング
-
変更の統合後、以下のログエントリが表示される場合、ネイティブ化は有効になっていません。有効にするには、ネイティブ化を有効にするフラグを設定します。フラグを設定する例については、ShakaPlayerの統合の手順2を参照してください。
hlsjs:ネイティブのプレイリスト解析が無効になっています -
変更の統合後、以下のログエントリが表示される場合、ネイティブ化は有効になっていません。最も考えられる原因として、Vega OSのリリースバージョンに互換性がなく、ネイティブ化に必要な変更が実装されていない可能性があります。使用しているバージョンが
OS 1.1(201010432050)以降であることを確認してください。hlsjs:ネイティブへのオフロードは使用できません
Last updated: 2025年9月30日

