改善HLS性能
Shaka播放器、Hls.js和Bitmovin等媒体源扩展 (MSE) 播放器使用JavaScript执行CPU密集型任务。这些任务包括解析多个HLS媒体清单,这可能会影响应用程序的用户界面响应能力和流畅度。这种影响在用清单大小较大的大型DVR窗口进行直播TV播放时尤其明显。本文档介绍如何利用HLS播放列表解析器的本机实现来优化性能。
改为本机解析可以显著提高性能,但并非所有应用都需要切换到本机HLS解析器支持。这些优化对于处理用大型DVR窗口播放直播TV的应用特别有益,因为频繁刷新和解析大型清单会导致频繁的JS线程阻塞、按键事件和用户界面处理延迟。应用还可以使用此优化来改善视频启动延迟。
适用于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”。
支持的播放器版本:
- ShakaPlayer版本“4.6.18”和“4.3.6”目前支持本机HLS解析器。
- Hls.js版本“1.5.11”目前支持本机HLS解析器。
# Shaka播放器
if(global.isNativeHlsParserSupported("shaka", "4.3.6")) {
console.log('平台支持此版本Shaka播放器的本机解析器');
}
#Hls.js播放器
if(global.isNativeHlsParserSupported("hlsjs", "1.5.11")) {
console.log('平台支持此版本hls.js播放器的本机解析器');
}
步骤3: 调用清单解析函数
global.parseHlsManifest函数实现了HLS清单解析。应用必须首先自行注册,然后调用解析函数。
为了解析清单,调用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);
以下部分提供了有关这些项的用法的其他详细信息。
集成变更
以下部分提供了有关前面步骤中展示的函数用法的其他详细信息。
Shaka播放器版本4.6.18和4.3.6支持本机HLS解析器。有关在应用中使用Shaka播放器并应用所有必需补丁的信息,请参阅使用Shaka播放器播放自适应内容 (HLS/DASH)。
注意: 在构建播放器之前,请确保Shaka播放器版本的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播放器版本。
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播放器之前,要先注册
parseHlsManifest()函数的实现。setNativeFunctions()函数允许应用将实现传递给本地parseHlsManifest函数。它接受一个参数形式的函数,在HLS解析期间从Shaka播放器调用该参数形式的函数。override async load(content: any, autoplay: boolean): void { if (ShakaPlayer.enableNativeParsing) { // 检查平台是否支持本机播放器实用工具,以及 // Shaka播放器挂钩是否为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:本机播放列表解析已禁用`); } }
这些集成更改也存在于ShakaPlayer.ts中,后者作为外部版本tarball的一部分提供,您可以将其用作参考。
1.5.11版本的Hls.js播放器支持本机HLS解析器。有关在应用中使用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.mjs来代替./dist/hls.js。相应地更新库对象。要更新的行由“-”标识。用标识了“+”的行替换它们。
##### 导入更新 ##### - 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 not supported for player version'); } } else { console.log('hlsjs:即使注册后也未设置本机函数,跳过它'); } } else { console.log(`hlsjs:未启用本机卸载! registerNativePlayerUtils: ${!!global.registerNativePlayerUtils}, setNativeFunctions: ${!!HlsPlayerLib.M3U8Parser.setNativeFunctions}`); } } else { console.log(`hlsjs:本机播放列表解析已禁用`); }
这些集成更改也存在于HlsjsPlayer.ts中,后者作为外部版本tarball的一部分提供,您可以将其用作参考。
支持的标记
Shaka播放器
- 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(仅提供英文版)。
故障排除
-
集成更改后,如果观察到以下日志条目,则未启用本机化。要启用它,请设置本机化启用标记。有关设置标记的示例,请参阅ShakePlayer集成的步骤2。
hlsjs:本机播放列表解析已禁用 -
集成更改后,如果观察到以下日志条目,则未启用本机化。最可能的原因是Vega OS版本不兼容,以及没有必需的本机化更改。确保您使用的版本是
OS 1.1 (201010432050)或更高版本。hlsjs:未启用本机卸载!
Last updated: 2025年9月30日

