ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Shaka Player 升级指南:从 v2.1 到 v2.4 的完整迁移手册

2026/9/18 0:09:33 拓冰建站 浏览量
Shaka Player 升级指南:从 v2.1 到 v2.4 的完整迁移手册 Shaka Player 升级指南从 v2.1 到 v2.4 的完整迁移手册【免费下载链接】shaka-playerJavaScript player library / DASH HLS client / MSE-EME player项目地址: https://gitcode.com/GitHub_Trending/sh/shaka-player本篇指南以 Shaka Player 官方升级文档 docs/upgrades/upgrade-v2.1-to-v2.4.md 为主体系统梳理从 v2.1 升级到 v2.4 过程中涉及的全部 API 变更、配置项迁移与新能力引入并结合当前仓库的 lib 目录源码与 externs 声明文件进行源码级佐证。读完本文你将掌握文本渲染、ABR 码率自适应、流失败重试、离线存储、网络请求与插件体系等模块在 v2.4 中的新写法并能在不踩坑的前提下完成应用代码迁移。一、v2.4 带来了什么升级文档开篇即列举了 v2.1 到 v2.4 之间的核心改进按主题可归纳为以下几类文本与字幕允许应用自绘文本轨道支持 CEA 字幕TS 内容支持 TTML 与 VTT 的 region 布局字幕在显示前不再被提前流式下载。码率自适应ABR默认 ABR 管理器更加可配置vaiant 轨道上新增声道数与带宽信息使用 NetworkInformation API 获取初始带宽估算。流式传输与网络Fetch 优先于 XHR可用时网络请求变为可中止abortable直播可在距离直播边缘负偏移处开始播放。格式与清单支持 HLS 直播流支持开始时间不为 t0 的 HLS VOD 流MPEG-2 TS 内容可被转封装transmux为 MP4 以在所有浏览器播放DASH 支持 Xlink。Player 生命周期构造Player时不再强制要求传入 video 元素新增 attach() 与detach()方法管理 video 元素挂载。其他离线内容支持无持久化许可即无 license persistence方案EME 证书配置运行时类型检查更严格示例应用demo升级为可离线使用的 PWA。需要说明的是本文聚焦 v2.4 相对 v2.1 的 API 变化。当前仓库的 lib/player.js 等实现已远超出 v2.4 的能力范围但文档中描述的接口契约如TrackChoice、AbrManager等在 externs 中仍可找到一一对应的声明可以作为迁移目标的权威依据。二、新的shaka.text命名空间在 v2.1 中TextEngine隶属于shaka.media命名空间从 v2.2 起它被迁移到新的shaka.text命名空间。文本解析插件现在应通过shaka.text.TextEngine.registerParser注册。当前仓库中 lib/text/text_engine.js 即为该迁移后的实现static registerParser(mimeType, plugin) { shaka.text.TextEngine.parserMap_.set(mimeType, plugin); }同时它还提供了unregisterParser(mimeType)与findParser(mimeType)两个配套静态方法见 lib/text/text_engine.js。TextEngine的构造函数签名为new TextEngine(displayer, manifestType)其中displayer是shaka.extern.TextDisplayer实例——这正是下一节自定义字幕显示的挂载点。三、自定义字幕显示Customizing subtitle displayv2.1 允许应用接入自定义文本解析器但字幕的最终显示完全由浏览器负责。v2.2 起 Shaka 将显示环节也开放给应用默认情况下渲染工作由shaka.text.SimpleTextDisplayer类完成应用可通过player.configure()指定自定义的文本显示工厂player.configure({ textDisplayFactory: customTextDisplayerClass });自定义显示类需要实现shaka.extern.TextDisplayer接口声明见 externs/shaka/player.js核心职责包括append(cues)、remove(startTime, endTime)、destroy()等。从 lib/player.js 的默认配置可以看到Player 在构造默认配置时便通过工厂函数懒加载 displayer——工厂接收 player 实例作为参数应用也可以基于此实现运行时根据场景选择 displayer的逻辑。在 lib/text/text_engine.js 中可以看到渲染链路解析出的 cues 会先经过可选的modifyCueCallback修改可用于样式或时间戳校正再按 append window 过滤后交给displayer_.append(cuesToAppend)。四、文本解析器 API 变更破坏性v2.4 对文本解析插件 API 做了不向后兼容的修改所有应用自带的解析插件必须更新返回值插件现在返回shaka.text.Cue对象数组而非 v2.1 的VTTCue/TextTrackCue。入参parseMedia的 data 参数由ArrayBuffer改为Uint8Array。时间上下文timeContext.segmentStart变为可空nullable。当该信息不可用例如 HLS 场景时插件会收到null。对照代码迁移示例// v2.1 MyTextParser.prototype.parseMedia function(data, timeContext) { var cues []; var parserState new MyInternalParser(data); // ArrayBuffer while (parserState.more()) { cues.push(new VTTCue(...)); } return cues; }; // v2.4 MyTextParser.prototype.parseMedia function(data, timeContext) { var cues []; var parserState new MyInternalParser(data); // Uint8Array while (parserState.more()) { cues.push(new shaka.text.Cue(...)); } return cues; };在仓库中externs/shaka/text.js 定义了shaka.extern.TextParser接口parseMedia(data, timeContext, uri, images)返回!Array!shaka.text.Cueexterns/shaka/text.js 定义了TimeContext包含periodStart、segmentStart、segmentEnd、vttOffset、isMpegTs五个字段。TextEngine.appendBuffer内部正是构造该time对象并传给解析器见 lib/text/text_engine.js。shaka.text.Cue类包含与VTTCue相同的 cue 信息并额外携带文本样式样式相关字段与textDisplayFactory配合可实现完全自定义的渲染效果。注意v2.4不提供该变更的向后兼容层升级时必须同步更新全部文本解析插件。五、ABR 管理器的设置与配置5.1 配置入口变更v2.1 中自定义 ABR 管理器通过abr.manager配置项注入v2.4 改为顶层abrFactory// v2.1 player.configure({ abr.manager: customAbrManager }); // v2.4 player.configure({ abrFactory: customAbrManager });5.2 AbrManager 接口变更v2.1 中默认带宽估算与码率限制通过setDefaultEstimate()和setRestrictions()两个独立方法设置v2.4 统一收敛为configure()方法接受一个shaka.extern.AbrConfiguration结构声明位于 externs/shaka/player.js// v2.1: abrManager.setDefaultEstimate(defaultBandwidthEstimate); abrManager.setRestrictions(restrictions); // v2.4: abrManager.configure(abrConfigurations);新方法更通用除默认带宽与限制外还允许配置带宽升/降级目标bandwidthUpgradeTarget/bandwidthDowngradeTarget。在默认实现 lib/abr/simple_abr_manager.js 中configure(config)将配置缓存到this.config_并同步给内部的EwmaBandwidthEstimator。5.3 流选择 APIchooseStreams()→chooseVariant()v2.1 中 Player 通过chooseStreams()请求流选择AbrManager 通过switch()回调把主动建议的变更回传参数是 audio/video 流的映射表v2.4 中chooseStreams()被chooseVariant()取代switch()回调直接接收一个 variant// v2.1: var map abrManager.chooseStreams([audio, video]); console.log(map[video], map[audio]); MyAbrManager.prototype.makeDecision_ function() { var video this.computeBestVideo_(this.bandwidth_); var audio this.computeBestAudio_(this.bandwidth_); var map { audio: audio, video: video }; this.switch_(map); }; // v2.4: var variant abrManager.chooseVariant(); console.log(variant, variant.video, variant.audio); MyAbrManager.prototype.makeDecision_ function() { var variant this.computeBestVariant_(this.bandwidth_); this.switch_(variant); };当前仓库的shaka.extern.AbrManager接口externs/shaka/abr_manager.js完整反映了这一演进setVariants(variants, isLowLatency)、chooseVariant(preferFastSwitching)、enable()/disable()、configure(config)等。switchCallback的语义也已明确——第一个参数是要切换到的 variant第二、三个可选参数控制是否清空缓冲clearBufferSwitch以及清缓冲时保留的安全余量秒数safeMarginSwitch后者可用于实现无卡顿的快速切换。v2.1 的旧接口在 v2.2 被标记废弃、v2.3 被移除所有自定义 AbrManager 插件必须更新到 v2.4 接口。六、切换历史Switch History的变化v2.1 中shakaExtern.Stats.switchHistory使用shakaExtern.StreamChoice结构type字段为 audio / video / text。v2.2 起改名为shakaExtern.TrackChoice语义从流细化到轨道// v2.1: shakaExtern.StreamChoice; // id: 流 idtype: audio/video/text // v2.4: shakaExtern.TrackChoice; // id: 轨道 idtype: variant/text新增 bandwidth仓库 externs/shaka/player.js 中的shaka.extern.TrackChoice定义与升级文档完全一致{ timestamp, id, type: variant|text, fromAdaptation, bandwidth: ?number }其中fromAdaptation表示该切换是 ABR 自适应true还是应用主动调用选择接口falsebandwidth对文本轨为null。lib/util/switch_history.js 提供了SwitchHistory实现updateCurrentVariant(newVariant, fromAdaptation)与updateCurrentText(newText, fromAdaptation)会去重记录冗余切换getCopy()返回历史副本文本轨的 bandwidth 固定记录为nulllib/util/switch_history.js与 typedef 约定一致。开发者通过player.getStats().switchHistory即可拿到该数组用于分析码率切换行为。七、流失败后的自定义重试逻辑这是 v2.2 引入、v2.4 完整成型的核心能力。v2.0 时代网络错误且重试耗尽后流式传输会无限继续重试请求唯一的终止方式是unload()或destroy()v2.1.3 增加了streaming.infiniteRetriesForLiveStreams配置来单独控制直播重试v2.2 则替换为更灵活的streaming.failureCallback回调机制覆盖所有流类型// v2.1 player.configure({ streaming: { infiniteRetriesForLiveStreams: true // 默认值 } }); // v2.4 player.configure({ streaming: { failureCallback: function(error) { // 直播流总是重试 if (player.isLive()) player.retryStreaming(); } } });关闭重试的对应写法// v2.1 player.configure({ streaming: { infiniteRetriesForLiveStreams: false // 不重试直播 } }); // v2.4 player.configure({ streaming: { failureCallback: function(error) { // 什么都不做即停止尝试流式传输该内容 } } });streaming.infiniteRetriesForLiveStreams在 v2.2 被废弃、v2.3 被移除。新机制下决策依据可以是player.isLive()、error.code或任何其他信息由于player.retryStreaming()可在任意时刻调用你完全可以推迟决策——比如等用户反馈、等浏览器重新联网。文档给出的几种典型回调策略function neverRetryCallback(error) {} function alwaysRetryCallback(error) { player.retryStreaming(); } function retryLiveOnFailureCallback(error) { if (player.isLive()) { 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事件处理也可以用event.preventDefault()完全跳过 failureCallbackplayer.addEventListener(error, function(event) { // 自定义 error 事件逻辑 if (player.isLive() event.error.code shaka.util.Error.Code.BAD_HTTP_STATUS) { player.retryStreaming(); } // 该事件不再触发 failureCallback event.preventDefault(); });当前仓库中 lib/player.js 的retryStreaming(retryDelaySeconds 0.1)仅对 MEDIA_SOURCE 加载模式生效loadMode_ shaka.Player.LoadMode.MEDIA_SOURCE时调用streamingEngine_.retry()且可传入以秒为单位的重试延迟。Player 的默认 failureCallbacklib/player.js演示了 v2.4 之后的演进方向对动态流isDynamic()遇到BAD_HTTP_STATUS/HTTP_ERROR默认延迟 1 秒重试低延迟模式下 0.1 秒、TIMEOUT错误延迟 0.1 秒重试而 VOD 流的流式失败视为致命错误不自动重试。另外 Player 内部还会监听浏览器的online事件恢复联网后自动调用retryStreaming()恢复播放lib/player.js。八、HLS 起始时间配置的移除对于开始时间不为 t0 的 HLS VOD 内容v2.1 提供了manifest.hls.defaultTimeOffset配置来告知正确的起始时间。该配置在 v2.4 中已被移除——HLS 内容的起始时间现在可以从分段segment本身自动提取无需任何配置。这意味着升级到 v2.4 后应用代码中针对manifest.hls.defaultTimeOffset的配置可以直接删除由解析器自动完成起始时间的推导。九、离线存储 API 变更v2.1 中shaka.offline.Storage.remove()接收一个StoredContent实例v2.4 改为接收StoredContent上的offlineUri字段字符串// v2.1: 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 移除所有使用离线存储的应用必须更新。仓库 lib/offline/storage.js 中remove(contentUri)的签名验证了这一点它接收字符串 URI内部通过shaka.offline.OfflineUri.parse解析并以isManifest()校验非法 URI 会抛出MALFORMED_OFFLINE_URI错误。十、语言与角色Language and Role选择在 v2.1 语言选择方法的基础上v2.4 新增了针对角色的方法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; } }这一能力与当前仓库的轨道模型一脉相承shaka.extern.Track结构中的language、roles字段externs/shaka/player.js正是语言/角色组合的数据来源而 Player 的轨道查询/选择接口getAudioTracks()、selectAudioTrack()、getTextTracks()、selectTextTrack()等见 lib/player.js继续承载按用户偏好切换轨道的职责。十一、NetworkingEngine API 变更v2.1 中shaka.net.NetworkingEngine.request()直接返回 Promisev2.4 返回shakaExtern.IAbortableOperation实例其中包含一个 Promise// v2.1: player.getNetworkingEngine().request(type, request).then((response) { // ... }); // v2.4: let operation player.getNetworkingEngine().request(type, request); // 用 operation.promise 获取响应 operation.promise.then((response) { // ... }); // 也可在满足某个条件时中止操作 onSomeOtherCondition(() { operation.abort(); });v2.4 通过给request()的返回值附加.then与.catch方法提供了向后兼容层但该兼容层计划在 v2.5 移除应用级请求建议尽快迁移到新 API。从源码看lib/net/networking_engine.js 的request(type, request, context)返回shaka.net.NetworkingEngine.PendingRequest继承AbortableOperation内部先执行带重试的请求再通过.chain()串联 response filter 等阶段当请求尚未开始就调用 abort 时会以OPERATION_ABORTED拒绝。十二、网络 scheme 插件 API 变更v2.4 同时变更了网络 scheme 插件自定义 URI 协议的请求插件的 API插件返回shakaExtern.IAbortableOperation实例官方建议使用shaka.util.AbortableOperation工具类。新增第三个参数requestType用于标识请求类型MANIFEST、SEGMENT、LICENSE 等应用可据此实现差异化处理。// v2.1 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; // 需要时使用 requestType否则忽略 if (requestType shaka.net.NetworkingEngine.RequestType.MANIFEST) { // ... } else { // ... } }); const abort () { // 中止底层操作 // ... // 拒绝 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);shaka.util.AbortableOperation的完整实现位于 lib/util/abortable_operation.js除了构造函数(promise, onAbort)外还提供若干静态工厂failed(error)、aborted()、completed(value)、notAbortable(promise)、all(operations)以及用于串联异步阶段的实例方法chain(onSuccess, onError)和finally(onFinal)。aborted属性可查询操作是否已被中止lib/util/abortable_operation.js。注意旧的 Promise 风格 scheme 插件同样只在 v2.4 中保留兼容层计划在 v2.5 移除。十三、Manifest 解析器插件 API 变更shaka.media.PresentationTimeline的接口发生两处重命名/签名变化使用这些方法的ManifestParser插件必须同步更新setAvailabilityStart()更名为setUserSeekStart()。notifySegments()现在接收一个引用数组reference array和一个名为isFirstPeriod的布尔值取代原来的 period 起始时间 引用数组两个参数。这两处变更直接影响 DASH、HLS 等清单解析插件的实现应用若自行编写 ManifestParser 插件升级时务必检查对PresentationTimeline的调用是否命中上述方法。十四、升级清单速查以下为从 v2.1 迁移到 v2.4 时需要逐一核对的应用代码变更点变更领域v2.1 写法v2.4 写法迁移强度文本命名空间shaka.media.TextEngineshaka.text.TextEngine.registerParser(...)必须文本解析插件返回VTTCue入参ArrayBuffer返回shaka.text.Cue入参Uint8Array必须无兼容层字幕显示仅浏览器渲染textDisplayFactory自定义渲染可选ABR 配置abr.managersetDefaultEstimate/setRestrictionsabrFactoryconfigure(AbrConfiguration)必须ABR 接口chooseStreams()/switch(streamMap)chooseVariant()/switch(variant)必须切换历史shakaExtern.StreamChoiceshakaExtern.TrackChoice新增 bandwidth读取方需适配失败重试streaming.infiniteRetriesForLiveStreamsstreaming.failureCallbackplayer.retryStreaming()必须HLS 起始时间manifest.hls.defaultTimeOffset自动从分段提取配置移除删除配置离线删除storage.remove(storedContent)storage.remove(storedContent.offlineUri)必须语言/角色仅语言选择方法新增getAudioLanguagesAndRoles()等新增能力网络请求request()返回 Promise返回IAbortableOperation含.promise/.abort()强烈建议网络插件返回 Promise(uri, request)返回AbortableOperation(uri, request, requestType)强烈建议清单插件setAvailabilityStart()、旧notifySegments()setUserSeekStart()、新notifySegments(refs, isFirstPeriod)必须若使用十五、延伸阅读升级文档系列upgrade-v2.2-to-v2.4.md、upgrade-v2.3-to-v2.4.md以及 v2.4 之后的 upgrade-v2.4-to-v2.5.md 与 upgrade-v2.5-to-v3.0.md。ABR 默认实现lib/abr/simple_abr_manager.js 与带宽估算器 lib/abr/ewma_bandwidth_estimator.js。文本引擎与 Cuelib/text/text_engine.js、lib/text/cue.js。网络层lib/net/networking_engine.js 与可中止操作工具 lib/util/abortable_operation.js。离线存储lib/offline/storage.js。基础使用与配置docs/tutorials/basic-usage.md、docs/tutorials/config.md。【免费下载链接】shaka-playerJavaScript player library / DASH HLS client / MSE-EME player项目地址: https://gitcode.com/GitHub_Trending/sh/shaka-player创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考