news 2026/9/16 16:03:07

Shaka Player v2.2 升级至 v2.4 完整指南:API 迁移、配置变更与重试机制详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Shaka Player v2.2 升级至 v2.4 完整指南:API 迁移、配置变更与重试机制详解

Shaka Player v2.2 升级至 v2.4 完整指南:API 迁移、配置变更与重试机制详解

【免费下载链接】shaka-playerJavaScript player library / DASH & HLS client / MSE-EME player项目地址: https://gitcode.com/GitHub_Trending/sh/shaka-player

本文是面向应用开发者的 Shaka Player 从 v2.2 升级到 v2.4 的详细迁移指南,覆盖 HLS 起始时间配置移除、文本解析/显示插件 API 重写、离线存储删除接口变更、流失败重试回调机制、语言与角色选择、网络层可中止操作(IAbortableOperation)以及 Manifest 解析器相关 API 调整等全部破坏性变更。读完本文,你将掌握每个变更点的迁移步骤、可直接复制的升级代码示例,以及对应的源码实现依据,能够在升级后快速定位并修复自己的应用代码。

v2.4 带来了哪些新能力

相比 v2.2,Shaka Player v2.4 引入了一系列播放能力与工程体验上的改进,主要包括:

  • HLS 直播流支持,并支持起始时间不为 t=0 的 HLS VOD 流;
  • MPEG-2 TS 内容可被转封装(transmux)为 MP4,从而在所有浏览器上播放;
  • 字幕仅在显示时才被拉取流式传输(Captions are not streamed until shown),减少带宽浪费;
  • 使用NetworkInformation API获取初始带宽估计;
  • 官方 Demo 应用升级为渐进式 Web 应用(PWA),可离线使用;
  • 支持 TS 内容中的CEA 字幕
  • 支持TTML 与 VTT 区域(region)的精确表示;
  • 构造Player不再强制要求传入 video 元素,新增attach()detach()方法管理播放器与 video 元素的绑定关系;
  • Fetch 优先于 XHR发起网络请求;
  • 网络请求支持中止(abort)
  • 直播流可从偏离直播边缘的负偏移位置开始播放。

这些能力中的多项(如 TS 转封装、请求中止、字幕按需拉取)都依赖下文要讲的 API 变更,因此在升级时务必同步迁移应用代码。

HLS 起始时间配置移除:自动从分片提取

v2.2 中,对于起始时间不为 t=0 的 HLS VOD 内容,应用需要显式配置manifest.hls.defaultTimeOffset告知播放器正确的内容起始时间。该配置在 v2.4 中已被移除

v2.4 会自动从分片(segments)本身提取 HLS 内容的起始时间,无需任何配置。如果你的应用仍在调用player.configure({manifest: {hls: {defaultTimeOffset: ...}}}),请在升级时删除这段配置。

这一能力背后的实现可参考 lib/media/presentation_timeline.js 中的setUserSeekStart(time)方法(由 lib/player.js 在解析到播放范围起始时间后调用),它设置用户可定义的 seek 范围起点,并仅用于 VOD 内容,与getSegmentAvailabilityStart()共同决定可用分片的起始边界。自动提取的起始时间最终会落到这一时间轴上。

文本解析插件(TextParser)API 变更

文本解析插件(TextParser)的 API 在 v2.4 中发生变化,所有应用自定义的文本解析插件都必须更新,v2.4 不提供向后兼容

核心变化是:插件接收的数据类型由ArrayBuffer改为Uint8Array,这一改动让库内部得以优化并避免缓冲区拷贝

// v2.2 /** * @param {!ArrayBuffer} data * @param {shakaExtern.TextParser.TimeContext} timeContext * @return {!Array.<!shaka.text.Cue>} */ MyTextParser.prototype.parseMedia = function(data, timeContext) {}; // v2.4 /** * @param {!Uint8Array} data * @param {shakaExtern.TextParser.TimeContext} timeContext * @return {!Array.<!shaka.text.Cue>} */ MyTextParser.prototype.parseMedia = function(data, timeContext) {};

同时,timeContext中的segmentStart字段变为可空(nullable)。当该信息不可用时——例如在 HLS 场景下——你的插件会收到null作为segmentStart,需要做好空值处理:

MyTextParser.prototype.parseMedia = function(data, timeContext) { if (timeContext.segmentStart == null) { // HLS 场景下起始时间可能不可用,走兜底逻辑 } // ... };

产生区域(region)信息的文本解析插件还需要改用新的shaka.text.CueRegion类。新结构能够更精确地同时表示 TTML 与 VTT 的区域信息。接口细节可参考 externs/shaka/text.js 中的shakaExtern.TextParser.prototype.parseInitshakaExtern.TextParser.prototype.parseMedia定义。

文本显示插件(TextDisplayer)API 变更

文本显示插件(TextDisplayer)的 API 同样发生了变更。所有应用自定义的 TextDisplayer 插件都必须更新,v2.4 不提供向后兼容

插件需要适配shakaExtern.CueRegion结构的调整——新的结构支持更精确地表示 TTML 与 VTT 区域。例如,区域单位目前支持shaka.text.CueRegion.units.LINES(行单位)与PERCENTAGE(百分比单位)两种取值,CEA-708 窗口定位就是通过把锚点相关值映射到CueRegion实现的(参见 lib/cea/cea708_window.js)。如果你的自定义显示插件直接操作旧的区域字段,需要按新结构重新实现。

区域结构的完整定义可查看shakaExtern.CueRegion(位于 externs/shaka/text.js)。

离线存储(Offline Storage)API 变更

v2.2 中,shaka.offline.Storageremove()方法接收一个StoredContent实例作为参数;v2.4 改为接收StoredContent中的offlineUri字段

// v2.2: storage.list().then(function(storedContentList) { var someContent = storedContentList[someIndex]; storage.remove(someContent); }); // v2.4: storage.list().then(function(storedContentList) { var someContent = storedContentList[someIndex]; storage.remove(someContent.offlineUri); });

旧参数在 v2.3 中被标记废弃,并在 v2.4 中正式移除。所有使用离线存储的应用都必须更新到新 API

从源码看,新实现位于 lib/offline/storage.js:remove(contentUri)接收字符串形式的contentUri,随后通过shaka.offline.OfflineUri.parse(contentUri)解析并校验;若 URI 不合法或不是 manifest 类型,会抛出MALFORMED_OFFLINE_URI错误。删除内容时还会尝试释放对应的 DRM license。

流失败后的重试机制:从配置项到回调函数

v2.1.3 引入了streaming.infiniteRetriesForLiveStreams配置来控制直播流的重试行为;v2.2 又增加了更灵活的回调机制来为所有类型的流指定重试策略。到 v2.4,该配置已被移除(v2.2 标记废弃、v2.3 正式删除),取而代之的是streaming.failureCallback

// v2.1 —— 直播流无限重试(默认行为) player.configure({ streaming: { infiniteRetriesForLiveStreams: true // the default } }); // v2.4 —— 等价写法:回调里判断直播并重试 player.configure({ streaming: { failureCallback: function(error) { // Always retry live streams: if (player.isLive()) player.retryStreaming(); } } }); // v2.1 —— 直播流不重试 player.configure({ streaming: { infiniteRetriesForLiveStreams: false // do not retry live } }); // v2.4 —— 等价写法:回调里什么都不做,停止尝试继续流式传输 player.configure({ streaming: { failureCallback: function(error) { // Do nothing, and we will stop trying to stream the content. } } });

灵活决策:结合 isLive()、错误码与其他条件

player.retryStreaming()可在失败后随时调用以重试。你可以基于player.isLive()error.code或任何其他条件决定是否重试。由于retryStreaming()可在任意时刻调用,你甚至可以把决策推迟到收到用户反馈、浏览器恢复联网等时机。

几个典型回调示例:

function neverRetryCallback(error) {} function alwaysRetryCallback(error) { player.retryStreaming(); } function retryOnSpecificHttpErrorsCallback(error) { if (error.code == shaka.util.Error.Code.BAD_HTTP_STATUS) { var statusCode = error.data[1]; var retryCodes = [ 502, 503, 504, 520 ]; if (retryCodes.indexOf(statusCode) >= 0) { player.retryStreaming(); } } }

如果你选择响应error事件而不是 failure 回调,可以通过event.preventDefault()完全绕过回调:

player.addEventListener('error', function(event) { // Custom logic for error events if (player.isLive() && event.error.code == shaka.util.Error.Code.BAD_HTTP_STATUS) { player.retryStreaming(); } // Do not invoke the failure callback for this event event.preventDefault(); });

从源码看,retryStreaming()定义于 lib/player.js,其默认重试延迟为 0.1 秒,并且只有在当前加载模式为MEDIA_SOURCE时才真正生效(否则返回false)。failure 回调的实际触发点位于 lib/media/streaming_engine.js,即流媒体引擎在遭遇失败并经过退避等待(backoff)后,会调用配置中的failureCallback,并把错误对象传给它;回调自身抛出的异常会被捕获并记入日志,避免干扰播放器状态机。

语言与角色选择

在 v2.1 引入的语言选择方法基础上,v2.4 新增了面向角色(role)的方法:getAudioLanguagesAndRoles()getTextLanguagesAndRoles()。它们以对象数组的形式返回语言/角色的组合,并且语言选择方法支持用可选的第二个参数指定角色:

// v2.4: var languagesAndRoles = player.getAudioLanguagesAndRoles(); for (var i = 0; i < languagesAndRoles.length; ++i) { var combo = languagesAndRoles[i]; if (someSelector(combo)) { player.selectAudioLanguage(combo.language, combo.role); break; } }

这种模式非常适合“根据某种偏好规则自动挑选一条带指定角色(如注释音轨、导演评论)的音轨或字幕轨”的场景,例如在 UI 中列出所有可选项供用户勾选后调用selectAudioLanguage(language, role)/selectTextLanguage(language, role)完成切换。

NetworkingEngine API 变更:request() 返回可中止操作

v2.2 中,shaka.net.NetworkingEnginerequest()方法直接返回一个 Promise;v2.4 改为返回shakaExtern.IAbortableOperation实例,该实例内含一个 Promise

所有通过NetworkingEngine发起应用级请求的代码 SHOULD 更新到新 API(旧 API 的支持将在 v2.5 中移除):

// v2.2: player.getNetworkingEngine().request(type, request).then((response) => { // ... }); // v2.4: let operation = player.getNetworkingEngine().request(type, request); // Use operation.promise to get the response. operation.promise.then((response) => { // ... }); // The operation can also be aborted on some condition. onSomeOtherCondition(() => { operation.abort(); });

为平滑过渡,v2.4 的发布版本对request()的返回值额外提供了.then.catch方法,实现向后兼容。

IAbortableOperation的推荐实现是工具类shaka.util.AbortableOperation(见 lib/util/abortable_operation.js)。它的构造函数接收底层操作的 Promise 与onAbort回调,并对外暴露promiseabortedabort()。其中abort()并非“取消”(不撤销已完成的工作),只是停止后续工作;被中止的操作应以OPERATION_ABORTED错误码拒绝其 Promise。该工具类还提供了failed()aborted()completed()notAbortable()等静态工厂方法与combine()chain()等组合原语,方便网络插件与上层逻辑复用。

网络 scheme 插件 API 变更

v2.4 同样调整了网络 scheme 插件(负责特定 URI scheme 的请求)的 API。所有应用级网络 scheme 插件 SHOULD 更新到新 API(旧 API 支持将在 v2.5 中移除)。

变化有两处:

  1. 插件现在返回shakaExtern.IAbortableOperation实例(推荐用shaka.util.AbortableOperation封装);
  2. 新增一个参数用于标识请求类型(requestType)
// v2.2 function fooPlugin(uri, request) { return new Promise((resolve, reject) => { // ... }); } shaka.net.NetworkingEngine.registerScheme('foo', fooPlugin); // v2.4 function fooPlugin(uri, request, requestType) { let rejectCallback = null; const promise = new Promise((resolve, reject) => { rejectCallback = reject; // Use this if you have a need for it. Ignore it otherwise. if (requestType == shaka.net.NetworkingEngine.RequestType.MANIFEST) { // ... } else { // ... } // ... }); const abort = () => { // Abort the operation. // ... // Reject the Promise. rejectCallback(new shaka.util.Error( shaka.util.Error.Severity.RECOVERABLE, shaka.util.Error.Category.NETWORK, shaka.util.Error.Code.OPERATION_ABORTED)); }; return new shaka.util.AbortableOperation(promise, abort); } shaka.net.NetworkingEngine.registerScheme('foo', fooPlugin);

requestType的枚举值定义于 lib/net/networking_engine.js 的shaka.net.NetworkingEngine.RequestType,覆盖MANIFESTSEGMENTLICENSETIMING等常用类型,另有更细粒度的AdvancedRequestTyperegisterScheme(scheme, plugin, priority, progressSupport)也支持通过priority调整同一 scheme 下多个插件的优先级,并在 v2.4 中增加了progressSupport参数以支持请求进度上报。

Manifest 解析器插件 API 变更

shaka.media.PresentationTimeline的 API 发生了变化,使用以下方法的 ManifestParser 插件必须更新

  • setAvailabilityStart()更名为setUserSeekStart()
  • notifySegments()的参数由“周期起始时间 + 引用数组”改为“引用数组 + 布尔值isFirstPeriod”。

其中setUserSeekStart(time)的当前实现位于 lib/media/presentation_timeline.js,仅用于 VOD 内容,其值会参与getSegmentAvailabilityStart()的计算(取userSeekStart_与动态可用窗口起点中较大者),直接影响播放器允许 seek 的最小时间点。

升级自检清单

对照下表逐项检查你的应用,可避免在 v2.4 升级后踩坑:

变更点旧用法(v2.2)新用法(v2.4)是否破坏性
HLS 起始时间manifest.hls.defaultTimeOffset配置自动从分片提取,删除配置
TextParser 插件parseMedia(data /* ArrayBuffer */, timeContext)parseMedia(data /* Uint8Array */, timeContext)segmentStart可为null,区域改用CueRegion是,无兼容
TextDisplayer 插件CueRegion结构CueRegion结构(支持 TTML/VTT 区域)是,无兼容
离线存储删除storage.remove(storedContent)storage.remove(storedContent.offlineUri)
直播流重试streaming.infiniteRetriesForLiveStreamsstreaming.failureCallback+player.retryStreaming()是(配置已移除)
语言/角色选择selectAudioLanguage(language)新增getAudioLanguagesAndRoles()/getTextLanguagesAndRoles(),选择方法支持 role 参数否(新增)
NetworkingEngine.request返回 Promise返回IAbortableOperation(含.promise,可abort()建议更新(v2.5 移除旧支持)
网络 scheme 插件(uri, request)返回 Promise(uri, request, requestType)返回AbortableOperation建议更新(v2.5 移除旧支持)
Manifest 解析器setAvailabilityStart()、旧notifySegments()setUserSeekStart()notifySegments(refs, isFirstPeriod)是(解析器插件)

其中标注“无兼容”的两处(TextParser 与 TextDisplayer 插件 API)破坏性最强,应用必须同步改写插件代码;标注“建议更新”的两处(NetworkingEngine 与网络 scheme 插件)在 v2.4 中仍带过渡兼容层,但需在 v2.5 之前完成迁移。按此清单逐项处理后,你的应用即可平稳运行在 Shaka Player v2.4 之上。

【免费下载链接】shaka-playerJavaScript player library / DASH & HLS client / MSE-EME player项目地址: https://gitcode.com/GitHub_Trending/sh/shaka-player

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 16:01:55

Sunshine 游戏串流快速上手指南:一个晚上打通第一帧

Sunshine 游戏串流快速上手指南&#xff1a;一个晚上打通第一帧 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 装好串通&#xff0c;最终能干什么 Sunshine 是一套自托管的游戏串…

作者头像 李华
网站建设 2026/9/16 16:01:26

基于深度学习与图像分类的舌苔识别完整工程实践

简介&#xff1a;一份整合了Python源码、PyQt5图形界面、训练模型与毕业论文的深度学习舌苔识别检测系统&#xff0c;适合计算机视觉或医学图像处理方向的毕业设计及项目实践者。压缩包共110个文件&#xff0c;主要包含Python脚本、pyc编译文件、PyQt5界面ui与ttc字体、模型pth…

作者头像 李华
网站建设 2026/9/16 16:00:22

基于NLP的微博情感分析系统:从数据清洗到Flask部署

简介&#xff1a;基于NLP的微博用户情感分析系统是一套完整的毕业设计Python工程&#xff0c;面向计算机、通信、人工智能、自动化等专业学生及从业者&#xff0c;可用于课程设计、大作业或毕业设计参考&#xff0c;也适合用来掌握中文微博文本情感倾向自动判别的完整流程。压缩…

作者头像 李华
网站建设 2026/9/16 16:00:11

MATLAB实现粒子群优化求解电力系统最优潮流(OPF)

简介&#xff1a;本资源是一份面向MATLAB初学者与电力系统优化方向学习者的粒子群优化算法&#xff08;PSO&#xff09;基础实现包&#xff0c;聚焦于最优潮流&#xff08;OPF&#xff09;等典型工程优化问题的求解。压缩包共3个文件&#xff0c;含2个核心MATLAB源码文件&#…

作者头像 李华
网站建设 2026/9/16 15:59:09

三维RRT算法在无人机路径规划中的MATLAB实现

1. 项目概述&#xff1a;三维RRT算法在无人机路径规划中的应用在无人机自主导航领域&#xff0c;路径规划算法直接决定了飞行器能否安全高效地完成任务。这个MATLAB实现的三维RRT&#xff08;快速随机树&#xff09;算法项目&#xff0c;为开发者提供了一个可自定义起终点、障碍…

作者头像 李华
网站建设 2026/9/16 15:57:31

2026大理电气检测机构排名 TOP5 CMA 资质机构提供防爆设备检测+防爆安全检测 联系方式推荐

大理电气防爆检测机构鳞次栉比、鱼龙混杂&#xff0c;化工园区、油库加油站、矿山厂区、制药企业、危化品仓储场所开展防爆电气安全排查、生产验收时&#xff0c;大量无资质机构出具报告无法通过应急管理部门核查。小编实地走访筛选本地正规第三方电气防爆检测实验室&#xff0…

作者头像 李华