@amazon/vinyl 3.2.1 → 3.2.3-next.20261001143710

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.
Files changed (109) hide show
  1. package/README.md +2 -2
  2. package/dist/index.cjs +98 -43
  3. package/dist/index.cjs.map +3 -3
  4. package/dist/index.js +126 -68
  5. package/dist/index.js.map +3 -3
  6. package/dist/test/benchmark.es5.js +7 -6
  7. package/dist/test/benchmark.js +35 -30
  8. package/dist/test/benchmark.js.map +3 -3
  9. package/dist/test/integ.es5.js +329 -312
  10. package/dist/test/integ.js +519 -187
  11. package/dist/test/integ.js.map +4 -4
  12. package/dist/types/current/ad/AdControllerImpl.d.ts.map +1 -1
  13. package/dist/types/current/ad/AdControllerImpl.js +15 -1
  14. package/dist/types/current/ad/discoverHlsInterstitials.js +13 -1
  15. package/dist/types/current/drm/DrmControllerImpl.d.ts +6 -0
  16. package/dist/types/current/drm/DrmControllerImpl.d.ts.map +1 -1
  17. package/dist/types/current/drm/DrmControllerImpl.js +11 -1
  18. package/dist/types/current/drm/commonEme/MsCommonEme.d.ts.map +1 -1
  19. package/dist/types/current/drm/commonEme/MsCommonEme.js +2 -2
  20. package/dist/types/current/drm/commonEme/StandardCommonEme.d.ts.map +1 -1
  21. package/dist/types/current/drm/commonEme/StandardCommonEme.js +3 -2
  22. package/dist/types/current/drm/commonEme/WebKitCommonEme.d.ts.map +1 -1
  23. package/dist/types/current/drm/commonEme/WebKitCommonEme.js +2 -2
  24. package/dist/types/current/drm/dom/MSMediaKeys.d.ts +1 -1
  25. package/dist/types/current/drm/dom/MSMediaKeys.d.ts.map +1 -1
  26. package/dist/types/current/drm/dom/WebKitMediaKeys.d.ts +1 -1
  27. package/dist/types/current/drm/dom/WebKitMediaKeys.d.ts.map +1 -1
  28. package/dist/types/current/drm/util/extractContentId.js +2 -2
  29. package/dist/types/current/playback/PlaybackControllerImpl.d.ts +9 -3
  30. package/dist/types/current/playback/PlaybackControllerImpl.d.ts.map +1 -1
  31. package/dist/types/current/playback/PlaybackControllerImpl.js +38 -33
  32. package/dist/types/current/streaming/MediaQualityMetadata.d.ts +3 -1
  33. package/dist/types/current/streaming/MediaQualityMetadata.d.ts.map +1 -1
  34. package/dist/types/current/streaming/SegmentControllerImpl.d.ts +1 -1
  35. package/dist/types/current/streaming/buffering/BufferingController.d.ts +1 -1
  36. package/dist/types/current/streaming/buffering/BufferingController.d.ts.map +1 -1
  37. package/dist/types/current/streaming/buffering/BufferingController.js +14 -5
  38. package/dist/types/current/streaming/buffering/MediaSourceController.d.ts.map +1 -1
  39. package/dist/types/current/streaming/buffering/MediaSourceController.js +4 -0
  40. package/dist/types/current/text/discoverDashTextTracks.d.ts +2 -2
  41. package/dist/types/current/text/discoverDashTextTracks.js +4 -3
  42. package/dist/types/current/text/parseWebVtt.d.ts.map +1 -1
  43. package/dist/types/current/text/parseWebVtt.js +3 -2
  44. package/dist/types/current/track/TrackController.d.ts.map +1 -1
  45. package/dist/types/current/track/TrackController.js +7 -0
  46. package/dist/types/current/track/hls/HlsManifestData.d.ts +14 -1
  47. package/dist/types/current/track/hls/HlsManifestData.d.ts.map +1 -1
  48. package/dist/types/current/track/hls/buildHlsMediaTimeline.d.ts.map +1 -1
  49. package/dist/types/current/track/hls/buildHlsMediaTimeline.js +10 -2
  50. package/dist/types/current/track/hls/createUrlHlsManifestProvider.d.ts +3 -2
  51. package/dist/types/current/track/hls/createUrlHlsManifestProvider.d.ts.map +1 -1
  52. package/dist/types/current/track/hls/createUrlHlsManifestProvider.js +8 -3
  53. package/dist/types/current/track/mse/MseTrack.d.ts +0 -1
  54. package/dist/types/current/track/mse/MseTrack.d.ts.map +1 -1
  55. package/dist/types/current/track/mse/MseTrack.js +5 -6
  56. package/dist/types/current/tsconfig.tsbuildinfo +1 -1
  57. package/dist/types/ts3.7/drm/DrmControllerImpl.d.ts +6 -0
  58. package/dist/types/ts3.7/playback/PlaybackControllerImpl.d.ts +9 -3
  59. package/dist/types/ts3.7/streaming/MediaQualityMetadata.d.ts +3 -1
  60. package/dist/types/ts3.7/streaming/SegmentControllerImpl.d.ts +1 -1
  61. package/dist/types/ts3.7/streaming/buffering/BufferingController.d.ts +1 -1
  62. package/dist/types/ts3.7/text/discoverDashTextTracks.d.ts +2 -2
  63. package/dist/types/ts3.7/track/hls/HlsManifestData.d.ts +14 -1
  64. package/dist/types/ts3.7/track/hls/createUrlHlsManifestProvider.d.ts +3 -2
  65. package/dist/types/ts3.7/track/mse/MseTrack.d.ts +0 -1
  66. package/dist/types/ts4.1/drm/DrmControllerImpl.d.ts +6 -0
  67. package/dist/types/ts4.1/playback/PlaybackControllerImpl.d.ts +9 -3
  68. package/dist/types/ts4.1/streaming/MediaQualityMetadata.d.ts +3 -1
  69. package/dist/types/ts4.1/streaming/SegmentControllerImpl.d.ts +1 -1
  70. package/dist/types/ts4.1/streaming/buffering/BufferingController.d.ts +1 -1
  71. package/dist/types/ts4.1/text/discoverDashTextTracks.d.ts +2 -2
  72. package/dist/types/ts4.1/track/hls/HlsManifestData.d.ts +14 -1
  73. package/dist/types/ts4.1/track/hls/createUrlHlsManifestProvider.d.ts +3 -2
  74. package/dist/types/ts4.1/track/mse/MseTrack.d.ts +0 -1
  75. package/dist/types/ts4.7/drm/DrmControllerImpl.d.ts +6 -0
  76. package/dist/types/ts4.7/playback/PlaybackControllerImpl.d.ts +9 -3
  77. package/dist/types/ts4.7/streaming/MediaQualityMetadata.d.ts +3 -1
  78. package/dist/types/ts4.7/streaming/SegmentControllerImpl.d.ts +1 -1
  79. package/dist/types/ts4.7/streaming/buffering/BufferingController.d.ts +1 -1
  80. package/dist/types/ts4.7/text/discoverDashTextTracks.d.ts +2 -2
  81. package/dist/types/ts4.7/track/hls/HlsManifestData.d.ts +14 -1
  82. package/dist/types/ts4.7/track/hls/createUrlHlsManifestProvider.d.ts +3 -2
  83. package/dist/types/ts4.7/track/mse/MseTrack.d.ts +0 -1
  84. package/dist/unit/types/current/ad/AdControllerImpl.test.js +66 -0
  85. package/dist/unit/types/current/ad/discoverHlsInterstitials.test.js +29 -2
  86. package/dist/unit/types/current/drm/DrmControllerImpl.test.js +19 -1
  87. package/dist/unit/types/current/drm/commonEme/StandardCommonEme.test.js +12 -4
  88. package/dist/unit/types/current/drm/util/extractContentId.test.js +7 -0
  89. package/dist/unit/types/current/index.d.ts +1 -0
  90. package/dist/unit/types/current/index.d.ts.map +1 -1
  91. package/dist/unit/types/current/index.js +1 -0
  92. package/dist/unit/types/current/playback/PlaybackControllerImpl.test.js +15 -0
  93. package/dist/unit/types/current/streaming/MediaQualityMetadata.test.js +8 -0
  94. package/dist/unit/types/current/streaming/MseTrack.test.js +15 -0
  95. package/dist/unit/types/current/streaming/buffering/BufferingController.test.js +26 -0
  96. package/dist/unit/types/current/streaming/buffering/MediaSourceController.test.js +29 -0
  97. package/dist/unit/types/current/text/TextTrack.test.d.ts +2 -0
  98. package/dist/unit/types/current/text/TextTrack.test.d.ts.map +1 -0
  99. package/dist/unit/types/current/text/TextTrack.test.js +12 -0
  100. package/dist/unit/types/current/text/discoverDashTextTracks.test.js +17 -0
  101. package/dist/unit/types/current/text/parseWebVtt.test.js +26 -0
  102. package/dist/unit/types/current/track/TrackController.test.js +15 -60
  103. package/dist/unit/types/current/track/hls/buildHlsMediaTimeline.test.js +22 -0
  104. package/dist/unit/types/current/track/hls/createUrlHlsManifestProvider.test.js +23 -0
  105. package/dist/unit/types/current/tsconfig.tsbuildinfo +1 -1
  106. package/dist/vinylTestUtil/types/current/tsconfig.tsbuildinfo +1 -1
  107. package/docs/CUSTOMIZATION_GUIDE.md +310 -0
  108. package/package.json +10 -10
  109. package/docs/DASH_MANIFEST_TRANSFORM_GUIDE.md +0 -236
package/README.md CHANGED
@@ -40,8 +40,8 @@ player.load({
40
40
  PlayReady setup.
41
41
  - [DRM Controller](./docs/DRM_CONTROLLER.md) — implementing custom license
42
42
  acquisition.
43
- - [DASH Manifest Transforms](./docs/DASH_MANIFEST_TRANSFORM_GUIDE.md) —
44
- rewriting manifests before parsing.
43
+ - [Customization Guide](./docs/CUSTOMIZATION_GUIDE.md) — timeline / DASH / HLS
44
+ transforms and parser rule extensions.
45
45
  - [Auto Reset](./docs/AUTO_RESET.md) — recovering from terminal playback errors.
46
46
 
47
47
  Browse the full docs and TypeDoc API reference at
package/dist/index.cjs CHANGED
@@ -67,6 +67,7 @@ __export(index_exports, {
67
67
  DrmError: () => DrmError,
68
68
  DrmKeySystem: () => DrmKeySystem,
69
69
  DrmRobustness: () => DrmRobustness,
70
+ EXCESSIVE_SESSION_COUNT: () => EXCESSIVE_SESSION_COUNT,
70
71
  FAIR_PLAY_KEY_SYSTEMS: () => FAIR_PLAY_KEY_SYSTEMS,
71
72
  FixedPlaybackQuality: () => FixedPlaybackQuality,
72
73
  HtmlTextTrackRenderer: () => HtmlTextTrackRenderer,
@@ -669,7 +670,11 @@ var AdControllerImpl = class extends import_vinyl_util2.EventHostImpl {
669
670
  (0, import_vinyl_util2.logVerbose)(this, "nextAd");
670
671
  try {
671
672
  const ad = await adBreakState2.nextAd();
672
- if (this.disposed || adBreakState2.completedReason) return;
673
+ if (this.disposed) return;
674
+ if (adBreakState2.completedReason) {
675
+ if (!this.adBreakState) await nextBreak();
676
+ return;
677
+ }
673
678
  if (ad) {
674
679
  this.startAd(ad);
675
680
  } else {
@@ -803,12 +808,18 @@ var AdControllerImpl = class extends import_vinyl_util2.EventHostImpl {
803
808
  const currProgress = pC.currentTimePercent;
804
809
  const progressStart = adState.timeStart / pC.duration;
805
810
  if (!adState.quartile.first && currProgress > 0.25 && progressStart < AD_START_TOLERANCE) {
811
+ adState.quartile.first = true;
812
+ (0, import_vinyl_util2.logDebug)(this, "adFirstQuartile", adState.ad);
806
813
  this.dispatch("adFirstQuartile", createAdProgressEvent(adState));
807
814
  }
808
815
  if (!adState.quartile.midpoint && currProgress > 0.5 && progressStart < 0.25 + AD_START_TOLERANCE) {
816
+ adState.quartile.midpoint = true;
817
+ (0, import_vinyl_util2.logDebug)(this, "adMidpoint", adState.ad);
809
818
  this.dispatch("adMidpoint", createAdProgressEvent(adState));
810
819
  }
811
820
  if (!adState.quartile.third && currProgress > 0.75 && progressStart < 0.5 + AD_START_TOLERANCE) {
821
+ adState.quartile.third = true;
822
+ (0, import_vinyl_util2.logDebug)(this, "adThirdQuartile", adState.ad);
812
823
  this.dispatch("adThirdQuartile", createAdProgressEvent(adState));
813
824
  }
814
825
  }
@@ -1220,6 +1231,7 @@ async function resolveHlsAssetList({
1220
1231
  const url = (0, import_vinyl_util5.resolveUrl)(assetListUrl, baseUrl);
1221
1232
  const response = await (0, import_vinyl_util5.requestWithRetry)(url);
1222
1233
  const json = await (0, import_vinyl_util5.readResponseBody)(response, "json");
1234
+ const assetListBaseUrl = response.url || url;
1223
1235
  const assets = (_a = json.ASSETS) != null ? _a : [];
1224
1236
  const ads = assets.map((asset, i) => {
1225
1237
  var _a2;
@@ -1227,7 +1239,14 @@ async function resolveHlsAssetList({
1227
1239
  id: `${rangeId}-${i}`,
1228
1240
  startTime,
1229
1241
  duration: (_a2 = asset.DURATION) != null ? _a2 : null,
1230
- uri: (0, import_vinyl_util5.resolveUrl)(asset.URI, baseUrl)
1242
+ // Each Asset-Description "URI" MUST be an absolute URI, so the base
1243
+ // only applies to non-conforming lists. As a leniency (not a spec
1244
+ // rule), resolve against the asset list the URI was read from, as
1245
+ // for any relative reference in a retrieved document (RFC 3986
1246
+ // §5.1.3): asset lists are commonly served by an ad server rather
1247
+ // than alongside the playlist.
1248
+ // @see https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-22#appendix-D.2
1249
+ uri: (0, import_vinyl_util5.resolveUrl)(asset.URI, assetListBaseUrl)
1231
1250
  };
1232
1251
  });
1233
1252
  return { ads, skipControl: parseSkipControl(json["SKIP-CONTROL"]) };
@@ -1545,7 +1564,7 @@ var MsCommonMediaKeySession = class extends import_vinyl_util13.EventHostImpl {
1545
1564
  __publicField(this, "_disposed", false);
1546
1565
  __publicField(this, "messageHandler", (event) => {
1547
1566
  this.dispatch("message", {
1548
- message: event.message.buffer
1567
+ message: (0, import_vinyl_util13.bufferToArrayBuffer)(event.message)
1549
1568
  });
1550
1569
  });
1551
1570
  __publicField(this, "errorHandler", () => {
@@ -1692,11 +1711,7 @@ var StandardCommonMediaKeySession = class extends import_vinyl_util15.EventHostI
1692
1711
  return "StandardCommonMediaKeySession";
1693
1712
  }
1694
1713
  generateRequest() {
1695
- const initData = this.initData;
1696
- return this.session.generateRequest(
1697
- this.initDataType,
1698
- initData instanceof ArrayBuffer ? initData : initData.buffer
1699
- ).catch(createDrmErrorHandler());
1714
+ return this.session.generateRequest(this.initDataType, this.initData).catch(createDrmErrorHandler());
1700
1715
  }
1701
1716
  update(key) {
1702
1717
  if (this.disposed) throw new import_vinyl_util15.DisposedError();
@@ -1805,7 +1820,7 @@ var WebKitCommonMediaKeySession = class extends import_vinyl_util16.EventHostImp
1805
1820
  __publicField(this, "_disposed", false);
1806
1821
  __publicField(this, "messageHandler", (event) => {
1807
1822
  this.dispatch("message", {
1808
- message: event.message.buffer
1823
+ message: (0, import_vinyl_util16.bufferToArrayBuffer)(event.message)
1809
1824
  });
1810
1825
  });
1811
1826
  __publicField(this, "errorHandler", () => {
@@ -2056,7 +2071,7 @@ var import_vinyl_util20 = require("@amazon/vinyl-util");
2056
2071
  var import_vinyl_util21 = require("@amazon/vinyl-util");
2057
2072
  var import_vinyl_util22 = require("@amazon/vinyl-util");
2058
2073
  function extractContentId(initData) {
2059
- const bufferStr = (0, import_vinyl_util22.bufferToUtf16)(initData.buffer);
2074
+ const bufferStr = (0, import_vinyl_util22.bufferToUtf16)((0, import_vinyl_util22.bufferToArrayBuffer)(initData));
2060
2075
  const matches = bufferStr.match(/skd:\/\/(.+)$/);
2061
2076
  if (!matches) {
2062
2077
  throw new import_vinyl_util20.ValidationError("No contentId match", import_vinyl_util21.ErrorOrigin.MEDIA);
@@ -2098,6 +2113,7 @@ function createFairPlaySessionInitData(initData, contentId, certificateData) {
2098
2113
  // src/drm/DrmControllerImpl.ts
2099
2114
  var LICENSE_TIMEOUT = 90;
2100
2115
  var LICENSE_TIMEOUT_MESSAGE = "License provider timed out after {time}s";
2116
+ var EXCESSIVE_SESSION_COUNT = 20;
2101
2117
  var DrmControllerImpl = class extends import_vinyl_util24.EventHostImpl {
2102
2118
  constructor(deps, options) {
2103
2119
  super();
@@ -2314,6 +2330,13 @@ var DrmControllerImpl = class extends import_vinyl_util24.EventHostImpl {
2314
2330
  trackUri
2315
2331
  });
2316
2332
  this.sessions.push(newSession);
2333
+ (0, import_vinyl_util24.logVerbose)(this, `total sessions: ${this.sessions.length}`);
2334
+ if (this.sessions.length === EXCESSIVE_SESSION_COUNT + 1) {
2335
+ (0, import_vinyl_util24.logWarn)(
2336
+ this,
2337
+ `${this.sessions.length} open key sessions exceeds ${EXCESSIVE_SESSION_COUNT}; sessions may be leaking (not closing on track deactivation)`
2338
+ );
2339
+ }
2317
2340
  this.dispatch("sessionCreate", {
2318
2341
  initDataType: newSession.initDataType,
2319
2342
  mimeType: newSession.mimeType
@@ -2825,7 +2848,7 @@ function configureVinylGlobal(options) {
2825
2848
  var import_vinyl_util27 = require("@amazon/vinyl-util");
2826
2849
  var vinylVersion = /* @__PURE__ */ (0, import_vinyl_util27.parseVersion)(
2827
2850
  /* istanbul ignore next */
2828
- "3.2.1"
2851
+ "3.2.2"
2829
2852
  );
2830
2853
 
2831
2854
  // src/global/globalRef.ts
@@ -3378,15 +3401,13 @@ var PlaybackControllerImpl = class extends import_vinyl_util42.EventHostImpl {
3378
3401
  __publicField(this, "_playing", false);
3379
3402
  __publicField(this, "_seeking", false);
3380
3403
  __publicField(this, "_waiting", false);
3381
- // Monotonic counter identifying the most recent seekTo call.
3382
- __publicField(this, "_seekId", 0);
3404
+ __publicField(this, "seekAbortSlot", /* @__PURE__ */ (0, import_vinyl_util42.createAbortSlot)());
3383
3405
  // Stops the stall detector started after the last seek, if any.
3384
3406
  __publicField(this, "stopStallDetection", null);
3385
3407
  // default user volume (0.0 to 1.0 scale)
3386
3408
  __publicField(this, "userVolume", 1);
3387
3409
  __publicField(this, "_pendingPlay", null);
3388
3410
  __publicField(this, "playAbort", null);
3389
- __publicField(this, "disposeAbort", /* @__PURE__ */ new import_vinyl_util42.Abort());
3390
3411
  __publicField(this, "options");
3391
3412
  this.options = __spreadValues(__spreadProps(__spreadValues({}, defaultPlaybackControllerImplOptions), {
3392
3413
  minSeekableBuffer: getMinSeekableBufferDefault()
@@ -3397,8 +3418,7 @@ var PlaybackControllerImpl = class extends import_vinyl_util42.EventHostImpl {
3397
3418
  const { add } = this.disposer;
3398
3419
  add(() => {
3399
3420
  var _a;
3400
- this.disposeAbort.abort();
3401
- this.disposeAbort.dispose();
3421
+ this.seekAbortSlot.abort();
3402
3422
  (_a = this.stopStallDetection) == null ? void 0 : _a.call(this);
3403
3423
  });
3404
3424
  this.domEvents = add(
@@ -3811,14 +3831,10 @@ var PlaybackControllerImpl = class extends import_vinyl_util42.EventHostImpl {
3811
3831
  async seekTo(time, tolerance = 0.5) {
3812
3832
  var _a;
3813
3833
  (0, import_vinyl_util42.logDebug)(this, `seekTo: ${time}`);
3814
- const seekId = ++this._seekId;
3815
3834
  (_a = this.stopStallDetection) == null ? void 0 : _a.call(this);
3816
3835
  this.stopStallDetection = null;
3817
- const superseded = () => {
3818
- if (this._seekId === seekId) return false;
3819
- (0, import_vinyl_util42.logDebug)(this, `seekTo: ${time} superseded by a newer seek`);
3820
- return true;
3821
- };
3836
+ this.seekAbortSlot.abort();
3837
+ const seekAbort = this.seekAbortSlot.value;
3822
3838
  const nextEvent = (type, options) => {
3823
3839
  var _a2;
3824
3840
  return (0, import_vinyl_util42.nextEventAsPromise)(this, type, {
@@ -3826,12 +3842,25 @@ var PlaybackControllerImpl = class extends import_vinyl_util42.EventHostImpl {
3826
3842
  timeoutMessage: `seek timed out on ${type} event after {time}s`,
3827
3843
  timeoutOrigin: import_vinyl_util42.ErrorOrigin.INTERNAL,
3828
3844
  timeoutLevel: import_vinyl_util42.ErrorLevel.WARN,
3829
- abort: this.disposeAbort
3845
+ abort: seekAbort
3830
3846
  });
3831
3847
  };
3848
+ try {
3849
+ await this.doSeek(time, tolerance, seekAbort, nextEvent);
3850
+ } catch (error) {
3851
+ if (seekAbort.aborted() && !this.disposed) return;
3852
+ throw error;
3853
+ }
3854
+ }
3855
+ /**
3856
+ * The body of a single {@link seekTo} attempt. Extracted so {@link seekTo}
3857
+ * can wrap it with per-seek abort/supersession handling. `seekAbort` is
3858
+ * aborted when a newer seek supersedes this one (or on dispose).
3859
+ * @private
3860
+ */
3861
+ async doSeek(time, tolerance, seekAbort, nextEvent) {
3832
3862
  if (!this.hasMetadata) {
3833
3863
  await nextEvent("loadedMetadata");
3834
- if (superseded()) return;
3835
3864
  }
3836
3865
  const seekable = this.seekable;
3837
3866
  const range = seekable.getRangeAt(
@@ -3862,7 +3891,7 @@ var PlaybackControllerImpl = class extends import_vinyl_util42.EventHostImpl {
3862
3891
  );
3863
3892
  } else {
3864
3893
  const nullIfStuck = (error) => {
3865
- if (this.disposeAbort.aborted()) throw error;
3894
+ if (this.disposed) throw error;
3866
3895
  return null;
3867
3896
  };
3868
3897
  const seekOnce = async (reSeeking) => {
@@ -3876,7 +3905,7 @@ var PlaybackControllerImpl = class extends import_vinyl_util42.EventHostImpl {
3876
3905
  }).catch(nullIfStuck);
3877
3906
  };
3878
3907
  let seekedEvent = await seekOnce(false);
3879
- for (let attempt = 0; !superseded() && attempt < SEEK_RETRY_LIMIT && (seekedEvent === null || seekedEvent.reason === "seeked" && !(0, import_vinyl_util42.closeTo)(clampedTime, this.currentTime, tolerance)); attempt++) {
3908
+ for (let attempt = 0; !seekAbort.aborted() && attempt < SEEK_RETRY_LIMIT && (seekedEvent === null || seekedEvent.reason === "seeked" && !(0, import_vinyl_util42.closeTo)(clampedTime, this.currentTime, tolerance)); attempt++) {
3880
3909
  if (seekedEvent === null) void this.media.play().catch(import_vinyl_util42.noop);
3881
3910
  (0, import_vinyl_util42.logDebug)(this, `seekTo: re-seeking to ${clampedTime}`);
3882
3911
  seekedEvent = await seekOnce(true);
@@ -3884,7 +3913,7 @@ var PlaybackControllerImpl = class extends import_vinyl_util42.EventHostImpl {
3884
3913
  if ((seekedEvent == null ? void 0 : seekedEvent.reason) === "emptied") {
3885
3914
  throw new import_vinyl_util42.AbortError();
3886
3915
  }
3887
- if (!this.paused) this.startStallDetection();
3916
+ if (!this.paused && !seekAbort.aborted()) this.startStallDetection();
3888
3917
  }
3889
3918
  }
3890
3919
  /**
@@ -4448,14 +4477,16 @@ var BufferingControllerImpl = class extends import_vinyl_util46.EventHostImpl {
4448
4477
  return;
4449
4478
  }
4450
4479
  const byteLength = streamingSegment.data.byteLength;
4451
- if (byteLength > appendSize) {
4480
+ const remaining = byteLength - this.appendOffset;
4481
+ const firstAppend = this.appendOffset === 0;
4482
+ if (remaining > appendSize) {
4452
4483
  const newOffset = this.appendOffset + appendSize;
4453
4484
  const chunk = streamingSegment.data.slice(
4454
4485
  this.appendOffset,
4455
4486
  newOffset
4456
4487
  );
4457
4488
  await sourceBufferController.append(chunk);
4458
- if (this.appendOffset === 0) {
4489
+ if (firstAppend) {
4459
4490
  this.buffered.push(streamingSegment);
4460
4491
  }
4461
4492
  this.appendOffset = newOffset;
@@ -4464,9 +4495,13 @@ var BufferingControllerImpl = class extends import_vinyl_util46.EventHostImpl {
4464
4495
  `appended chunk, this.appendOffset: ${this.appendOffset}`
4465
4496
  );
4466
4497
  } else {
4467
- await sourceBufferController.append(streamingSegment.data);
4468
- this.appendOffset = streamingSegment.data.byteLength;
4469
- this.buffered.push(streamingSegment);
4498
+ await sourceBufferController.append(
4499
+ firstAppend ? streamingSegment.data : streamingSegment.data.slice(this.appendOffset)
4500
+ );
4501
+ this.appendOffset = byteLength;
4502
+ if (firstAppend) {
4503
+ this.buffered.push(streamingSegment);
4504
+ }
4470
4505
  }
4471
4506
  if (!tail) this.refreshHead();
4472
4507
  }
@@ -4754,6 +4789,7 @@ var MediaSourceControllerImpl = class extends import_vinyl_util49.EventHostImpl
4754
4789
  this.activateDisposer.dispose();
4755
4790
  this.activateDisposer = null;
4756
4791
  ++this.durationToken;
4792
+ this.durationSet = false;
4757
4793
  try {
4758
4794
  URL.revokeObjectURL(this.objectUrl);
4759
4795
  } catch (error) {
@@ -6583,10 +6619,16 @@ function discoverDashTextTracks(manifest, baseUrl) {
6583
6619
  return out;
6584
6620
  }
6585
6621
  function isTextAdaptationSet(adaptationSet) {
6622
+ var _a;
6586
6623
  if (adaptationSet.contentType === "text") return true;
6587
6624
  const mt = adaptationSet.mimeType;
6588
6625
  if (mt && mt.startsWith("text/")) return true;
6589
- return false;
6626
+ return ((_a = adaptationSet.Representation) != null ? _a : []).some(
6627
+ (representation) => {
6628
+ var _a2;
6629
+ return (_a2 = representation.mimeType) == null ? void 0 : _a2.startsWith("text/");
6630
+ }
6631
+ );
6590
6632
  }
6591
6633
  function isSidecarTextMime(mimeType) {
6592
6634
  if (mimeType == null) return true;
@@ -6846,7 +6888,7 @@ function parseWebVtt(input) {
6846
6888
  const cues = [];
6847
6889
  const styles = [];
6848
6890
  let i = 1;
6849
- while (i < lines.length && lines[i] !== "") i++;
6891
+ while (i < lines.length && lines[i] !== "" && !lines[i].includes("-->")) i++;
6850
6892
  while (i < lines.length) {
6851
6893
  if (lines[i] === "") {
6852
6894
  i++;
@@ -7993,7 +8035,6 @@ var MseTrack = class extends TrackBase {
7993
8035
  const deps = depsContainer.dependencies;
7994
8036
  super(uri, type, deps);
7995
8037
  __publicField(this, "streams", []);
7996
- __publicField(this, "disposeAbort", /* @__PURE__ */ new import_vinyl_util80.Abort());
7997
8038
  __publicField(this, "lastPreloadOptions", null);
7998
8039
  __publicField(this, "allFetchedRanges", []);
7999
8040
  __publicField(this, "_fetchedRanges", /* @__PURE__ */ new import_vinyl_util80.IntersectionRanges(
@@ -8018,7 +8059,7 @@ var MseTrack = class extends TrackBase {
8018
8059
  if (this.active) {
8019
8060
  this.deps.drmController.initializeForPlayback(event.current, {
8020
8061
  trackUri: this.uri,
8021
- abort: this.disposeAbort
8062
+ abort: this.drmSessionAbort.value
8022
8063
  });
8023
8064
  }
8024
8065
  });
@@ -8026,7 +8067,7 @@ var MseTrack = class extends TrackBase {
8026
8067
  if (event.current == null) return;
8027
8068
  this.deps.drmController.setBufferingDrmInfo(event.current, {
8028
8069
  trackUri: this.uri,
8029
- abort: this.disposeAbort
8070
+ abort: this.drmSessionAbort.value
8030
8071
  });
8031
8072
  });
8032
8073
  add(
@@ -8264,7 +8305,7 @@ var MseTrack = class extends TrackBase {
8264
8305
  this.streams.forEach((stream) => {
8265
8306
  this.deps.drmController.initializeForPlayback(
8266
8307
  stream.streamingQuality,
8267
- { trackUri: this.uri, abort: this.disposeAbort }
8308
+ { trackUri: this.uri, abort: this.drmSessionAbort.value }
8268
8309
  );
8269
8310
  });
8270
8311
  this.deps.playbackSource.src = this.deps.mediaSourceController.activate();
@@ -8290,7 +8331,7 @@ var MseTrack = class extends TrackBase {
8290
8331
  this.callOnStreams("deactivate");
8291
8332
  this.deps.drmController.setBufferingDrmInfo(null, {
8292
8333
  trackUri: this.uri,
8293
- abort: this.disposeAbort
8334
+ abort: this.drmSessionAbort.value
8294
8335
  });
8295
8336
  (_b = this.deps.textTrackController) == null ? void 0 : _b.deactivate();
8296
8337
  this.deps.playbackSource.src = null;
@@ -9579,7 +9620,11 @@ function createHlsQualityData(deps, data3, baseUrl, playlistUri, metadata) {
9579
9620
  async getSegment(time, affordance = 0) {
9580
9621
  var _a;
9581
9622
  const playlist = await data3.getMediaPlaylist(playlistUri);
9582
- const playlistBaseUrl = (0, import_vinyl_util94.resolveUrl)(playlistUri, baseUrl);
9623
+ const playlistBaseUrl = getPlaylistBaseUrl(
9624
+ playlist,
9625
+ playlistUri,
9626
+ baseUrl
9627
+ );
9583
9628
  const segments = buildSegmentTimeline(
9584
9629
  deps,
9585
9630
  playlistBaseUrl,
@@ -9626,9 +9671,13 @@ async function discoverAdsFromManifest(data3) {
9626
9671
  const variant = data3.mainPlaylist.variants[0];
9627
9672
  const media = await data3.getMediaPlaylist(variant.uri);
9628
9673
  const contentDuration = media.ended ? media.segments.reduce((sum, s) => sum + s.duration, 0) : null;
9629
- const playlistBaseUrl = (0, import_vinyl_util94.resolveUrl)(variant.uri, data3.baseUrl);
9674
+ const playlistBaseUrl = getPlaylistBaseUrl(media, variant.uri, data3.baseUrl);
9630
9675
  return discoverHlsInterstitials(media, playlistBaseUrl, contentDuration);
9631
9676
  }
9677
+ function getPlaylistBaseUrl(playlist, playlistUri, mainBaseUrl) {
9678
+ var _a;
9679
+ return (_a = playlist.baseUrl) != null ? _a : (0, import_vinyl_util94.resolveUrl)(playlistUri, mainBaseUrl);
9680
+ }
9632
9681
 
9633
9682
  // src/track/hls/createDefaultHlsManifestTransformer.ts
9634
9683
  function createDefaultHlsManifestTransformer(deps) {
@@ -9768,8 +9817,11 @@ async function fetchMediaPlaylist(options) {
9768
9817
  const variantUrl = (0, import_vinyl_util96.resolveUrl)(uri, baseUrl);
9769
9818
  const response = await (0, import_vinyl_util96.requestWithRetry)(variantUrl, requestInit, { abort });
9770
9819
  const text = await (0, import_vinyl_util96.readResponseBody)(response, "text");
9771
- const queryParams = parseQueryParams(response.url || variantUrl);
9772
- return (0, import_vinyl_hls_parser3.parseMediaPlaylist)(text, defines, queryParams);
9820
+ const playlistUrl = response.url || variantUrl;
9821
+ const queryParams = parseQueryParams(playlistUrl);
9822
+ return __spreadProps(__spreadValues({}, (0, import_vinyl_hls_parser3.parseMediaPlaylist)(text, defines, queryParams)), {
9823
+ baseUrl: playlistUrl
9824
+ });
9773
9825
  }
9774
9826
  function parseQueryParams(url) {
9775
9827
  const queryStart = url.indexOf("?");
@@ -10222,6 +10274,9 @@ var TrackControllerImpl = class extends import_vinyl_util97.EventHostImpl {
10222
10274
  for (const cachedTrack of this.trackCache.values()) {
10223
10275
  cachedTrack.clearPrefetch();
10224
10276
  }
10277
+ for (const adTracks of this.adTracksByParent.values()) {
10278
+ for (const adTrack of adTracks.values()) adTrack.clearPrefetch();
10279
+ }
10225
10280
  }
10226
10281
  clearQueue() {
10227
10282
  this.setQueue(this._current, []);