@volcengine/veplayer 2.6.1 → 2.7.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11842,14 +11842,6 @@ class Sources extends OptionsIcon {
11842
11842
  const sourceManager = args.player.config.sources.sourceManager;
11843
11843
  args.config.list = sourceManager.sources;
11844
11844
  }
11845
- afterCreate() {
11846
- super.afterCreate();
11847
- if (this.config.sourceManager.sources.length < 2) {
11848
- this.hide();
11849
- } else {
11850
- this.renderItemList();
11851
- }
11852
- }
11853
11845
  registerIcons() {
11854
11846
  return {
11855
11847
  source: { icon: SourceIcon }
@@ -11858,6 +11850,10 @@ class Sources extends OptionsIcon {
11858
11850
  renderItemList() {
11859
11851
  const { sources, source } = this.config.sourceManager;
11860
11852
  const i18nManager = this.player.config.i18nManager;
11853
+ if (sources.length < 2) {
11854
+ this.hide();
11855
+ return;
11856
+ }
11861
11857
  const renderItems = sources.map((source2) => {
11862
11858
  return {
11863
11859
  ...source2,
@@ -12539,6 +12535,10 @@ class DefinitionPlugin extends OptionsIcon {
12539
12535
  var _a, _b;
12540
12536
  const sourceManager = this.player.config.sourceManager;
12541
12537
  const definitions = ((_a = sourceManager.source) == null ? void 0 : _a.definitions) ?? [];
12538
+ if (definitions.length < 2) {
12539
+ this.hide();
12540
+ return;
12541
+ }
12542
12542
  const renderItems = definitions.map((definition) => {
12543
12543
  const showItem = {
12544
12544
  url: definition.url,
@@ -13459,7 +13459,7 @@ function getStreamType(url) {
13459
13459
  }
13460
13460
  return "unknown";
13461
13461
  }
13462
- function isMseSupported$2(codec = Codec.H264) {
13462
+ function isMseSupported$3(codec = Codec.H264) {
13463
13463
  if (codec === Codec.H265) {
13464
13464
  return sniffer$1.isHevcSupported();
13465
13465
  }
@@ -13490,7 +13490,7 @@ const util = {
13490
13490
  ...util$1,
13491
13491
  ...DomUtils,
13492
13492
  getStreamType,
13493
- isMseSupported: isMseSupported$2,
13493
+ isMseSupported: isMseSupported$3,
13494
13494
  isSoftDecodeSupported: isSoftDecodeSupported$1,
13495
13495
  isMMSSupported: isMMSSupported$2,
13496
13496
  appendSearchParams: appendSearchParams$1,
@@ -14227,10 +14227,12 @@ class VePlayerBase {
14227
14227
  __publicField(this, "_events", {});
14228
14228
  __publicField(this, "_customMedia");
14229
14229
  __publicField(this, "_errorCallback");
14230
+ __publicField(this, "_beforeFallbackError");
14230
14231
  var _a, _b, _c, _d, _e, _f;
14231
14232
  this._sourceManager = options.sourceManager;
14232
14233
  this._preparePlugins = options.preparePlugins;
14233
14234
  this._previousPrepareResult = options.prepareResult;
14235
+ this._beforeFallbackError = options.beforeFallbackError;
14234
14236
  this._i18nManager = options.i18nManager ?? new VeI18n({
14235
14237
  i18n: options.i18n
14236
14238
  });
@@ -14255,6 +14257,9 @@ class VePlayerBase {
14255
14257
  ...DEFAULT_OPTIONS,
14256
14258
  ...xgOptions,
14257
14259
  definition: {
14260
+ // TODO: ts
14261
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
14262
+ // @ts-ignore
14258
14263
  list: ((_d = this._sourceManager.source) == null ? void 0 : _d.definitions) ?? [],
14259
14264
  defaultDefinition: (_e = this._sourceManager.definition) == null ? void 0 : _e.definition,
14260
14265
  ...options.definition ?? {}
@@ -14313,7 +14318,7 @@ class VePlayerBase {
14313
14318
  return this._player.played;
14314
14319
  }
14315
14320
  /** {zh}
14316
- * @brief 设置/获取视频当前的播放时间, 单位为 s。
14321
+ * @brief 设置/获取视频当前的播放时间,单位为 s。
14317
14322
  */
14318
14323
  /** {en}
14319
14324
  * @brief Sets or gets the current playback position of the video, in seconds.
@@ -14439,7 +14444,7 @@ class VePlayerBase {
14439
14444
  * @brief Retrieve the player SDK version number.
14440
14445
  */
14441
14446
  get playerVersion() {
14442
- return "2.6.1";
14447
+ return "2.7.0-rc.0";
14443
14448
  }
14444
14449
  /** {zh}
14445
14450
  * @brief 获取当前播放视频的清晰度唯一标识(definition)。
@@ -14925,13 +14930,18 @@ class VePlayerBase {
14925
14930
  * @hidden
14926
14931
  */
14927
14932
  async prepare(url) {
14928
- var _a, _b, _c, _d, _e, _f, _g;
14933
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
14929
14934
  const result = await ((_a = this._preparePlugins) == null ? void 0 : _a.call(this, url));
14930
- const newUrl = ((_b = result == null ? void 0 : result.options) == null ? void 0 : _b.url) ?? url;
14931
- const oldUrl = (_d = (_c = this._player) == null ? void 0 : _c.config) == null ? void 0 : _d.url;
14932
- const isSameProtocol = oldUrl && getStreamType(newUrl) === getStreamType(oldUrl);
14935
+ let isSameProtocol;
14936
+ if ((result == null ? void 0 : result.protocol) && ((_b = this._previousPrepareResult) == null ? void 0 : _b.protocol)) {
14937
+ isSameProtocol = result.protocol === ((_c = this._previousPrepareResult) == null ? void 0 : _c.protocol);
14938
+ } else {
14939
+ const newUrl = ((_d = result == null ? void 0 : result.options) == null ? void 0 : _d.url) ?? url;
14940
+ const oldUrl = (_f = (_e = this._player) == null ? void 0 : _e.config) == null ? void 0 : _f.url;
14941
+ isSameProtocol = oldUrl && getStreamType(newUrl) === getStreamType(oldUrl);
14942
+ }
14933
14943
  if (!isSameProtocol) {
14934
- (_f = (_e = this._previousPrepareResult) == null ? void 0 : _e.plugins) == null ? void 0 : _f.forEach((plugin) => {
14944
+ (_h = (_g = this._previousPrepareResult) == null ? void 0 : _g.plugins) == null ? void 0 : _h.forEach((plugin) => {
14935
14945
  this._player.unRegisterPlugin(plugin.pluginName);
14936
14946
  });
14937
14947
  }
@@ -14940,7 +14950,7 @@ class VePlayerBase {
14940
14950
  this._player.setConfig(result.options);
14941
14951
  }
14942
14952
  return {
14943
- plugins: isSameProtocol ? [] : (_g = result == null ? void 0 : result.plugins) == null ? void 0 : _g.map((plugin) => {
14953
+ plugins: isSameProtocol ? [] : (_i = result == null ? void 0 : result.plugins) == null ? void 0 : _i.map((plugin) => {
14944
14954
  return this._player.registerPlugin(plugin);
14945
14955
  }),
14946
14956
  options: result == null ? void 0 : result.options,
@@ -14953,11 +14963,18 @@ class VePlayerBase {
14953
14963
  const preUrl = this._sourceManager.url;
14954
14964
  const url = this._sourceManager.fallback();
14955
14965
  if (!url) {
14966
+ const transformedError = transform$1(err, this._i18nManager);
14967
+ try {
14968
+ const { canEmitError } = await this._beforeFallbackError(
14969
+ transformedError
14970
+ );
14971
+ if (!canEmitError) {
14972
+ return;
14973
+ }
14974
+ } catch (error2) {
14975
+ }
14956
14976
  this._player.removeClass(STATE_CLASS.ENTER);
14957
- this.emit(
14958
- Events$1.FALLBACK_ERROR,
14959
- transform$1(err, this._i18nManager)
14960
- );
14977
+ this.emit(Events$1.FALLBACK_ERROR, transformedError);
14961
14978
  return;
14962
14979
  }
14963
14980
  this._player.once("canplay", () => {
@@ -15037,7 +15054,6 @@ class VePlayerBase {
15037
15054
  return new Promise((resolve) => {
15038
15055
  const curTime = this._player.currentTime;
15039
15056
  const _canplay = () => {
15040
- console.log("canplay canplay");
15041
15057
  this._player.currentTime = curTime;
15042
15058
  if (isPaused) {
15043
15059
  this._player.once(CANPLAY, () => {
@@ -19588,44 +19604,6 @@ class Lite {
19588
19604
  return result;
19589
19605
  }
19590
19606
  }
19591
- function enableHlsJs(options) {
19592
- var _a, _b;
19593
- if ((_a = options == null ? void 0 : options.hls) == null ? void 0 : _a.enableHlsJs) {
19594
- return true;
19595
- }
19596
- if (((_b = options == null ? void 0 : options.ad) == null ? void 0 : _b.adType) === "ssai") {
19597
- return true;
19598
- }
19599
- return false;
19600
- }
19601
- const getHlsStrategy = async (options) => {
19602
- var _a, _b;
19603
- let mseStrategy;
19604
- let softStrategy;
19605
- const codec = await getCodec(options);
19606
- const isSoftDecode$1 = await isSoftDecode(options, codec);
19607
- const useHlsJs = enableHlsJs(options);
19608
- if (isSoftDecode$1) {
19609
- softStrategy = codec === Codec.H265 ? createSoftDecodeH265Strategy() : createSoftDecodeH264Strategy();
19610
- mseStrategy = createHlsMseStrategy(options, useHlsJs);
19611
- }
19612
- if ((sniffer$1.device !== "mobile" || ((_a = options == null ? void 0 : options.hls) == null ? void 0 : _a.enableMSE)) && (codec === "unknown" ? isMseSupported$2(Codec.H264) : isMseSupported$2(codec))) {
19613
- mseStrategy = createHlsMseStrategy(options, useHlsJs);
19614
- }
19615
- if (!mseStrategy && !softStrategy) {
19616
- return {};
19617
- }
19618
- const [mseModule, softModule] = await Promise.all([
19619
- (mseStrategy == null ? void 0 : mseStrategy.module) && load(mseStrategy.module).catch(() => void 0),
19620
- (softStrategy == null ? void 0 : softStrategy.module) && load(softStrategy.module).catch(() => void 0)
19621
- ]);
19622
- (softModule == null ? void 0 : softModule.XGVideoPlugin) && ((_b = softStrategy == null ? void 0 : softStrategy.afterLoad) == null ? void 0 : _b.call(softStrategy, softModule == null ? void 0 : softModule.XGVideoPlugin));
19623
- const combineOptions$1 = combineOptions([mseStrategy, softStrategy]);
19624
- return {
19625
- options: combineOptions$1,
19626
- plugins: (mseModule == null ? void 0 : mseModule.HlsPlugin) ? [mseModule.HlsPlugin] : []
19627
- };
19628
- };
19629
19607
  const getDefaultFlvOptions = (options) => {
19630
19608
  var _a;
19631
19609
  return {
@@ -19797,203 +19775,6 @@ function create(errorCode, i18n) {
19797
19775
  i18n
19798
19776
  );
19799
19777
  }
19800
- async function isRTMSupported() {
19801
- const { RtmPlugin } = await load(DynamicModule.PluginRtm);
19802
- return RtmPlugin.isSupported();
19803
- }
19804
- async function isRTMSupportCodec(codec = RTMCodec.H264) {
19805
- const { RtmPlugin } = await load(DynamicModule.PluginRtm);
19806
- if (codec === RTMCodec.H264)
19807
- return RtmPlugin.isSupportedH264();
19808
- return false;
19809
- }
19810
- const rtmStrategy = {
19811
- options: {},
19812
- module: DynamicModule.PluginRtm
19813
- };
19814
- const generateFallbackUrl = (url) => {
19815
- if (sniffer$1.device === "pc") {
19816
- return url.replace(".sdp", ".flv");
19817
- } else {
19818
- return url.replace(".sdp", ".m3u8");
19819
- }
19820
- };
19821
- const getRtmStrategy = async (options, player, i18n) => {
19822
- var _a, _b;
19823
- let backupStrategy;
19824
- let actualFallbackUrl = "";
19825
- const { url, playlist } = options;
19826
- const { fallbackUrl, enableRTMAutoTranscode, ...ret } = options.rtm || {};
19827
- let { enableFallback = true } = options.rtm || {};
19828
- if (playlist == null ? void 0 : playlist.length) {
19829
- enableFallback = false;
19830
- }
19831
- const isRTMAutoTranscode = enableRTMAutoTranscode || ((_a = getUrlObject(url)) == null ? void 0 : _a.searchParams.get("enableRTMAutoTranscode")) === "true";
19832
- if (enableFallback) {
19833
- if (fallbackUrl) {
19834
- actualFallbackUrl = fallbackUrl;
19835
- } else if (isRTMAutoTranscode && url) {
19836
- actualFallbackUrl = generateFallbackUrl(url);
19837
- } else {
19838
- console.warn(
19839
- create(ErrorCode.EMPTY_RTM_FALLBACK_PARAMETER, i18n).message
19840
- );
19841
- }
19842
- }
19843
- const backupType = actualFallbackUrl && util.getStreamType(actualFallbackUrl);
19844
- if (backupType === "flv" && util.isMseSupported(Codec.H264)) {
19845
- backupStrategy = createFlvMseStrategy(options);
19846
- } else if (backupType === "hls" && (sniffer$1.device !== "mobile" || ((_b = options == null ? void 0 : options.hls) == null ? void 0 : _b.enableMSE)) && util.isMseSupported(Codec.H264)) {
19847
- backupStrategy = createHlsMseStrategy(options);
19848
- }
19849
- const [rtmCdn, backupCdn] = await Promise.all([
19850
- load(rtmStrategy.module).then((module) => {
19851
- return module.RtmPlugin;
19852
- }).catch(() => void 0),
19853
- backupStrategy && load(backupStrategy.module).then((module) => {
19854
- if ((backupStrategy == null ? void 0 : backupStrategy.module) === DynamicModule.PluginFlv) {
19855
- return module.FlvPlugin;
19856
- } else if ((backupStrategy == null ? void 0 : backupStrategy.module) === DynamicModule.PluginHls) {
19857
- return module.HlsPlugin;
19858
- }
19859
- }).catch(() => void 0)
19860
- ]);
19861
- if (actualFallbackUrl) {
19862
- const [RTMSupported, RTMSupportCodec] = await Promise.all([
19863
- isRTMSupported(),
19864
- isRTMSupportCodec()
19865
- ]);
19866
- if (!RTMSupported || !RTMSupportCodec) {
19867
- if (player) {
19868
- player.emit("degrade", {
19869
- url: actualFallbackUrl,
19870
- originRtmUrl: url,
19871
- code: "NOT_SUPPORT",
19872
- message: "not support rtm or h264",
19873
- isRTMSupported: RTMSupported,
19874
- isRTMSupportCodec: RTMSupportCodec
19875
- });
19876
- }
19877
- return {
19878
- options: {
19879
- ...(backupStrategy == null ? void 0 : backupStrategy.options) || {},
19880
- url: actualFallbackUrl,
19881
- _RTMdegrade: {
19882
- _originRtmUrl: url,
19883
- _isRTMSupported: RTMSupported,
19884
- _isRTMSupportCodec: RTMSupportCodec
19885
- }
19886
- },
19887
- plugins: backupCdn ? [backupCdn] : []
19888
- };
19889
- }
19890
- }
19891
- return {
19892
- options: {
19893
- ...(backupStrategy == null ? void 0 : backupStrategy.options) || {},
19894
- url: enableRTMAutoTranscode ? util.appendSearchParams(url, { enableRTMAutoTranscode: "true" }) : void 0,
19895
- _RTMdegrade: void 0,
19896
- rts: {
19897
- retryCount: 0,
19898
- ...ret,
19899
- backupURL: actualFallbackUrl,
19900
- backupConstruct: backupCdn
19901
- }
19902
- },
19903
- plugins: rtmCdn ? [rtmCdn] : []
19904
- };
19905
- };
19906
- var DrmType = /* @__PURE__ */ ((DrmType2) => {
19907
- DrmType2["Fairplay"] = "fairplay";
19908
- return DrmType2;
19909
- })(DrmType || {});
19910
- function getDrmType(drm) {
19911
- if ((drm == null ? void 0 : drm.fairplay) && (sniffer$1.browser === "safari" || sniffer$1.os.isIos)) {
19912
- return "fairplay";
19913
- }
19914
- return;
19915
- }
19916
- function isMseSupportedWithDrm({
19917
- drm,
19918
- streamType
19919
- }) {
19920
- const drmType = getDrmType(drm);
19921
- if (!drmType) {
19922
- return true;
19923
- }
19924
- if (drmType === "fairplay" && streamType === "hls") {
19925
- return false;
19926
- }
19927
- return true;
19928
- }
19929
- const { isMMSSupported: isMMSSupported$1, isMseSupported: isMseSupported$1 } = util;
19930
- function enableMMS() {
19931
- return sniffer$1.os.isIos;
19932
- }
19933
- function isFLVSupported(codec = Codec.H264) {
19934
- const isMediaSourceSupported = enableMMS() ? isMMSSupported$1 : isMseSupported$1;
19935
- return isMediaSourceSupported(codec);
19936
- }
19937
- const { appendSearchParams } = util;
19938
- const getFlvStrategy = async (options) => {
19939
- var _a, _b, _c, _d, _e, _f;
19940
- let mseStrategy;
19941
- let softStrategy;
19942
- const enableLowLatency = (_a = options == null ? void 0 : options.flv) == null ? void 0 : _a.enableLowLatency;
19943
- const enableFrameChasing = ((_c = (_b = options == null ? void 0 : options.flv) == null ? void 0 : _b.lowLatency) == null ? void 0 : _c.enableFrameChasing) ?? true;
19944
- const abrPts = ((_e = (_d = options == null ? void 0 : options.flv) == null ? void 0 : _d.lowLatency) == null ? void 0 : _e.abrPts) ?? "-800";
19945
- const codec = await getCodec(options);
19946
- const isSoftDecode$1 = await isSoftDecode(options, codec);
19947
- if (isSoftDecode$1) {
19948
- softStrategy = codec === Codec.H265 ? createSoftDecodeH265Strategy() : createSoftDecodeH264Strategy();
19949
- mseStrategy = createFlvMseStrategy(options);
19950
- }
19951
- if (codec === "unknown" ? isFLVSupported(Codec.H264) : isFLVSupported(codec)) {
19952
- mseStrategy = enableMMS() ? createFlvMssStrategy(options) : createFlvMseStrategy(options);
19953
- }
19954
- if (!mseStrategy && !softStrategy) {
19955
- return {};
19956
- }
19957
- const [mseModule, softModule] = await Promise.all([
19958
- (mseStrategy == null ? void 0 : mseStrategy.module) && load(mseStrategy.module).catch(() => void 0),
19959
- (softStrategy == null ? void 0 : softStrategy.module) && load(softStrategy.module).catch(() => void 0)
19960
- ]);
19961
- (softModule == null ? void 0 : softModule.XGVideoPlugin) && ((_f = softStrategy == null ? void 0 : softStrategy.afterLoad) == null ? void 0 : _f.call(softStrategy, softModule == null ? void 0 : softModule.XGVideoPlugin));
19962
- const combineOptions$1 = combineOptions([mseStrategy, softStrategy]);
19963
- const plugins = [];
19964
- if (enableLowLatency) {
19965
- combineOptions$1.url = appendSearchParams(options.url, { abr_pts: abrPts });
19966
- }
19967
- if (mseModule) {
19968
- plugins.push(mseModule.FlvPlugin);
19969
- if (enableLowLatency && enableFrameChasing) {
19970
- plugins.push(mseModule.Adaptive);
19971
- }
19972
- }
19973
- return {
19974
- options: combineOptions$1,
19975
- plugins
19976
- };
19977
- };
19978
- const getTypeStrategy = async (options, player, i18n) => {
19979
- const type = options.url ? util.getStreamType(options.url) : "";
19980
- if (!type || type === "unknown") {
19981
- return { options: {}, plugins: [] };
19982
- }
19983
- if (type === "rtm") {
19984
- return await getRtmStrategy(options, player, i18n);
19985
- }
19986
- if (type === "flv") {
19987
- return await getFlvStrategy(options);
19988
- }
19989
- if (type === "hls") {
19990
- if (!isMseSupportedWithDrm({ drm: options.drm, streamType: type })) {
19991
- return { options: {}, plugins: [] };
19992
- }
19993
- return await getHlsStrategy(options);
19994
- }
19995
- return { options: {}, plugins: [] };
19996
- };
19997
19778
  var FUNC_ERROR_TEXT = "Expected a function";
19998
19779
  var NAN = 0 / 0;
19999
19780
  var symbolTag = "[object Symbol]";
@@ -22806,7 +22587,7 @@ class Logger extends Plugin {
22806
22587
  device_id: this._deviceId,
22807
22588
  error_report_stop: true,
22808
22589
  ext: {
22809
- veplayer_version: "2.6.1",
22590
+ veplayer_version: "2.7.0-rc.0",
22810
22591
  flv_version: "3.0.21-rc.21",
22811
22592
  hls_version: "3.0.21-rc.21",
22812
22593
  rts_version: "0.2.1-alpha.14"
@@ -23081,16 +22862,326 @@ const ZH_CN = {
23081
22862
  DECODE_INFO: "软解信息",
23082
22863
  REFRESH: "刷新"
23083
22864
  };
23084
- const getDrmStrategy = async (options, player) => {
23085
- var _a;
23086
- const drmType = getDrmType(options.drm);
23087
- if (options.url && drmType === DrmType.Fairplay) {
23088
- try {
23089
- const { getDrmConfig, ...originFairplayConfig } = ((_a = options == null ? void 0 : options.drm) == null ? void 0 : _a.fairplay) ?? {};
23090
- const [drmPlugin, drmConfig] = await Promise.all([
23091
- load(DynamicModule.PluginDrm).then((module) => module.DrmPlugin).catch(() => void 0),
23092
- getDrmConfig == null ? void 0 : getDrmConfig({
23093
- url: options.url
22865
+ const LiveUrlType = {
22866
+ Hls: "hls",
22867
+ LLHls: "ll-hls",
22868
+ Flv: "flv",
22869
+ Rtm: "rtm",
22870
+ LLFlv: "ll-flv"
22871
+ };
22872
+ const { isMMSSupported: isMMSSupported$1, isMseSupported: isMseSupported$2 } = util;
22873
+ function enableMMS() {
22874
+ return sniffer$1.os.isIos;
22875
+ }
22876
+ function isFLVSupported(codec = Codec.H264) {
22877
+ const isMediaSourceSupported = enableMMS() ? isMMSSupported$1 : isMseSupported$2;
22878
+ return isMediaSourceSupported(codec);
22879
+ }
22880
+ var FallbackKind = /* @__PURE__ */ ((FallbackKind2) => {
22881
+ FallbackKind2["Error"] = "Error";
22882
+ FallbackKind2["Stall"] = "Stall";
22883
+ return FallbackKind2;
22884
+ })(FallbackKind || {});
22885
+ class BaseProtocol {
22886
+ constructor(options) {
22887
+ // 下一个 protocol 类
22888
+ __publicField(this, "nextProtocol");
22889
+ __publicField(this, "preProtocol");
22890
+ __publicField(this, "protocolStrategy");
22891
+ __publicField(this, "_fallback");
22892
+ this._fallback = options.fallback;
22893
+ }
22894
+ _getKindFallbackStrategy(kind) {
22895
+ var _a, _b, _c, _d, _e, _f, _g;
22896
+ return ((_c = (_b = (_a = this._fallback) == null ? void 0 : _a.fallbackStrategy) == null ? void 0 : _b[this.protocolType]) == null ? void 0 : _c[kind]) ?? ((_f = (_e = (_d = this._fallback) == null ? void 0 : _d.fallbackStrategy) == null ? void 0 : _e["all"]) == null ? void 0 : _f[kind]) ?? ((_g = this.defaultFallbackStrategy) == null ? void 0 : _g[kind]);
22897
+ }
22898
+ // eslint-disable-next-line @typescript-eslint/member-ordering
22899
+ get errorFallbackStrategy() {
22900
+ return this._getKindFallbackStrategy(
22901
+ "Error"
22902
+ /* Error */
22903
+ );
22904
+ }
22905
+ // eslint-disable-next-line @typescript-eslint/member-ordering
22906
+ get stallFallbackStrategy() {
22907
+ return this._getKindFallbackStrategy(
22908
+ "Stall"
22909
+ /* Stall */
22910
+ );
22911
+ }
22912
+ // eslint-disable-next-line @typescript-eslint/member-ordering
22913
+ shouldFallbackWhenError(params) {
22914
+ var _a, _b, _c;
22915
+ if ((_a = this.errorFallbackStrategy) == null ? void 0 : _a.shouldFallback) {
22916
+ return (_b = this.errorFallbackStrategy) == null ? void 0 : _b.shouldFallback(
22917
+ this.protocolType,
22918
+ params
22919
+ );
22920
+ }
22921
+ if ((_c = this.errorFallbackStrategy) == null ? void 0 : _c.excludeList) {
22922
+ return !this.errorFallbackStrategy.excludeList.includes(
22923
+ params.error.errorCode
22924
+ );
22925
+ }
22926
+ return false;
22927
+ }
22928
+ }
22929
+ const { appendSearchParams } = util;
22930
+ const getFlvStrategy = async (options) => {
22931
+ var _a, _b, _c, _d, _e, _f;
22932
+ let mseStrategy;
22933
+ let softStrategy;
22934
+ const enableLowLatency = (_a = options == null ? void 0 : options.flv) == null ? void 0 : _a.enableLowLatency;
22935
+ const enableFrameChasing = ((_c = (_b = options == null ? void 0 : options.flv) == null ? void 0 : _b.lowLatency) == null ? void 0 : _c.enableFrameChasing) ?? true;
22936
+ const abrPts = ((_e = (_d = options == null ? void 0 : options.flv) == null ? void 0 : _d.lowLatency) == null ? void 0 : _e.abrPts) ?? "-800";
22937
+ const codec = await getCodec(options);
22938
+ const isSoftDecode$1 = await isSoftDecode(options, codec);
22939
+ if (isSoftDecode$1) {
22940
+ softStrategy = codec === Codec.H265 ? createSoftDecodeH265Strategy() : createSoftDecodeH264Strategy();
22941
+ mseStrategy = createFlvMseStrategy(options);
22942
+ }
22943
+ if (codec === "unknown" ? isFLVSupported(Codec.H264) : isFLVSupported(codec)) {
22944
+ mseStrategy = enableMMS() ? createFlvMssStrategy(options) : createFlvMseStrategy(options);
22945
+ }
22946
+ if (!mseStrategy && !softStrategy) {
22947
+ return {};
22948
+ }
22949
+ const [mseModule, softModule] = await Promise.all([
22950
+ (mseStrategy == null ? void 0 : mseStrategy.module) && load(mseStrategy.module).catch(() => void 0),
22951
+ (softStrategy == null ? void 0 : softStrategy.module) && load(softStrategy.module).catch(() => void 0)
22952
+ ]);
22953
+ (softModule == null ? void 0 : softModule.XGVideoPlugin) && ((_f = softStrategy == null ? void 0 : softStrategy.afterLoad) == null ? void 0 : _f.call(softStrategy, softModule == null ? void 0 : softModule.XGVideoPlugin));
22954
+ const combineOptions$1 = combineOptions([mseStrategy, softStrategy]);
22955
+ const plugins = [];
22956
+ if (enableLowLatency) {
22957
+ combineOptions$1.url = appendSearchParams(options.url, { abr_pts: abrPts });
22958
+ }
22959
+ if (mseModule) {
22960
+ plugins.push(mseModule.FlvPlugin);
22961
+ if (enableLowLatency && enableFrameChasing) {
22962
+ plugins.push(mseModule.Adaptive);
22963
+ }
22964
+ }
22965
+ return {
22966
+ options: combineOptions$1,
22967
+ plugins
22968
+ };
22969
+ };
22970
+ class FlvProtocol extends BaseProtocol {
22971
+ static get suffix() {
22972
+ return ".flv";
22973
+ }
22974
+ get protocolType() {
22975
+ return LiveUrlType.Flv;
22976
+ }
22977
+ get defaultFallbackStrategy() {
22978
+ return {};
22979
+ }
22980
+ static generateUrl(urls, {
22981
+ generateUrlFromOtherProtocol: generateUrlFromOtherProtocol2
22982
+ }) {
22983
+ return urls[LiveUrlType.Flv] ?? generateUrlFromOtherProtocol2();
22984
+ }
22985
+ static canGenerateOtherProtocol() {
22986
+ return true;
22987
+ }
22988
+ async canPlay() {
22989
+ return {
22990
+ canPlay: isFLVSupported()
22991
+ };
22992
+ }
22993
+ shouldFallbackWhenStall() {
22994
+ return false;
22995
+ }
22996
+ async getProtocolStrategy(options, {
22997
+ enableSelector
22998
+ }) {
22999
+ return getFlvStrategy(
23000
+ enableSelector ? {
23001
+ ...options,
23002
+ flv: {
23003
+ ...options.flv,
23004
+ enableLowLatency: false
23005
+ }
23006
+ } : options
23007
+ );
23008
+ }
23009
+ async getAbrStrategy(options) {
23010
+ var _a;
23011
+ const abrOptions = (_a = options == null ? void 0 : options.flv) == null ? void 0 : _a.abr;
23012
+ if (!abrOptions) {
23013
+ return {};
23014
+ }
23015
+ const abrPlugin = await load(DynamicModule.PluginAbr).catch(
23016
+ () => void 0
23017
+ );
23018
+ return {
23019
+ options: {
23020
+ abr: {
23021
+ ...abrOptions,
23022
+ open: abrOptions.enable ?? true
23023
+ }
23024
+ },
23025
+ plugins: [abrPlugin == null ? void 0 : abrPlugin.AbrPlugin]
23026
+ };
23027
+ }
23028
+ getDrmStrategy() {
23029
+ return void 0;
23030
+ }
23031
+ }
23032
+ class FlvLowLatencyProtocol extends FlvProtocol {
23033
+ get protocolType() {
23034
+ return LiveUrlType.LLFlv;
23035
+ }
23036
+ async getProtocolStrategy(options) {
23037
+ return getFlvStrategy({
23038
+ ...options,
23039
+ flv: {
23040
+ ...options.flv,
23041
+ enableLowLatency: true
23042
+ }
23043
+ });
23044
+ }
23045
+ }
23046
+ var DrmType = /* @__PURE__ */ ((DrmType2) => {
23047
+ DrmType2["Fairplay"] = "fairplay";
23048
+ return DrmType2;
23049
+ })(DrmType || {});
23050
+ function getDrmType(drm) {
23051
+ if ((drm == null ? void 0 : drm.fairplay) && (sniffer$1.browser === "safari" || sniffer$1.os.isIos)) {
23052
+ return "fairplay";
23053
+ }
23054
+ return;
23055
+ }
23056
+ function isMseSupportedWithDrm({
23057
+ drm,
23058
+ streamType
23059
+ }) {
23060
+ const drmType = getDrmType(drm);
23061
+ if (!drmType) {
23062
+ return true;
23063
+ }
23064
+ if (drmType === "fairplay" && streamType === "hls") {
23065
+ return false;
23066
+ }
23067
+ return true;
23068
+ }
23069
+ const { isMseSupported: isMseSupported$1 } = util;
23070
+ function enableHlsJs(options) {
23071
+ var _a, _b;
23072
+ if ((_a = options == null ? void 0 : options.hls) == null ? void 0 : _a.enableHlsJs) {
23073
+ return true;
23074
+ }
23075
+ if (((_b = options == null ? void 0 : options.ad) == null ? void 0 : _b.adType) === "ssai") {
23076
+ return true;
23077
+ }
23078
+ return false;
23079
+ }
23080
+ const getHlsStrategy = async (options) => {
23081
+ var _a, _b;
23082
+ let mseStrategy;
23083
+ let softStrategy;
23084
+ if (!isMseSupportedWithDrm({ drm: options.drm, streamType: "hls" })) {
23085
+ return { options: {}, plugins: [] };
23086
+ }
23087
+ const codec = await getCodec(options);
23088
+ const isSoftDecode$1 = await isSoftDecode(options, codec);
23089
+ const useHlsJs = enableHlsJs(options);
23090
+ if (isSoftDecode$1) {
23091
+ softStrategy = codec === Codec.H265 ? createSoftDecodeH265Strategy() : createSoftDecodeH264Strategy();
23092
+ mseStrategy = createHlsMseStrategy(options, useHlsJs);
23093
+ }
23094
+ if ((sniffer$1.device !== "mobile" || ((_a = options == null ? void 0 : options.hls) == null ? void 0 : _a.enableMSE)) && (codec === "unknown" ? isMseSupported$1(Codec.H264) : isMseSupported$1(codec))) {
23095
+ mseStrategy = createHlsMseStrategy(options, useHlsJs);
23096
+ }
23097
+ if (!mseStrategy && !softStrategy) {
23098
+ return {};
23099
+ }
23100
+ const [mseModule, softModule] = await Promise.all([
23101
+ (mseStrategy == null ? void 0 : mseStrategy.module) && load(mseStrategy.module).catch(() => void 0),
23102
+ (softStrategy == null ? void 0 : softStrategy.module) && load(softStrategy.module).catch(() => void 0)
23103
+ ]);
23104
+ (softModule == null ? void 0 : softModule.XGVideoPlugin) && ((_b = softStrategy == null ? void 0 : softStrategy.afterLoad) == null ? void 0 : _b.call(softStrategy, softModule == null ? void 0 : softModule.XGVideoPlugin));
23105
+ const combineOptions$1 = combineOptions([mseStrategy, softStrategy]);
23106
+ return {
23107
+ options: combineOptions$1,
23108
+ plugins: (mseModule == null ? void 0 : mseModule.HlsPlugin) ? [mseModule.HlsPlugin] : []
23109
+ };
23110
+ };
23111
+ function getType(definition) {
23112
+ if (typeof definition === "string") {
23113
+ return getStreamType(definition);
23114
+ }
23115
+ if (definition.type) {
23116
+ return definition.type;
23117
+ }
23118
+ return getStreamType(definition.url);
23119
+ }
23120
+ function pushToEmpty(obj, key, value) {
23121
+ if (!obj[key]) {
23122
+ obj[key] = [];
23123
+ }
23124
+ obj[key].push(value);
23125
+ }
23126
+ function splitPlaylist(playlist) {
23127
+ return playlist.reduce((pre, source) => {
23128
+ const definitionMap = source.definitions.reduce(
23129
+ (preDefinition, definition) => {
23130
+ const type = getType(definition);
23131
+ pushToEmpty(preDefinition, type, definition);
23132
+ return preDefinition;
23133
+ },
23134
+ {}
23135
+ );
23136
+ Object.keys(definitionMap).map((type) => {
23137
+ pushToEmpty(pre, type, {
23138
+ ...source,
23139
+ definitions: definitionMap[type]
23140
+ });
23141
+ });
23142
+ return pre;
23143
+ }, {});
23144
+ }
23145
+ function generateUrlFromOtherProtocol(playlist, suffix, targetSuffix) {
23146
+ return modifyPlaylistUrl(playlist, (url) => {
23147
+ return url.replace(suffix, targetSuffix);
23148
+ });
23149
+ }
23150
+ function modifyPlaylistUrl(playlist, callback) {
23151
+ const newPlaylist = [];
23152
+ playlist == null ? void 0 : playlist.forEach((source) => {
23153
+ const definitions = [];
23154
+ source.definitions.forEach((definition) => {
23155
+ var _a;
23156
+ if (typeof definition === "string") {
23157
+ definitions.push(callback(definition));
23158
+ } else {
23159
+ definitions.push({
23160
+ ...definition,
23161
+ url: callback(definition.url),
23162
+ fallbackUrls: (_a = definition.fallbackUrls) == null ? void 0 : _a.map(
23163
+ (fallbackUrl) => callback(fallbackUrl)
23164
+ )
23165
+ });
23166
+ }
23167
+ });
23168
+ newPlaylist.push({
23169
+ ...source,
23170
+ definitions
23171
+ });
23172
+ });
23173
+ return newPlaylist;
23174
+ }
23175
+ const getDrmStrategy = async (options, player) => {
23176
+ var _a;
23177
+ const drmType = getDrmType(options.drm);
23178
+ if (options.url && drmType === DrmType.Fairplay) {
23179
+ try {
23180
+ const { getDrmConfig, ...originFairplayConfig } = ((_a = options == null ? void 0 : options.drm) == null ? void 0 : _a.fairplay) ?? {};
23181
+ const [drmPlugin, drmConfig] = await Promise.all([
23182
+ load(DynamicModule.PluginDrm).then((module) => module.DrmPlugin).catch(() => void 0),
23183
+ getDrmConfig == null ? void 0 : getDrmConfig({
23184
+ url: options.url
23094
23185
  })
23095
23186
  ]);
23096
23187
  const fairplayDrmConfig = Object.assign(
@@ -23112,29 +23203,547 @@ const getDrmStrategy = async (options, player) => {
23112
23203
  }
23113
23204
  return {};
23114
23205
  };
23115
- const getAbrStrategy = async (options) => {
23116
- var _a, _b;
23117
- const streamType = options.url && getStreamType(options.url);
23118
- if (streamType === "rtm") {
23206
+ class HlsProtocol extends BaseProtocol {
23207
+ static get suffix() {
23208
+ return ".m3u8";
23209
+ }
23210
+ get protocolType() {
23211
+ return LiveUrlType.Hls;
23212
+ }
23213
+ get defaultFallbackStrategy() {
23119
23214
  return {};
23120
23215
  }
23121
- const abrOptions = streamType === "flv" ? (_a = options == null ? void 0 : options.flv) == null ? void 0 : _a.abr : (_b = options == null ? void 0 : options.hls) == null ? void 0 : _b.abr;
23122
- if (!abrOptions) {
23216
+ static canGenerateOtherProtocol() {
23217
+ return true;
23218
+ }
23219
+ static generateUrl(urls, {
23220
+ generateUrlFromOtherProtocol: generateUrlFromOtherProtocol2
23221
+ }) {
23222
+ if (urls[LiveUrlType.Hls]) {
23223
+ return urls[LiveUrlType.Hls];
23224
+ }
23225
+ if (urls[LiveUrlType.LLHls]) {
23226
+ return modifyPlaylistUrl(urls[LiveUrlType.LLHls], (url) => {
23227
+ return util.appendSearchParams(url, {
23228
+ fpkey_normal_hls: "1"
23229
+ });
23230
+ });
23231
+ }
23232
+ return generateUrlFromOtherProtocol2();
23233
+ }
23234
+ async canPlay() {
23235
+ return { canPlay: true };
23236
+ }
23237
+ shouldFallbackWhenStall() {
23238
+ return false;
23239
+ }
23240
+ async getProtocolStrategy(options) {
23241
+ return getHlsStrategy(options);
23242
+ }
23243
+ async getAbrStrategy(options) {
23244
+ var _a;
23245
+ const abrOptions = (_a = options == null ? void 0 : options.hls) == null ? void 0 : _a.abr;
23246
+ if (!abrOptions) {
23247
+ return {};
23248
+ }
23249
+ const abrPlugin = await load(DynamicModule.PluginAbr).catch(
23250
+ () => void 0
23251
+ );
23252
+ return {
23253
+ options: {
23254
+ hlsabr: {
23255
+ ...abrOptions,
23256
+ open: abrOptions.enable ?? true
23257
+ }
23258
+ },
23259
+ plugins: [abrPlugin == null ? void 0 : abrPlugin.HlsAbrPlugin]
23260
+ };
23261
+ }
23262
+ getDrmStrategy(options, player) {
23263
+ return getDrmStrategy(options, player);
23264
+ }
23265
+ }
23266
+ class HlsLowLatencyProtocol extends BaseProtocol {
23267
+ static get suffix() {
23268
+ return ".m3u8";
23269
+ }
23270
+ get protocolType() {
23271
+ return LiveUrlType.LLHls;
23272
+ }
23273
+ get defaultFallbackStrategy() {
23123
23274
  return {};
23124
23275
  }
23125
- const abrPlugin = await load(DynamicModule.PluginAbr).catch(() => void 0);
23276
+ static generateUrl(urls) {
23277
+ return urls[LiveUrlType.LLHls];
23278
+ }
23279
+ static canGenerateOtherProtocol() {
23280
+ return true;
23281
+ }
23282
+ async canPlay() {
23283
+ return { canPlay: true };
23284
+ }
23285
+ shouldFallbackWhenStall() {
23286
+ return false;
23287
+ }
23288
+ async getProtocolStrategy(options) {
23289
+ return getHlsStrategy(options);
23290
+ }
23291
+ getAbrStrategy() {
23292
+ return void 0;
23293
+ }
23294
+ getDrmStrategy() {
23295
+ return void 0;
23296
+ }
23297
+ }
23298
+ async function isRTMSupported() {
23299
+ const { RtmPlugin } = await load(DynamicModule.PluginRtm);
23300
+ return RtmPlugin.isSupported();
23301
+ }
23302
+ async function isRTMSupportCodec(codec = RTMCodec.H264) {
23303
+ const { RtmPlugin } = await load(DynamicModule.PluginRtm);
23304
+ if (codec === RTMCodec.H264)
23305
+ return RtmPlugin.isSupportedH264();
23306
+ return false;
23307
+ }
23308
+ const rtmStrategy = {
23309
+ options: {},
23310
+ module: DynamicModule.PluginRtm
23311
+ };
23312
+ const generateFallbackUrl = (url) => {
23313
+ if (sniffer$1.device === "pc") {
23314
+ return url.replace(".sdp", ".flv");
23315
+ } else {
23316
+ return url.replace(".sdp", ".m3u8");
23317
+ }
23318
+ };
23319
+ const getRtmStrategy = async (options, player, i18n) => {
23320
+ var _a, _b;
23321
+ let backupStrategy;
23322
+ let actualFallbackUrl = "";
23323
+ const { url, playlist } = options;
23324
+ const { fallbackUrl, enableRTMAutoTranscode, ...ret } = options.rtm || {};
23325
+ let { enableFallback = true } = options.rtm || {};
23326
+ if (playlist == null ? void 0 : playlist.length) {
23327
+ enableFallback = false;
23328
+ }
23329
+ const isRTMAutoTranscode = enableRTMAutoTranscode || ((_a = getUrlObject(url)) == null ? void 0 : _a.searchParams.get("enableRTMAutoTranscode")) === "true";
23330
+ if (enableFallback) {
23331
+ if (fallbackUrl) {
23332
+ actualFallbackUrl = fallbackUrl;
23333
+ } else if (isRTMAutoTranscode && url) {
23334
+ actualFallbackUrl = generateFallbackUrl(url);
23335
+ } else {
23336
+ console.warn(
23337
+ create(ErrorCode.EMPTY_RTM_FALLBACK_PARAMETER, i18n).message
23338
+ );
23339
+ }
23340
+ }
23341
+ const backupType = actualFallbackUrl && util.getStreamType(actualFallbackUrl);
23342
+ if (backupType === "flv" && util.isMseSupported(Codec.H264)) {
23343
+ backupStrategy = createFlvMseStrategy(options);
23344
+ } else if (backupType === "hls" && (sniffer$1.device !== "mobile" || ((_b = options == null ? void 0 : options.hls) == null ? void 0 : _b.enableMSE)) && util.isMseSupported(Codec.H264)) {
23345
+ backupStrategy = createHlsMseStrategy(options);
23346
+ }
23347
+ const [rtmCdn, backupCdn] = await Promise.all([
23348
+ load(rtmStrategy.module).then((module) => {
23349
+ return module.RtmPlugin;
23350
+ }).catch(() => void 0),
23351
+ backupStrategy && load(backupStrategy.module).then((module) => {
23352
+ if ((backupStrategy == null ? void 0 : backupStrategy.module) === DynamicModule.PluginFlv) {
23353
+ return module.FlvPlugin;
23354
+ } else if ((backupStrategy == null ? void 0 : backupStrategy.module) === DynamicModule.PluginHls) {
23355
+ return module.HlsPlugin;
23356
+ }
23357
+ }).catch(() => void 0)
23358
+ ]);
23359
+ if (actualFallbackUrl) {
23360
+ const [RTMSupported, RTMSupportCodec] = await Promise.all([
23361
+ isRTMSupported(),
23362
+ isRTMSupportCodec()
23363
+ ]);
23364
+ if (!RTMSupported || !RTMSupportCodec) {
23365
+ if (player) {
23366
+ player.emit("degrade", {
23367
+ url: actualFallbackUrl,
23368
+ originRtmUrl: url,
23369
+ code: "NOT_SUPPORT",
23370
+ message: "not support rtm or h264",
23371
+ isRTMSupported: RTMSupported,
23372
+ isRTMSupportCodec: RTMSupportCodec
23373
+ });
23374
+ }
23375
+ return {
23376
+ options: {
23377
+ ...(backupStrategy == null ? void 0 : backupStrategy.options) || {},
23378
+ url: actualFallbackUrl,
23379
+ _RTMdegrade: {
23380
+ _originRtmUrl: url,
23381
+ _isRTMSupported: RTMSupported,
23382
+ _isRTMSupportCodec: RTMSupportCodec
23383
+ }
23384
+ },
23385
+ plugins: backupCdn ? [backupCdn] : []
23386
+ };
23387
+ }
23388
+ }
23126
23389
  return {
23127
23390
  options: {
23128
- [streamType === "flv" ? "abr" : "hlsabr"]: {
23129
- ...abrOptions,
23130
- open: abrOptions.enable ?? true
23391
+ ...(backupStrategy == null ? void 0 : backupStrategy.options) || {},
23392
+ url: enableRTMAutoTranscode ? util.appendSearchParams(url, { enableRTMAutoTranscode: "true" }) : void 0,
23393
+ _RTMdegrade: void 0,
23394
+ rts: {
23395
+ retryCount: 0,
23396
+ ...ret,
23397
+ backupURL: actualFallbackUrl,
23398
+ backupConstruct: backupCdn
23131
23399
  }
23132
23400
  },
23133
- plugins: [
23134
- streamType === "flv" ? abrPlugin == null ? void 0 : abrPlugin.AbrPlugin : abrPlugin == null ? void 0 : abrPlugin.HlsAbrPlugin
23135
- ]
23401
+ plugins: rtmCdn ? [rtmCdn] : []
23136
23402
  };
23137
23403
  };
23404
+ class RtmProtocol extends BaseProtocol {
23405
+ static get suffix() {
23406
+ return ".sdp";
23407
+ }
23408
+ get protocolType() {
23409
+ return LiveUrlType.Rtm;
23410
+ }
23411
+ get defaultFallbackStrategy() {
23412
+ return { [FallbackKind.Error]: { shouldFallback: () => true } };
23413
+ }
23414
+ static canGenerateOtherProtocol(options) {
23415
+ var _a;
23416
+ return (_a = options.rtm) == null ? void 0 : _a.enableRTMAutoTranscode;
23417
+ }
23418
+ static generateUrl(urls, {
23419
+ generateUrlFromOtherProtocol: generateUrlFromOtherProtocol2,
23420
+ options
23421
+ }) {
23422
+ var _a;
23423
+ if (urls[LiveUrlType.Rtm]) {
23424
+ return urls[LiveUrlType.Rtm];
23425
+ }
23426
+ if ((_a = options.rtm) == null ? void 0 : _a.enableRTMAutoTranscode) {
23427
+ return generateUrlFromOtherProtocol2();
23428
+ }
23429
+ console.warn("生成 rtm 地址失败。请传入 rtm 播放地址,或开启自动转码");
23430
+ return;
23431
+ }
23432
+ async canPlay() {
23433
+ const [isSupported, isSupportCodec] = await Promise.all([
23434
+ isRTMSupported(),
23435
+ isRTMSupportCodec()
23436
+ ]);
23437
+ return {
23438
+ canPlay: isSupported && isSupportCodec
23439
+ };
23440
+ }
23441
+ shouldFallbackWhenStall() {
23442
+ return false;
23443
+ }
23444
+ async getProtocolStrategy(options, {
23445
+ player,
23446
+ i18n,
23447
+ enableSelector
23448
+ }) {
23449
+ this.protocolStrategy = await getRtmStrategy(
23450
+ enableSelector ? {
23451
+ options,
23452
+ rtm: {
23453
+ ...options.rtm,
23454
+ enableFallback: false
23455
+ }
23456
+ } : options,
23457
+ player,
23458
+ i18n
23459
+ );
23460
+ return this.protocolStrategy;
23461
+ }
23462
+ getAbrStrategy() {
23463
+ return void 0;
23464
+ }
23465
+ getDrmStrategy() {
23466
+ return void 0;
23467
+ }
23468
+ }
23469
+ class ProtocolSelector {
23470
+ constructor({ queue, streams, options }) {
23471
+ // 链开始的类
23472
+ // start?: AbstractProtocol;
23473
+ // 链结束的类,也是当前正在播放的类型
23474
+ __publicField(this, "current");
23475
+ // 降级顺序
23476
+ __publicField(this, "_queue");
23477
+ __publicField(this, "_streams");
23478
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
23479
+ // @ts-ignore
23480
+ __publicField(this, "_options");
23481
+ this._queue = queue;
23482
+ this._streams = streams;
23483
+ this._options = options;
23484
+ this.current = this._getStartProtocol();
23485
+ }
23486
+ // 获取最终返回的播放类型和参数。
23487
+ async getProtocol() {
23488
+ if (!this.current) {
23489
+ return;
23490
+ }
23491
+ const { canPlay } = await this.current.canPlay() ?? {};
23492
+ if (canPlay) {
23493
+ return this.current;
23494
+ }
23495
+ this.next();
23496
+ return this.getProtocol();
23497
+ }
23498
+ // 降级时,将指针指到上次结束的位置
23499
+ next() {
23500
+ var _a;
23501
+ this.current = (_a = this.current) == null ? void 0 : _a.nextProtocol;
23502
+ }
23503
+ // 生成责任链
23504
+ _getStartProtocol() {
23505
+ let nextProtocol;
23506
+ for (let index = this._queue.length - 1; index >= 0; index--) {
23507
+ const type = this._queue[index];
23508
+ const protocol = this._streams[type];
23509
+ if (protocol) {
23510
+ if (nextProtocol) {
23511
+ nextProtocol.preProtocol = protocol;
23512
+ protocol.nextProtocol = nextProtocol;
23513
+ }
23514
+ nextProtocol = protocol;
23515
+ }
23516
+ }
23517
+ return nextProtocol;
23518
+ }
23519
+ }
23520
+ const _LowLatencySelector = class extends ProtocolSelector {
23521
+ // 目前默认传入了默认的低延迟选择顺序,
23522
+ // 也可以支持自定义配置
23523
+ constructor({
23524
+ streams,
23525
+ options
23526
+ }) {
23527
+ super({
23528
+ queue: _LowLatencySelector.queue,
23529
+ streams,
23530
+ options
23531
+ });
23532
+ }
23533
+ };
23534
+ let LowLatencySelector = _LowLatencySelector;
23535
+ __publicField(LowLatencySelector, "queue", [
23536
+ LiveUrlType.Rtm,
23537
+ LiveUrlType.LLFlv,
23538
+ LiveUrlType.Flv,
23539
+ LiveUrlType.LLHls,
23540
+ LiveUrlType.Hls
23541
+ ]);
23542
+ class CustomSelector extends ProtocolSelector {
23543
+ constructor({
23544
+ streams,
23545
+ options
23546
+ }) {
23547
+ var _a;
23548
+ super({
23549
+ queue: (_a = options.fallback) == null ? void 0 : _a.fallbackOrder,
23550
+ streams,
23551
+ options
23552
+ });
23553
+ }
23554
+ }
23555
+ __publicField(CustomSelector, "queue");
23556
+ const _ProtocolManager = class {
23557
+ constructor(options) {
23558
+ __publicField(this, "_options");
23559
+ __publicField(this, "_selector");
23560
+ __publicField(this, "_protocol");
23561
+ __publicField(this, "_playlistMap", {});
23562
+ this._options = options;
23563
+ this._init({
23564
+ url: options.url,
23565
+ playlist: options.playlist
23566
+ });
23567
+ }
23568
+ get enableSelector() {
23569
+ return !!this._selector;
23570
+ }
23571
+ get protocol() {
23572
+ return this._protocol;
23573
+ }
23574
+ get playlist() {
23575
+ var _a;
23576
+ return ((_a = this._protocol) == null ? void 0 : _a.protocolType) && this._playlistMap ? this._playlistMap[this._protocol.protocolType] : void 0;
23577
+ }
23578
+ static async create(options) {
23579
+ const protocolManager = new _ProtocolManager(options);
23580
+ await protocolManager.getProtocol();
23581
+ return protocolManager;
23582
+ }
23583
+ static _generateProtocolMap(queue, splittedPlaylist, options) {
23584
+ const protocolMap = {};
23585
+ const playlistMap = {};
23586
+ const baseGenerateProtocol = queue.find((type) => {
23587
+ return _ProtocolManager._protocolMap[type].canGenerateOtherProtocol(options) && splittedPlaylist[type];
23588
+ });
23589
+ queue.forEach((protocolType) => {
23590
+ var _a;
23591
+ const playlist = ((_a = _ProtocolManager._protocolMap[protocolType]) == null ? void 0 : _a.generateUrl(
23592
+ splittedPlaylist,
23593
+ {
23594
+ generateUrlFromOtherProtocol: () => {
23595
+ if (!baseGenerateProtocol) {
23596
+ return;
23597
+ }
23598
+ return generateUrlFromOtherProtocol(
23599
+ splittedPlaylist[baseGenerateProtocol],
23600
+ _ProtocolManager._protocolMap[baseGenerateProtocol].suffix,
23601
+ _ProtocolManager._protocolMap[protocolType].suffix
23602
+ );
23603
+ },
23604
+ options
23605
+ }
23606
+ )) ?? splittedPlaylist[protocolType];
23607
+ if (playlist) {
23608
+ playlistMap[protocolType] = playlist;
23609
+ protocolMap[protocolType] = new _ProtocolManager._protocolMap[protocolType](options);
23610
+ }
23611
+ });
23612
+ return { protocolMap, playlistMap };
23613
+ }
23614
+ async getProtocol() {
23615
+ if (this._selector) {
23616
+ this._protocol = await this._selector.getProtocol();
23617
+ }
23618
+ return this._protocol;
23619
+ }
23620
+ async update({
23621
+ url,
23622
+ playlist
23623
+ }) {
23624
+ this._options = { ...this._options, url, playlist };
23625
+ this._init({
23626
+ url,
23627
+ playlist
23628
+ });
23629
+ await this.getProtocol();
23630
+ }
23631
+ async next() {
23632
+ if (!this._selector) {
23633
+ return;
23634
+ }
23635
+ this._selector.next();
23636
+ await this.getProtocol();
23637
+ return this._protocol;
23638
+ }
23639
+ async getStrategy(player, i18n) {
23640
+ var _a, _b, _c;
23641
+ const protocol = this._protocol;
23642
+ const [typeStrategy, drmStrategy, abrStrategy] = await Promise.all([
23643
+ protocol == null ? void 0 : protocol.getProtocolStrategy(this._options, {
23644
+ player,
23645
+ i18n,
23646
+ enableSelector: !!this._selector
23647
+ }),
23648
+ (_a = protocol == null ? void 0 : protocol.getDrmStrategy) == null ? void 0 : _a.call(protocol, this._options, player),
23649
+ (_b = protocol == null ? void 0 : protocol.getAbrStrategy) == null ? void 0 : _b.call(protocol, this._options)
23650
+ ]);
23651
+ const { options, plugins } = typeStrategy ?? {};
23652
+ const { options: drmOptions, plugins: drmPlugins } = drmStrategy ?? {};
23653
+ const { options: abrOptions, plugins: abrPlugins } = abrStrategy ?? {};
23654
+ return {
23655
+ options: Object.assign({}, options, drmOptions, abrOptions),
23656
+ plugins: [
23657
+ ...plugins ?? [],
23658
+ ...drmPlugins ?? [],
23659
+ ...abrPlugins ?? []
23660
+ ],
23661
+ useSrc: !((_c = typeStrategy == null ? void 0 : typeStrategy.plugins) == null ? void 0 : _c.length),
23662
+ protocol: protocol == null ? void 0 : protocol.protocolType
23663
+ };
23664
+ }
23665
+ _init({
23666
+ url,
23667
+ playlist
23668
+ }) {
23669
+ var _a;
23670
+ if (playlist) {
23671
+ const splittedPlaylist = splitPlaylist(playlist);
23672
+ const Selector = this._options.latencyMode === "low" ? LowLatencySelector : CustomSelector;
23673
+ const queue = (Selector == null ? void 0 : Selector.queue) ?? ((_a = this._options.fallback) == null ? void 0 : _a.fallbackOrder);
23674
+ if (queue == null ? void 0 : queue.length) {
23675
+ const { protocolMap, playlistMap } = _ProtocolManager._generateProtocolMap(
23676
+ queue,
23677
+ splittedPlaylist,
23678
+ this._options
23679
+ );
23680
+ this._playlistMap = playlistMap;
23681
+ this._selector = new Selector({
23682
+ streams: protocolMap,
23683
+ options: this._options
23684
+ });
23685
+ return;
23686
+ }
23687
+ this._playlistMap = splittedPlaylist;
23688
+ this._initSingleProtocol(Object.keys(splittedPlaylist)[0]);
23689
+ } else if (url) {
23690
+ this._initSingleProtocol(getStreamType(url));
23691
+ }
23692
+ }
23693
+ _initSingleProtocol(protocol) {
23694
+ if (protocol) {
23695
+ this._protocol = new _ProtocolManager._protocolMap[protocol](
23696
+ this._options
23697
+ );
23698
+ }
23699
+ }
23700
+ };
23701
+ let ProtocolManager = _ProtocolManager;
23702
+ __publicField(ProtocolManager, "_protocolMap", {
23703
+ [LiveUrlType.Flv]: FlvProtocol,
23704
+ [LiveUrlType.LLFlv]: FlvLowLatencyProtocol,
23705
+ [LiveUrlType.Hls]: HlsProtocol,
23706
+ [LiveUrlType.LLHls]: HlsLowLatencyProtocol,
23707
+ [LiveUrlType.Rtm]: RtmProtocol
23708
+ });
23709
+ class Fallback {
23710
+ constructor() {
23711
+ __publicField(this, "player");
23712
+ __publicField(this, "protocolManager");
23713
+ __publicField(this, "beforeFallbackError", async (error2) => {
23714
+ var _a, _b, _c, _d, _e, _f;
23715
+ if (!((_b = (_a = this.protocolManager) == null ? void 0 : _a.protocol) == null ? void 0 : _b.shouldFallbackWhenError({ error: error2 })) || !((_d = (_c = this.protocolManager) == null ? void 0 : _c.protocol) == null ? void 0 : _d.nextProtocol)) {
23716
+ return { canEmitError: true };
23717
+ }
23718
+ const nextProtocol = await ((_e = this.protocolManager) == null ? void 0 : _e.next());
23719
+ if (!nextProtocol || !((_f = this.protocolManager) == null ? void 0 : _f.playlist)) {
23720
+ return { canEmitError: true };
23721
+ }
23722
+ this.fallback();
23723
+ return { canEmitError: false };
23724
+ });
23725
+ }
23726
+ initErrorFallback(player, protocolManager) {
23727
+ this.player = player;
23728
+ this.protocolManager = protocolManager;
23729
+ }
23730
+ async fallback() {
23731
+ var _a, _b, _c, _d;
23732
+ if (!((_a = this.protocolManager) == null ? void 0 : _a.playlist))
23733
+ return;
23734
+ const definition = (_b = this.player) == null ? void 0 : _b.definition;
23735
+ const source = (_c = this.player) == null ? void 0 : _c.source;
23736
+ (_d = this.player) == null ? void 0 : _d.updatePlaylist(
23737
+ this.protocolManager.playlist,
23738
+ {
23739
+ definition,
23740
+ source
23741
+ },
23742
+ false
23743
+ );
23744
+ }
23745
+ }
23746
+ const fallback = new Fallback();
23138
23747
  VeI18n.extend([
23139
23748
  {
23140
23749
  LANG: "zh-cn",
@@ -23166,6 +23775,7 @@ class VePlayerLive extends VePlayerBase {
23166
23775
  */
23167
23776
  constructor(options) {
23168
23777
  super(options);
23778
+ __publicField(this, "_protocolManager");
23169
23779
  }
23170
23780
  /** {zh}
23171
23781
  * @brief 获取已经播放的时长,不包含暂停和等待时间,单位为秒。
@@ -23187,6 +23797,12 @@ class VePlayerLive extends VePlayerBase {
23187
23797
  }
23188
23798
  return time;
23189
23799
  }
23800
+ /** {en}
23801
+ * @hidden
23802
+ */
23803
+ /** {zh}
23804
+ * @hidden
23805
+ */
23190
23806
  get ad() {
23191
23807
  var _a, _b;
23192
23808
  return (_b = (_a = this._player.plugins) == null ? void 0 : _a.ad) == null ? void 0 : _b.adManager;
@@ -23339,6 +23955,13 @@ class VePlayerLive extends VePlayerBase {
23339
23955
  var _a, _b, _c;
23340
23956
  return (_c = (_b = (_a = this._player) == null ? void 0 : _a.plugins) == null ? void 0 : _b.flv) == null ? void 0 : _c.getStats();
23341
23957
  }
23958
+ async updatePlaylist(playlist, target, needUpdateProtocol = true) {
23959
+ var _a;
23960
+ if (needUpdateProtocol) {
23961
+ await ((_a = this._protocolManager) == null ? void 0 : _a.update({ playlist }));
23962
+ }
23963
+ return super.updatePlaylist(playlist, target);
23964
+ }
23342
23965
  }
23343
23966
  async function createLivePlayer(options) {
23344
23967
  var _a, _b, _c, _d;
@@ -23357,10 +23980,16 @@ async function createLivePlayer(options) {
23357
23980
  ...options,
23358
23981
  plugins: [...LIVE_DEFAULT_PLUGINS, ...options.plugins ?? []]
23359
23982
  };
23983
+ const protocolManager = await ProtocolManager.create(finalOptions);
23984
+ if (!options.url && !(protocolManager == null ? void 0 : protocolManager.playlist)) {
23985
+ throw create(ErrorCode.INVALID_PARAMETER, i18n);
23986
+ }
23360
23987
  player = await VePlayerBase.create(
23361
23988
  {
23362
23989
  ...LIVE_DEFAULT_OPTIONS,
23363
23990
  ...finalOptions,
23991
+ playlist: protocolManager == null ? void 0 : protocolManager.playlist,
23992
+ beforeFallbackError: fallback.beforeFallbackError,
23364
23993
  isLive: true,
23365
23994
  i18nManager: i18n,
23366
23995
  preProcessUrl: (url) => {
@@ -23372,44 +24001,16 @@ async function createLivePlayer(options) {
23372
24001
  };
23373
24002
  },
23374
24003
  async preparePlugins(url) {
23375
- var _a2;
23376
- const [typeStrategy, drmStrategy, abrStrategy] = await Promise.all([
23377
- getTypeStrategy(
23378
- {
23379
- ...finalOptions,
23380
- url
23381
- },
23382
- player,
23383
- i18n
23384
- ),
23385
- getDrmStrategy(
23386
- {
23387
- ...finalOptions,
23388
- url
23389
- },
23390
- player
23391
- ),
23392
- getAbrStrategy({
23393
- ...finalOptions,
23394
- url
23395
- })
23396
- ]);
23397
- const { options: options2, plugins } = typeStrategy ?? {};
23398
- const { options: drmOptions, plugins: drmPlugins } = drmStrategy ?? {};
23399
- const { options: abrOptions, plugins: abrPlugins } = abrStrategy ?? {};
23400
- return {
23401
- options: Object.assign({}, options2, drmOptions, abrOptions),
23402
- plugins: [
23403
- ...plugins ?? [],
23404
- ...drmPlugins ?? [],
23405
- ...abrPlugins ?? []
23406
- ],
23407
- useSrc: !((_a2 = typeStrategy.plugins) == null ? void 0 : _a2.length)
23408
- };
24004
+ if (!protocolManager.enableSelector) {
24005
+ await protocolManager.update({ url });
24006
+ }
24007
+ return protocolManager.getStrategy(player, i18n);
23409
24008
  }
23410
24009
  },
23411
24010
  VePlayerLive
23412
24011
  );
24012
+ player._protocolManager = protocolManager;
24013
+ fallback.initErrorFallback(player, protocolManager);
23413
24014
  if (player) {
23414
24015
  const RTMDegrade = (_d = (_c = player == null ? void 0 : player._player) == null ? void 0 : _c.config) == null ? void 0 : _d._RTMdegrade;
23415
24016
  if (RTMDegrade) {