@amazon/vinyl 2.0.0 → 3.0.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.
Files changed (167) hide show
  1. package/dist/index.cjs +603 -317
  2. package/dist/index.cjs.map +4 -4
  3. package/dist/index.js +622 -329
  4. package/dist/index.js.map +4 -4
  5. package/dist/test/benchmark.es5.js +8 -5
  6. package/dist/test/benchmark.js +228 -0
  7. package/dist/test/benchmark.js.map +4 -4
  8. package/dist/test/integ.es5.js +182 -156
  9. package/dist/test/integ.js +1853 -796
  10. package/dist/test/integ.js.map +4 -4
  11. package/dist/types/current/index.d.ts +4 -0
  12. package/dist/types/current/index.d.ts.map +1 -1
  13. package/dist/types/current/index.js +4 -0
  14. package/dist/types/current/streaming/AudioOptions.d.ts +39 -0
  15. package/dist/types/current/streaming/AudioOptions.d.ts.map +1 -0
  16. package/dist/types/current/streaming/AudioOptions.js +15 -0
  17. package/dist/types/current/streaming/createDefaultMediaTimelineTransformer.d.ts +2 -2
  18. package/dist/types/current/streaming/createDefaultMediaTimelineTransformer.d.ts.map +1 -1
  19. package/dist/types/current/streaming/createDefaultMediaTimelineTransformer.js +5 -5
  20. package/dist/types/current/text/HtmlTextTrackRenderer.d.ts +60 -0
  21. package/dist/types/current/text/HtmlTextTrackRenderer.d.ts.map +1 -0
  22. package/dist/types/current/text/HtmlTextTrackRenderer.js +231 -0
  23. package/dist/types/current/text/SidecarTextTrackController.d.ts +65 -53
  24. package/dist/types/current/text/SidecarTextTrackController.d.ts.map +1 -1
  25. package/dist/types/current/text/SidecarTextTrackController.js +167 -154
  26. package/dist/types/current/text/SidecarTextTrackLoader.d.ts +5 -0
  27. package/dist/types/current/text/SidecarTextTrackLoader.d.ts.map +1 -1
  28. package/dist/types/current/text/SidecarTextTrackLoader.js +13 -7
  29. package/dist/types/current/text/TextTrack.d.ts +74 -20
  30. package/dist/types/current/text/TextTrack.d.ts.map +1 -1
  31. package/dist/types/current/text/TextTrack.js +20 -0
  32. package/dist/types/current/text/TextTrackRenderer.d.ts +24 -0
  33. package/dist/types/current/text/TextTrackRenderer.d.ts.map +1 -0
  34. package/dist/types/current/text/TextTrackRenderer.js +5 -0
  35. package/dist/types/current/text/mediaTextTrackProvider.d.ts +34 -0
  36. package/dist/types/current/text/mediaTextTrackProvider.d.ts.map +1 -0
  37. package/dist/types/current/text/mediaTextTrackProvider.js +42 -0
  38. package/dist/types/current/text/parseWebVtt.d.ts +16 -2
  39. package/dist/types/current/text/parseWebVtt.d.ts.map +1 -1
  40. package/dist/types/current/text/parseWebVtt.js +176 -48
  41. package/dist/types/current/text/pickPreferredTextTrack.d.ts +2 -1
  42. package/dist/types/current/text/pickPreferredTextTrack.d.ts.map +1 -1
  43. package/dist/types/current/text/pickPreferredTextTrack.js +6 -3
  44. package/dist/types/current/track/Track.d.ts +1 -1
  45. package/dist/types/current/track/dash/createDashFactories.d.ts +21 -10
  46. package/dist/types/current/track/dash/createDashFactories.d.ts.map +1 -1
  47. package/dist/types/current/track/dash/createDashFactories.js +9 -21
  48. package/dist/types/current/track/hls/createHlsFactories.d.ts +21 -10
  49. package/dist/types/current/track/hls/createHlsFactories.d.ts.map +1 -1
  50. package/dist/types/current/track/hls/createHlsFactories.js +9 -21
  51. package/dist/types/current/track/mse/MseTrack.d.ts +1 -2
  52. package/dist/types/current/track/mse/MseTrack.d.ts.map +1 -1
  53. package/dist/types/current/track/mse/MseTrack.js +3 -7
  54. package/dist/types/current/tsconfig.tsbuildinfo +1 -1
  55. package/dist/types/current/vinyl/VinylOptions.d.ts +18 -40
  56. package/dist/types/current/vinyl/VinylOptions.d.ts.map +1 -1
  57. package/dist/types/current/vinyl/VinylOptions.js +12 -11
  58. package/dist/types/current/vinyl/VinylPlayer.d.ts +0 -6
  59. package/dist/types/current/vinyl/VinylPlayer.d.ts.map +1 -1
  60. package/dist/types/current/vinyl/VinylPlayer.js +2 -23
  61. package/dist/types/current/vinyl/createVinylFactories.d.ts +32 -18
  62. package/dist/types/current/vinyl/createVinylFactories.d.ts.map +1 -1
  63. package/dist/types/current/vinyl/createVinylFactories.js +6 -0
  64. package/dist/types/ts3.7/index.d.ts +4 -0
  65. package/dist/types/ts3.7/streaming/AudioOptions.d.ts +39 -0
  66. package/dist/types/ts3.7/streaming/createDefaultMediaTimelineTransformer.d.ts +2 -2
  67. package/dist/types/ts3.7/text/HtmlTextTrackRenderer.d.ts +60 -0
  68. package/dist/types/ts3.7/text/SidecarTextTrackController.d.ts +65 -53
  69. package/dist/types/ts3.7/text/SidecarTextTrackLoader.d.ts +5 -0
  70. package/dist/types/ts3.7/text/TextTrack.d.ts +74 -20
  71. package/dist/types/ts3.7/text/TextTrackRenderer.d.ts +24 -0
  72. package/dist/types/ts3.7/text/mediaTextTrackProvider.d.ts +34 -0
  73. package/dist/types/ts3.7/text/parseWebVtt.d.ts +16 -2
  74. package/dist/types/ts3.7/text/pickPreferredTextTrack.d.ts +2 -1
  75. package/dist/types/ts3.7/track/Track.d.ts +1 -1
  76. package/dist/types/ts3.7/track/dash/createDashFactories.d.ts +21 -10
  77. package/dist/types/ts3.7/track/hls/createHlsFactories.d.ts +21 -10
  78. package/dist/types/ts3.7/track/mse/MseTrack.d.ts +1 -2
  79. package/dist/types/ts3.7/vinyl/VinylOptions.d.ts +18 -40
  80. package/dist/types/ts3.7/vinyl/VinylPlayer.d.ts +0 -6
  81. package/dist/types/ts3.7/vinyl/createVinylFactories.d.ts +32 -18
  82. package/dist/types/ts4.1/index.d.ts +4 -0
  83. package/dist/types/ts4.1/streaming/AudioOptions.d.ts +39 -0
  84. package/dist/types/ts4.1/streaming/createDefaultMediaTimelineTransformer.d.ts +2 -2
  85. package/dist/types/ts4.1/text/HtmlTextTrackRenderer.d.ts +60 -0
  86. package/dist/types/ts4.1/text/SidecarTextTrackController.d.ts +65 -53
  87. package/dist/types/ts4.1/text/SidecarTextTrackLoader.d.ts +5 -0
  88. package/dist/types/ts4.1/text/TextTrack.d.ts +74 -20
  89. package/dist/types/ts4.1/text/TextTrackRenderer.d.ts +24 -0
  90. package/dist/types/ts4.1/text/mediaTextTrackProvider.d.ts +34 -0
  91. package/dist/types/ts4.1/text/parseWebVtt.d.ts +16 -2
  92. package/dist/types/ts4.1/text/pickPreferredTextTrack.d.ts +2 -1
  93. package/dist/types/ts4.1/track/Track.d.ts +1 -1
  94. package/dist/types/ts4.1/track/dash/createDashFactories.d.ts +21 -10
  95. package/dist/types/ts4.1/track/hls/createHlsFactories.d.ts +21 -10
  96. package/dist/types/ts4.1/track/mse/MseTrack.d.ts +1 -2
  97. package/dist/types/ts4.1/vinyl/VinylOptions.d.ts +18 -40
  98. package/dist/types/ts4.1/vinyl/VinylPlayer.d.ts +0 -6
  99. package/dist/types/ts4.1/vinyl/createVinylFactories.d.ts +32 -18
  100. package/dist/types/ts4.7/index.d.ts +4 -0
  101. package/dist/types/ts4.7/streaming/AudioOptions.d.ts +39 -0
  102. package/dist/types/ts4.7/streaming/createDefaultMediaTimelineTransformer.d.ts +2 -2
  103. package/dist/types/ts4.7/text/HtmlTextTrackRenderer.d.ts +60 -0
  104. package/dist/types/ts4.7/text/SidecarTextTrackController.d.ts +65 -53
  105. package/dist/types/ts4.7/text/SidecarTextTrackLoader.d.ts +5 -0
  106. package/dist/types/ts4.7/text/TextTrack.d.ts +74 -20
  107. package/dist/types/ts4.7/text/TextTrackRenderer.d.ts +24 -0
  108. package/dist/types/ts4.7/text/mediaTextTrackProvider.d.ts +34 -0
  109. package/dist/types/ts4.7/text/parseWebVtt.d.ts +16 -2
  110. package/dist/types/ts4.7/text/pickPreferredTextTrack.d.ts +2 -1
  111. package/dist/types/ts4.7/track/Track.d.ts +1 -1
  112. package/dist/types/ts4.7/track/dash/createDashFactories.d.ts +21 -10
  113. package/dist/types/ts4.7/track/hls/createHlsFactories.d.ts +21 -10
  114. package/dist/types/ts4.7/track/mse/MseTrack.d.ts +1 -2
  115. package/dist/types/ts4.7/vinyl/VinylOptions.d.ts +18 -40
  116. package/dist/types/ts4.7/vinyl/VinylPlayer.d.ts +0 -6
  117. package/dist/types/ts4.7/vinyl/createVinylFactories.d.ts +32 -18
  118. package/dist/unit/types/current/index.d.ts +2 -0
  119. package/dist/unit/types/current/index.d.ts.map +1 -1
  120. package/dist/unit/types/current/index.js +2 -0
  121. package/dist/unit/types/current/streaming/MseTrack.test.js +13 -7
  122. package/dist/unit/types/current/streaming/createDefaultMediaTimelineTransformer.test.js +8 -4
  123. package/dist/unit/types/current/text/HtmlTextTrackRenderer.test.d.ts +2 -0
  124. package/dist/unit/types/current/text/HtmlTextTrackRenderer.test.d.ts.map +1 -0
  125. package/dist/unit/types/current/text/HtmlTextTrackRenderer.test.js +231 -0
  126. package/dist/unit/types/current/text/SidecarTextTrackController.test.js +432 -333
  127. package/dist/unit/types/current/text/SidecarTextTrackLoader.test.js +29 -0
  128. package/dist/unit/types/current/text/mediaTextTrackProvider.test.d.ts +2 -0
  129. package/dist/unit/types/current/text/mediaTextTrackProvider.test.d.ts.map +1 -0
  130. package/dist/unit/types/current/text/mediaTextTrackProvider.test.js +86 -0
  131. package/dist/unit/types/current/text/parseWebVtt.test.js +187 -6
  132. package/dist/unit/types/current/text/pickPreferredTextTrack.test.js +12 -1
  133. package/dist/unit/types/current/track/dash/createDashFactories.test.js +1 -2
  134. package/dist/unit/types/current/track/hls/buildHlsMediaTimeline.test.js +1 -2
  135. package/dist/unit/types/current/track/hls/createHlsFactories.test.js +1 -2
  136. package/dist/unit/types/current/tsconfig.tsbuildinfo +1 -1
  137. package/dist/unit/types/current/vinyl/VinylPlayerTextTracks.test.js +102 -177
  138. package/dist/unit/types/current/vinyl/createVinylFactories.test.js +2 -0
  139. package/dist/vinylTestUtil/index.js +14 -8
  140. package/dist/vinylTestUtil/index.js.map +2 -2
  141. package/dist/vinylTestUtil/types/current/mock/player/MockVinylPlayerDependencies.d.ts +3 -2
  142. package/dist/vinylTestUtil/types/current/mock/player/MockVinylPlayerDependencies.d.ts.map +1 -1
  143. package/dist/vinylTestUtil/types/current/mock/player/MockVinylPlayerDependencies.js +5 -2
  144. package/dist/vinylTestUtil/types/current/mock/text/MockTextTrackController.d.ts +3 -3
  145. package/dist/vinylTestUtil/types/current/mock/text/MockTextTrackController.d.ts.map +1 -1
  146. package/dist/vinylTestUtil/types/current/mock/text/MockTextTrackController.js +3 -3
  147. package/dist/vinylTestUtil/types/current/mock/track/dash/createMockDashDependencies.d.ts +1 -2
  148. package/dist/vinylTestUtil/types/current/mock/track/dash/createMockDashDependencies.d.ts.map +1 -1
  149. package/dist/vinylTestUtil/types/current/mock/track/dash/createMockDashDependencies.js +3 -2
  150. package/dist/vinylTestUtil/types/current/mock/track/hls/createMockHlsDependencies.d.ts +1 -2
  151. package/dist/vinylTestUtil/types/current/mock/track/hls/createMockHlsDependencies.d.ts.map +1 -1
  152. package/dist/vinylTestUtil/types/current/mock/track/hls/createMockHlsDependencies.js +3 -2
  153. package/dist/vinylTestUtil/types/current/tsconfig.tsbuildinfo +1 -1
  154. package/dist/vinylTestUtil/types/ts3.7/mock/player/MockVinylPlayerDependencies.d.ts +3 -2
  155. package/dist/vinylTestUtil/types/ts3.7/mock/text/MockTextTrackController.d.ts +3 -3
  156. package/dist/vinylTestUtil/types/ts3.7/mock/track/dash/createMockDashDependencies.d.ts +1 -2
  157. package/dist/vinylTestUtil/types/ts3.7/mock/track/hls/createMockHlsDependencies.d.ts +1 -2
  158. package/dist/vinylTestUtil/types/ts4.1/mock/player/MockVinylPlayerDependencies.d.ts +3 -2
  159. package/dist/vinylTestUtil/types/ts4.1/mock/text/MockTextTrackController.d.ts +3 -3
  160. package/dist/vinylTestUtil/types/ts4.1/mock/track/dash/createMockDashDependencies.d.ts +1 -2
  161. package/dist/vinylTestUtil/types/ts4.1/mock/track/hls/createMockHlsDependencies.d.ts +1 -2
  162. package/dist/vinylTestUtil/types/ts4.7/mock/player/MockVinylPlayerDependencies.d.ts +3 -2
  163. package/dist/vinylTestUtil/types/ts4.7/mock/text/MockTextTrackController.d.ts +3 -3
  164. package/dist/vinylTestUtil/types/ts4.7/mock/track/dash/createMockDashDependencies.d.ts +1 -2
  165. package/dist/vinylTestUtil/types/ts4.7/mock/track/hls/createMockHlsDependencies.d.ts +1 -2
  166. package/docs/USAGE.md +82 -31
  167. package/package.json +12 -12
package/dist/index.js CHANGED
@@ -2565,7 +2565,7 @@ function configureVinylGlobal(options) {
2565
2565
  import { parseVersion } from "@amazon/vinyl-util";
2566
2566
  var vinylVersion = /* @__PURE__ */ parseVersion(
2567
2567
  /* istanbul ignore next */
2568
- "2.0.0"
2568
+ "3.0.0"
2569
2569
  );
2570
2570
 
2571
2571
  // src/global/globalRef.ts
@@ -3936,6 +3936,19 @@ var QualitySelectorImpl = class {
3936
3936
  }
3937
3937
  };
3938
3938
 
3939
+ // src/streaming/AudioOptions.ts
3940
+ import { array, boolean as boolean3, object as object7, string as string4 } from "@amazon/vinyl-validation";
3941
+ var defaultAudioOptions = {
3942
+ selection: { language: null, descriptive: false }
3943
+ };
3944
+ var audioSelectionValidator = /* @__PURE__ */ object7({
3945
+ language: /* @__PURE__ */ string4().or(/* @__PURE__ */ array(/* @__PURE__ */ string4()).readonly()).orNull().optional(),
3946
+ descriptive: /* @__PURE__ */ boolean3().optional()
3947
+ });
3948
+ var audioOptionsValidator = /* @__PURE__ */ object7({
3949
+ selection: /* @__PURE__ */ audioSelectionValidator.optional()
3950
+ });
3951
+
3939
3952
  // src/streaming/buffering/BufferingController.ts
3940
3953
  import {
3941
3954
  createAbortSlot,
@@ -5298,22 +5311,22 @@ function createLanguageFilter(preferredLanguage, contentType2) {
5298
5311
  return best;
5299
5312
  };
5300
5313
  const bestScoreForPeriod = memoize5(
5301
- (array4) => {
5314
+ (array6) => {
5302
5315
  let best = 0;
5303
- for (const quality of Array.from(array4)) {
5316
+ for (const quality of Array.from(array6)) {
5304
5317
  if (quality.contentType === contentType2 && quality.lang) {
5305
5318
  best = Math.max(best, scoreLang(quality.lang));
5306
5319
  }
5307
5320
  }
5308
5321
  return best;
5309
5322
  },
5310
- (array4) => array4,
5323
+ (array6) => array6,
5311
5324
  1
5312
5325
  );
5313
- return (quality, _index, array4) => {
5326
+ return (quality, _index, array6) => {
5314
5327
  if (quality.contentType !== contentType2) return true;
5315
5328
  if (!quality.lang) return true;
5316
- const best = bestScoreForPeriod(array4);
5329
+ const best = bestScoreForPeriod(array6);
5317
5330
  if (best === 0) return true;
5318
5331
  return scoreLang(quality.lang) === best;
5319
5332
  };
@@ -5377,22 +5390,22 @@ function isAudioDescription(quality) {
5377
5390
  }
5378
5391
  function createAudioDescriptionFilter(preferDescription) {
5379
5392
  const periodFlags = memoize7(
5380
- (array4) => {
5393
+ (array6) => {
5381
5394
  let hasDescription = false;
5382
5395
  let hasMain = false;
5383
- for (const quality of Array.from(array4)) {
5396
+ for (const quality of Array.from(array6)) {
5384
5397
  if (quality.contentType !== "audio") continue;
5385
5398
  if (isAudioDescription(quality)) hasDescription = true;
5386
5399
  else hasMain = true;
5387
5400
  }
5388
5401
  return { hasDescription, hasMain };
5389
5402
  },
5390
- (array4) => array4,
5403
+ (array6) => array6,
5391
5404
  1
5392
5405
  );
5393
- return (quality, _index, array4) => {
5406
+ return (quality, _index, array6) => {
5394
5407
  if (quality.contentType !== "audio") return true;
5395
- const { hasDescription, hasMain } = periodFlags(array4);
5408
+ const { hasDescription, hasMain } = periodFlags(array6);
5396
5409
  if (preferDescription) {
5397
5410
  if (!hasDescription) return true;
5398
5411
  return isAudioDescription(quality);
@@ -5438,7 +5451,7 @@ import {
5438
5451
  function throwSamplingRatesUnsupported() {
5439
5452
  throw new MediaUnsupportedError6("No supported sample rate", "sampling-rate");
5440
5453
  }
5441
- function supportsAudioSamplingRate(deps, metadata, _index, array4) {
5454
+ function supportsAudioSamplingRate(deps, metadata, _index, array6) {
5442
5455
  const isFirefox = hasBrowser4(Browser4.FIREFOX);
5443
5456
  const maxSampleRate = deps.capabilities.sampleRate;
5444
5457
  const samplingRate = last(metadata.audioSamplingRate);
@@ -5447,13 +5460,13 @@ function supportsAudioSamplingRate(deps, metadata, _index, array4) {
5447
5460
  return samplingRate <= 48e3;
5448
5461
  }
5449
5462
  if (samplingRate <= maxSampleRate) return true;
5450
- const allAboveMax = every(array4, (item) => {
5463
+ const allAboveMax = every(array6, (item) => {
5451
5464
  const itemSamplingRate = last(item.audioSamplingRate);
5452
5465
  return itemSamplingRate != null && itemSamplingRate > maxSampleRate;
5453
5466
  });
5454
5467
  if (allAboveMax) {
5455
5468
  const samplingRates = map2(
5456
- array4,
5469
+ array6,
5457
5470
  (item) => last(item.audioSamplingRate)
5458
5471
  ).filter((rate) => rate != null);
5459
5472
  const lowestSamplingRate = min(samplingRates);
@@ -5495,7 +5508,7 @@ function createDefaultMediaTimelineTransformer(deps) {
5495
5508
  return canPlayMimeType(deps, quality);
5496
5509
  }
5497
5510
  async function transformTimeline(timeline) {
5498
- var _a;
5511
+ var _a, _b;
5499
5512
  const codecOverrides = deps.options.value.codecOverrides;
5500
5513
  let t = filterTimelineQualities(
5501
5514
  (quality) => canPlayWithOverrides(quality, codecOverrides),
@@ -5508,22 +5521,18 @@ function createDefaultMediaTimelineTransformer(deps) {
5508
5521
  t
5509
5522
  );
5510
5523
  t = filterTimelineQualities(
5511
- (quality, index, array4) => supportsAudioSamplingRate(deps, quality, index, array4),
5524
+ (quality, index, array6) => supportsAudioSamplingRate(deps, quality, index, array6),
5512
5525
  throwSamplingRatesUnsupported,
5513
5526
  t
5514
5527
  );
5528
+ const selection = deps.options.value.audio.selection;
5515
5529
  t = filterTimelineQualities(
5516
- createAudioDescriptionFilter(
5517
- (_a = deps.options.value.preferDescriptiveAudio) != null ? _a : false
5518
- ),
5530
+ createAudioDescriptionFilter((_a = selection == null ? void 0 : selection.descriptive) != null ? _a : false),
5519
5531
  throwNoPlayableAudio,
5520
5532
  t
5521
5533
  );
5522
5534
  t = filterTimelineQualities(
5523
- createLanguageFilter(
5524
- deps.options.value.preferredAudioLanguage,
5525
- "audio"
5526
- ),
5535
+ createLanguageFilter((_b = selection == null ? void 0 : selection.language) != null ? _b : null, "audio"),
5527
5536
  throwLanguagesUnsupported,
5528
5537
  t
5529
5538
  );
@@ -5531,8 +5540,7 @@ function createDefaultMediaTimelineTransformer(deps) {
5531
5540
  }
5532
5541
  return combineData2({
5533
5542
  timeline: deps.mediaTimeline,
5534
- preferredAudioLanguage: deps.options.pick("preferredAudioLanguage"),
5535
- preferDescriptiveAudio: deps.options.pick("preferDescriptiveAudio"),
5543
+ audio: deps.options.pick("audio"),
5536
5544
  codecOverrides: deps.options.pick("codecOverrides")
5537
5545
  }).map(async ({ timeline }) => {
5538
5546
  return transformTimeline(await timeline);
@@ -5541,10 +5549,10 @@ function createDefaultMediaTimelineTransformer(deps) {
5541
5549
 
5542
5550
  // src/streaming/DescriptorRecord.ts
5543
5551
  import {
5544
- array,
5545
- object as object7,
5552
+ array as array2,
5553
+ object as object8,
5546
5554
  record as record2,
5547
- string as string4
5555
+ string as string5
5548
5556
  } from "@amazon/vinyl-validation";
5549
5557
  import { first } from "@amazon/vinyl-util";
5550
5558
  function getDescriptorValue(record4, uri, id) {
@@ -5554,11 +5562,11 @@ function getDescriptorValue(record4, uri, id) {
5554
5562
  if (id !== void 0) arr = arr.filter((descriptor) => descriptor.id === id);
5555
5563
  return (_b = (_a = first(arr)) == null ? void 0 : _a.value) != null ? _b : null;
5556
5564
  }
5557
- var descriptorValidator = /* @__PURE__ */ object7({
5558
- id: /* @__PURE__ */ string4().maybe().optional(),
5559
- value: /* @__PURE__ */ string4().maybe().optional()
5565
+ var descriptorValidator = /* @__PURE__ */ object8({
5566
+ id: /* @__PURE__ */ string5().maybe().optional(),
5567
+ value: /* @__PURE__ */ string5().maybe().optional()
5560
5568
  });
5561
- var descriptorRecordValidator = /* @__PURE__ */ record2(/* @__PURE__ */ string4(), /* @__PURE__ */ array(descriptorValidator).readonly().orUndefined());
5569
+ var descriptorRecordValidator = /* @__PURE__ */ record2(/* @__PURE__ */ string5(), /* @__PURE__ */ array2(descriptorValidator).readonly().orUndefined());
5562
5570
 
5563
5571
  // src/streaming/ManifestControllerImpl.ts
5564
5572
  import { data } from "@amazon/vinyl-observable";
@@ -5671,12 +5679,12 @@ import {
5671
5679
  createShortUid
5672
5680
  } from "@amazon/vinyl-util";
5673
5681
  import {
5674
- array as array2,
5682
+ array as array3,
5675
5683
  enumOf as enumOf3,
5676
5684
  isOneOf as isOneOf3,
5677
5685
  number as number5,
5678
- object as object8,
5679
- string as string5,
5686
+ object as object9,
5687
+ string as string6,
5680
5688
  tuple
5681
5689
  } from "@amazon/vinyl-validation";
5682
5690
  var ALL_CONTENT_TYPES = [
@@ -5690,15 +5698,15 @@ var RESTRICTABLE_CONTENT_TYPES = [
5690
5698
  ];
5691
5699
  var drmProtectionValidator = /* @__PURE__ */ descriptorValidator.extend({
5692
5700
  keySystem: /* @__PURE__ */ enumOf3(DrmKeySystem),
5693
- pro: /* @__PURE__ */ string5().maybe().optional(),
5694
- pssh: /* @__PURE__ */ string5().maybe().optional()
5701
+ pro: /* @__PURE__ */ string6().maybe().optional(),
5702
+ pssh: /* @__PURE__ */ string6().maybe().optional()
5695
5703
  });
5696
- var mediaFormatMetadataValidator = /* @__PURE__ */ object8({
5697
- contentProtections: /* @__PURE__ */ array2(drmProtectionValidator).readonly(),
5704
+ var mediaFormatMetadataValidator = /* @__PURE__ */ object9({
5705
+ contentProtections: /* @__PURE__ */ array3(drmProtectionValidator).readonly(),
5698
5706
  contentType: /* @__PURE__ */ isOneOf3("audio", "video", "text").orNull(),
5699
- initDataType: /* @__PURE__ */ string5().orNull(),
5700
- encryptionScheme: /* @__PURE__ */ string5().orNull(),
5701
- mimeType: /* @__PURE__ */ string5().orNull()
5707
+ initDataType: /* @__PURE__ */ string6().orNull(),
5708
+ encryptionScheme: /* @__PURE__ */ string6().orNull(),
5709
+ mimeType: /* @__PURE__ */ string6().orNull()
5702
5710
  });
5703
5711
  function createEmptyMediaFormatMetadata() {
5704
5712
  return {
@@ -5728,20 +5736,20 @@ function createEmptyMediaQualityMetadata() {
5728
5736
  });
5729
5737
  }
5730
5738
  var mediaQualityMetadataValidator = /* @__PURE__ */ mediaFormatMetadataValidator.extend({
5731
- audioSamplingRate: /* @__PURE__ */ array2(/* @__PURE__ */ number5()).readonly().orNull(),
5739
+ audioSamplingRate: /* @__PURE__ */ array3(/* @__PURE__ */ number5()).readonly().orNull(),
5732
5740
  bandwidth: /* @__PURE__ */ number5().orNull(),
5733
5741
  bandwidthTotal: /* @__PURE__ */ number5().orNull(),
5734
- codecs: /* @__PURE__ */ string5().orNull(),
5735
- decoderId: /* @__PURE__ */ string5(),
5742
+ codecs: /* @__PURE__ */ string6().orNull(),
5743
+ decoderId: /* @__PURE__ */ string6(),
5736
5744
  frameRate: /* @__PURE__ */ tuple(/* @__PURE__ */ number5(), /* @__PURE__ */ number5()).readonly().orNull(),
5737
5745
  height: /* @__PURE__ */ number5().orNull(),
5738
- qualityId: /* @__PURE__ */ string5(),
5746
+ qualityId: /* @__PURE__ */ string6(),
5739
5747
  supplementalProperties: descriptorRecordValidator,
5740
5748
  width: /* @__PURE__ */ number5().orNull(),
5741
- lang: /* @__PURE__ */ string5().orNull(),
5742
- characteristics: /* @__PURE__ */ array2(/* @__PURE__ */ string5()).readonly(),
5743
- groupId: /* @__PURE__ */ string5(),
5744
- switchingGroupIds: /* @__PURE__ */ array2(/* @__PURE__ */ string5()).readonly().orNull()
5749
+ lang: /* @__PURE__ */ string6().orNull(),
5750
+ characteristics: /* @__PURE__ */ array3(/* @__PURE__ */ string6()).readonly(),
5751
+ groupId: /* @__PURE__ */ string6(),
5752
+ switchingGroupIds: /* @__PURE__ */ array3(/* @__PURE__ */ string6()).readonly().orNull()
5745
5753
  });
5746
5754
 
5747
5755
  // src/streaming/MediaTimeline.ts
@@ -6545,10 +6553,202 @@ function discoverHlsTextTracks(mainPlaylist, baseUrl) {
6545
6553
  return out;
6546
6554
  }
6547
6555
 
6556
+ // src/text/HtmlTextTrackRenderer.ts
6557
+ var ROW_EM = 1.5;
6558
+ function computeCueLayout(cue) {
6559
+ const style = {};
6560
+ style.textAlign = cue.align || "center";
6561
+ if (cue.vertical === "rl") style.writingMode = "vertical-rl";
6562
+ else if (cue.vertical === "lr") style.writingMode = "vertical-lr";
6563
+ const size = typeof cue.size === "number" ? cue.size : 100;
6564
+ style.maxWidth = `${size}%`;
6565
+ const line = typeof cue.line === "number" ? cue.line : null;
6566
+ const position = typeof cue.position === "number" ? cue.position : null;
6567
+ if (line == null && position == null) return style;
6568
+ style.position = "absolute";
6569
+ const transforms = [];
6570
+ if (position == null) {
6571
+ style.left = "50%";
6572
+ transforms.push("translateX(-50%)");
6573
+ } else {
6574
+ if (cue.positionAlign === "line-right") {
6575
+ style.right = `${100 - position}%`;
6576
+ } else if (cue.positionAlign === "line-left") {
6577
+ style.left = `${position}%`;
6578
+ } else {
6579
+ style.left = `${position}%`;
6580
+ transforms.push("translateX(-50%)");
6581
+ }
6582
+ }
6583
+ if (line == null) {
6584
+ style.bottom = "0";
6585
+ } else {
6586
+ if (cue.snapToLines === false) {
6587
+ if (cue.lineAlign === "end") {
6588
+ style.bottom = `${100 - line}%`;
6589
+ } else if (cue.lineAlign === "center") {
6590
+ style.top = `${line}%`;
6591
+ transforms.push("translateY(-50%)");
6592
+ } else {
6593
+ style.top = `${line}%`;
6594
+ }
6595
+ } else if (line < 0) {
6596
+ style.bottom = `${(-line - 1) * ROW_EM}em`;
6597
+ } else {
6598
+ style.top = `${line * ROW_EM}em`;
6599
+ }
6600
+ }
6601
+ if (transforms.length > 0) style.transform = transforms.join(" ");
6602
+ return style;
6603
+ }
6604
+ var HTML_ESCAPE = {
6605
+ "&": "&amp;",
6606
+ "<": "&lt;",
6607
+ ">": "&gt;",
6608
+ '"': "&quot;"
6609
+ };
6610
+ function escapeHtml(text) {
6611
+ return text.replace(/["&<>]/g, (ch) => HTML_ESCAPE[ch]);
6612
+ }
6613
+ var PASSTHROUGH_TAGS = /* @__PURE__ */ new Set(["i", "b", "u", "ruby", "rt"]);
6614
+ var SPAN_TAGS = /* @__PURE__ */ new Set(["c", "v", "lang"]);
6615
+ function openTag(inner) {
6616
+ if (/^\d/.test(inner)) return "";
6617
+ const head = inner.split(/\s/, 1)[0];
6618
+ const [name, ...classes] = head.split(".");
6619
+ const annotation = inner.slice(head.length).trim();
6620
+ const classAttr = classes.filter(Boolean).length ? ` class="${escapeHtml(classes.filter(Boolean).join(" "))}"` : "";
6621
+ if (PASSTHROUGH_TAGS.has(name)) return `<${name}${classAttr}>`;
6622
+ if (name === "v") {
6623
+ const title = annotation ? ` title="${escapeHtml(annotation)}"` : "";
6624
+ return `<span${classAttr}${title}>`;
6625
+ }
6626
+ if (name === "lang") {
6627
+ const lang = annotation ? ` lang="${escapeHtml(annotation)}"` : "";
6628
+ return `<span${classAttr}${lang}>`;
6629
+ }
6630
+ if (name === "c") return `<span${classAttr}>`;
6631
+ return "";
6632
+ }
6633
+ function closeTag(name) {
6634
+ if (PASSTHROUGH_TAGS.has(name)) return `</${name}>`;
6635
+ if (SPAN_TAGS.has(name)) return "</span>";
6636
+ return "";
6637
+ }
6638
+ function renderCueText(text) {
6639
+ var _a;
6640
+ let html = "";
6641
+ for (const token of (_a = text.match(/<[^<>]*>|[^<]+|</g)) != null ? _a : []) {
6642
+ if (token[0] !== "<" || token === "<") {
6643
+ html += escapeHtml(token).replace(/\n/g, "<br>");
6644
+ } else {
6645
+ const inner = token.slice(1, -1);
6646
+ html += inner[0] === "/" ? closeTag(
6647
+ inner.slice(1).split(/[.\s]/, 1)[0].toLowerCase()
6648
+ ) : openTag(inner);
6649
+ }
6650
+ }
6651
+ return html;
6652
+ }
6653
+ function scopeCueRules(css) {
6654
+ return css.replace(/::cue\(([^)]*)\)/g, ".vinyl-text-cue $1").replace(/::cue\b/g, ".vinyl-text-cue");
6655
+ }
6656
+ var HtmlTextTrackRenderer = class {
6657
+ constructor() {
6658
+ /** The overlay container to mount over the video. */
6659
+ __publicField(this, "element");
6660
+ __publicField(this, "track", null);
6661
+ // Holds the authored STYLE-block CSS (::cue rules rewritten to target our
6662
+ // cue elements). A <style> renders nothing itself, so it lives in-container.
6663
+ __publicField(this, "styleElement");
6664
+ __publicField(this, "onCueChange", () => this.renderActiveCues());
6665
+ this.element = document.createElement("div");
6666
+ this.element.className = "vinyl-text-container";
6667
+ Object.assign(this.element.style, {
6668
+ display: "flex",
6669
+ flexDirection: "column",
6670
+ justifyContent: "flex-end",
6671
+ alignItems: "center",
6672
+ pointerEvents: "none"
6673
+ });
6674
+ this.styleElement = document.createElement("style");
6675
+ this.element.appendChild(this.styleElement);
6676
+ }
6677
+ setTextTrack(track) {
6678
+ var _a;
6679
+ if (track === this.track) return;
6680
+ (_a = this.track) == null ? void 0 : _a.removeEventListener("cuechange", this.onCueChange);
6681
+ this.track = track;
6682
+ this.styleElement.textContent = "";
6683
+ if (!track) {
6684
+ this.element.replaceChildren(this.styleElement);
6685
+ return;
6686
+ }
6687
+ track.addEventListener("cuechange", this.onCueChange);
6688
+ this.renderActiveCues();
6689
+ }
6690
+ setStyles(styles) {
6691
+ this.styleElement.textContent = styles.map(scopeCueRules).join("\n");
6692
+ }
6693
+ dispose() {
6694
+ this.setTextTrack(null);
6695
+ }
6696
+ renderActiveCues() {
6697
+ var _a;
6698
+ const active = (_a = this.track.activeCues) != null ? _a : [];
6699
+ const children = [this.styleElement];
6700
+ for (let i = 0; i < active.length; i++) {
6701
+ children.push(this.createCueBox(active[i]));
6702
+ }
6703
+ this.element.replaceChildren(...children);
6704
+ }
6705
+ createCueBox(cue) {
6706
+ var _a;
6707
+ const box = document.createElement("div");
6708
+ box.className = "vinyl-text-cue";
6709
+ Object.assign(box.style, computeCueLayout(cue));
6710
+ box.innerHTML = renderCueText((_a = cue.text) != null ? _a : "");
6711
+ return box;
6712
+ }
6713
+ };
6714
+
6715
+ // src/text/mediaTextTrackProvider.ts
6716
+ function createMediaTextTrackProvider(deps) {
6717
+ const { media } = deps;
6718
+ const cache = /* @__PURE__ */ new Map();
6719
+ const isAttached = (track) => {
6720
+ for (let i = 0; i < media.textTracks.length; i++) {
6721
+ if (media.textTracks[i] === track) return true;
6722
+ }
6723
+ return false;
6724
+ };
6725
+ const create = (kind, label, language) => {
6726
+ const track = media.addTextTrack(kind, label, language);
6727
+ return {
6728
+ track,
6729
+ clear() {
6730
+ if (!track.cues) return;
6731
+ const all = Array.from(track.cues);
6732
+ for (const cue of all) track.removeCue(cue);
6733
+ }
6734
+ };
6735
+ };
6736
+ return {
6737
+ getOrCreate(kind, label, language) {
6738
+ const key = `${kind}-${label}-${language}`;
6739
+ const cached = cache.get(key);
6740
+ if (cached && isAttached(cached.track)) return cached;
6741
+ const ref = create(kind, label, language);
6742
+ cache.set(key, ref);
6743
+ return ref;
6744
+ }
6745
+ };
6746
+ }
6747
+
6548
6748
  // src/text/parseWebVtt.ts
6549
6749
  import { ErrorOrigin as ErrorOrigin16, ValidationError as ValidationError3 } from "@amazon/vinyl-util";
6550
6750
  var WEBVTT_HEADER = "WEBVTT";
6551
- var TIME_RE = /^\s*(?:(\d+):)?([0-5]?\d):([0-5]?\d)\.(\d{3})\s*-->\s*(?:(\d+):)?([0-5]?\d):([0-5]?\d)\.(\d{3})(?:\s.*)?$/;
6751
+ var TIMESTAMP_RE = /^(?:(\d+):)?([0-5]\d):([0-5]\d)\.(\d{3})/;
6552
6752
  function parseWebVtt(input) {
6553
6753
  if (typeof input !== "string") {
6554
6754
  throw new ValidationError3(
@@ -6566,6 +6766,7 @@ function parseWebVtt(input) {
6566
6766
  );
6567
6767
  }
6568
6768
  const cues = [];
6769
+ const styles = [];
6569
6770
  let i = 1;
6570
6771
  while (i < lines.length && lines[i] !== "") i++;
6571
6772
  while (i < lines.length) {
@@ -6573,49 +6774,71 @@ function parseWebVtt(input) {
6573
6774
  i++;
6574
6775
  continue;
6575
6776
  }
6576
- if (lines[i] === "NOTE" || lines[i].startsWith("NOTE ")) {
6777
+ if (lines[i] === "NOTE" || lines[i].startsWith("NOTE ") || lines[i].startsWith("NOTE ") || lines[i] === "REGION") {
6577
6778
  i++;
6578
6779
  while (i < lines.length && lines[i] !== "") i++;
6579
6780
  continue;
6580
6781
  }
6581
- if (lines[i] === "STYLE" || lines[i] === "REGION") {
6782
+ if (lines[i] === "STYLE") {
6582
6783
  i++;
6784
+ const start = i;
6583
6785
  while (i < lines.length && lines[i] !== "") i++;
6786
+ const css = lines.slice(start, i).join("\n").trim();
6787
+ if (css) styles.push(css);
6584
6788
  continue;
6585
6789
  }
6586
6790
  let id = null;
6587
- let timingLine;
6588
- const firstLine = lines[i];
6589
- if (TIME_RE.test(firstLine)) {
6590
- timingLine = firstLine;
6591
- i++;
6592
- } else {
6593
- id = firstLine;
6791
+ if (!lines[i].includes("-->")) {
6792
+ id = lines[i];
6594
6793
  i++;
6595
6794
  if (i >= lines.length) break;
6596
- timingLine = lines[i];
6597
- i++;
6598
6795
  }
6599
- const match = TIME_RE.exec(timingLine);
6600
- if (!match) {
6796
+ const timing = parseTiming(lines[i]);
6797
+ i++;
6798
+ if (!timing) {
6601
6799
  while (i < lines.length && lines[i] !== "") i++;
6602
6800
  continue;
6603
6801
  }
6604
- const startTime = toSeconds(match[1], match[2], match[3], match[4]);
6605
- const endTime = toSeconds(match[5], match[6], match[7], match[8]);
6606
6802
  const payloadLines = [];
6607
6803
  while (i < lines.length && lines[i] !== "") {
6608
6804
  payloadLines.push(lines[i]);
6609
6805
  i++;
6610
6806
  }
6611
- cues.push({
6612
- id,
6613
- startTime,
6614
- endTime,
6615
- text: payloadLines.join("\n")
6616
- });
6807
+ const text2 = payloadLines.join("\n");
6808
+ cues.push(
6809
+ timing.settings === void 0 ? {
6810
+ id,
6811
+ startTime: timing.startTime,
6812
+ endTime: timing.endTime,
6813
+ text: text2
6814
+ } : {
6815
+ id,
6816
+ startTime: timing.startTime,
6817
+ endTime: timing.endTime,
6818
+ text: text2,
6819
+ settings: timing.settings
6820
+ }
6821
+ );
6617
6822
  }
6618
- return { cues };
6823
+ return { cues, styles };
6824
+ }
6825
+ function parseTiming(line) {
6826
+ const arrow = line.indexOf("-->");
6827
+ if (arrow < 0) return null;
6828
+ const before = line.slice(0, arrow).trim();
6829
+ const start = TIMESTAMP_RE.exec(before);
6830
+ if (!start || start[0].length !== before.length) return null;
6831
+ const rest = line.slice(arrow + 3).trim();
6832
+ const end = TIMESTAMP_RE.exec(rest);
6833
+ if (!end) return null;
6834
+ return {
6835
+ startTime: toSeconds(start[1], start[2], start[3], start[4]),
6836
+ endTime: toSeconds(end[1], end[2], end[3], end[4]),
6837
+ settings: parseCueSettings(rest.slice(end[0].length))
6838
+ };
6839
+ }
6840
+ function toSeconds(hours, minutes, seconds, millis) {
6841
+ return (hours ? Number(hours) * 3600 : 0) + Number(minutes) * 60 + Number(seconds) + Number(millis) / 1e3;
6619
6842
  }
6620
6843
  function isWebVttHeader(line) {
6621
6844
  if (!line.startsWith(WEBVTT_HEADER)) return false;
@@ -6623,18 +6846,80 @@ function isWebVttHeader(line) {
6623
6846
  const next = line.charCodeAt(WEBVTT_HEADER.length);
6624
6847
  return next === 32 || next === 9;
6625
6848
  }
6626
- function toSeconds(hours, minutes, seconds, millis) {
6627
- const h = hours ? Number(hours) : 0;
6628
- const m = Number(minutes);
6629
- const s = Number(seconds);
6630
- const ms = Number(millis);
6631
- return h * 3600 + m * 60 + s + ms / 1e3;
6849
+ var ALIGN = /* @__PURE__ */ new Set(["start", "center", "end", "left", "right"]);
6850
+ var LINE_ALIGN = /* @__PURE__ */ new Set(["start", "center", "end"]);
6851
+ var POSITION_ALIGN = /* @__PURE__ */ new Set(["line-left", "center", "line-right", "auto"]);
6852
+ var VERTICAL = /* @__PURE__ */ new Set(["rl", "lr"]);
6853
+ function parseCueSettings(text) {
6854
+ if (!text) return void 0;
6855
+ const settings = {};
6856
+ for (const token of text.trim().split(/\s+/)) {
6857
+ const colon = token.indexOf(":");
6858
+ if (colon <= 0) continue;
6859
+ const key = token.slice(0, colon);
6860
+ const value = token.slice(colon + 1);
6861
+ switch (key) {
6862
+ case "align": {
6863
+ const align = value === "middle" ? "center" : value;
6864
+ if (ALIGN.has(align)) settings.align = align;
6865
+ break;
6866
+ }
6867
+ case "vertical":
6868
+ if (VERTICAL.has(value))
6869
+ settings.vertical = value;
6870
+ break;
6871
+ case "size": {
6872
+ const size = parsePercent(value);
6873
+ if (size != null) settings.size = size;
6874
+ break;
6875
+ }
6876
+ case "line":
6877
+ parseLine(value, settings);
6878
+ break;
6879
+ case "position":
6880
+ parsePosition(value, settings);
6881
+ break;
6882
+ }
6883
+ }
6884
+ return Object.keys(settings).length > 0 ? settings : void 0;
6885
+ }
6886
+ function parseLine(value, settings) {
6887
+ const [pos, align] = value.split(",");
6888
+ if (pos.endsWith("%")) {
6889
+ const percent = parsePercent(pos);
6890
+ if (percent == null) return;
6891
+ settings.line = percent;
6892
+ settings.snapToLines = false;
6893
+ } else {
6894
+ const n = Number(pos);
6895
+ if (!Number.isInteger(n)) return;
6896
+ settings.line = n;
6897
+ settings.snapToLines = true;
6898
+ }
6899
+ const lineAlign = align === "middle" ? "center" : align;
6900
+ if (lineAlign && LINE_ALIGN.has(lineAlign))
6901
+ settings.lineAlign = lineAlign;
6902
+ }
6903
+ function parsePosition(value, settings) {
6904
+ const [pos, align] = value.split(",");
6905
+ const percent = parsePercent(pos);
6906
+ if (percent == null) return;
6907
+ settings.position = percent;
6908
+ const positionAlign = align === "middle" ? "center" : align;
6909
+ if (positionAlign && POSITION_ALIGN.has(positionAlign))
6910
+ settings.positionAlign = positionAlign;
6911
+ }
6912
+ function parsePercent(value) {
6913
+ if (!value.endsWith("%")) return null;
6914
+ const n = Number(value.slice(0, -1));
6915
+ return Number.isFinite(n) ? n : null;
6632
6916
  }
6633
6917
 
6634
6918
  // src/text/pickPreferredTextTrack.ts
6635
6919
  function resolvePreferredTextLanguages(preferred) {
6636
6920
  if (typeof preferred === "string") return [preferred];
6637
6921
  if (preferred) return preferred;
6922
+ if (typeof navigator !== "undefined") return [...navigator.languages];
6638
6923
  return [];
6639
6924
  }
6640
6925
  function pickPreferredTextTrack(tracks, preferred) {
@@ -6668,9 +6953,11 @@ function scoreTextTrack(track, prefs) {
6668
6953
 
6669
6954
  // src/text/SidecarTextTrackController.ts
6670
6955
  import {
6671
- Abort as Abort3,
6956
+ createAbortSlot as createAbortSlot4,
6957
+ createDisposer as createDisposer14,
6672
6958
  equalDeep,
6673
- EventHostImpl as EventHostImpl13
6959
+ EventHostImpl as EventHostImpl13,
6960
+ logError as logError4
6674
6961
  } from "@amazon/vinyl-util";
6675
6962
 
6676
6963
  // src/text/SidecarTextTrackLoader.ts
@@ -6681,7 +6968,7 @@ var DEFAULT_TEXT_LOOK_BEHIND = 2;
6681
6968
  var IDLE_POLL_SECONDS = 0.25;
6682
6969
  async function loadWebVttCues(uri, options) {
6683
6970
  var _a, _b, _c;
6684
- const { abort, requestInit, variables, onCues, getCurrentTime } = options;
6971
+ const { abort, requestInit, variables, onCues, onStyles, getCurrentTime } = options;
6685
6972
  const lookAhead = (_a = options.lookAhead) != null ? _a : DEFAULT_TEXT_LOOK_AHEAD;
6686
6973
  const lookBehind = (_b = options.lookBehind) != null ? _b : DEFAULT_TEXT_LOOK_BEHIND;
6687
6974
  const init = requestInit != null ? requestInit : void 0;
@@ -6692,6 +6979,7 @@ async function loadWebVttCues(uri, options) {
6692
6979
  abort,
6693
6980
  variables: variables != null ? variables : void 0,
6694
6981
  onCues,
6982
+ onStyles,
6695
6983
  getCurrentTime,
6696
6984
  lookAhead,
6697
6985
  lookBehind
@@ -6708,13 +6996,15 @@ async function loadWebVttCues(uri, options) {
6708
6996
  abort,
6709
6997
  variables: variables != null ? variables : void 0,
6710
6998
  onCues,
6999
+ onStyles,
6711
7000
  getCurrentTime,
6712
7001
  lookAhead,
6713
7002
  lookBehind
6714
7003
  });
6715
7004
  }
6716
- const cues = parseWebVtt(body).cues;
6717
- if (cues.length > 0) onCues(cues);
7005
+ const doc = parseWebVtt(body);
7006
+ if (doc.cues.length > 0) onCues(doc.cues);
7007
+ if (onStyles && doc.styles.length > 0) onStyles(doc.styles);
6718
7008
  }
6719
7009
  function looksLikeMediaPlaylist(uri) {
6720
7010
  const path = uri.split(/[?#]/)[0];
@@ -6754,8 +7044,9 @@ async function streamMediaPlaylistText(ctx) {
6754
7044
  abort: ctx.abort
6755
7045
  });
6756
7046
  const body = await res.text();
6757
- const cues = parseWebVtt(body).cues;
6758
- if (cues.length > 0) ctx.onCues(cues);
7047
+ const doc = parseWebVtt(body);
7048
+ if (doc.cues.length > 0) ctx.onCues(doc.cues);
7049
+ if (ctx.onStyles && doc.styles.length > 0) ctx.onStyles(doc.styles);
6759
7050
  }
6760
7051
  }
6761
7052
  function pickInWindow(pending, ranges, ctx) {
@@ -6778,7 +7069,7 @@ function pickInWindow(pending, ranges, ctx) {
6778
7069
  }
6779
7070
 
6780
7071
  // src/text/VttCueStyle.ts
6781
- import { boolean as boolean3, isOneOf as isOneOf4, number as number6, object as object9 } from "@amazon/vinyl-validation";
7072
+ import { boolean as boolean4, isOneOf as isOneOf4, number as number6, object as object10 } from "@amazon/vinyl-validation";
6782
7073
  function isVttCue(cue) {
6783
7074
  return typeof VTTCue !== "undefined" && cue instanceof VTTCue;
6784
7075
  }
@@ -6793,7 +7084,7 @@ function applyVttCueStyle(cue, style) {
6793
7084
  if (style.snapToLines !== void 0) cue.snapToLines = style.snapToLines;
6794
7085
  if (style.vertical !== void 0) cue.vertical = style.vertical;
6795
7086
  }
6796
- var vttCueStyleValidator = /* @__PURE__ */ object9({
7087
+ var vttCueStyleValidator = /* @__PURE__ */ object10({
6797
7088
  align: /* @__PURE__ */ isOneOf4("start", "center", "end", "left", "right").optional(),
6798
7089
  line: /* @__PURE__ */ number6().or(/* @__PURE__ */ isOneOf4("auto")).optional(),
6799
7090
  lineAlign: /* @__PURE__ */ isOneOf4("start", "center", "end").optional(),
@@ -6805,27 +7096,50 @@ var vttCueStyleValidator = /* @__PURE__ */ object9({
6805
7096
  "auto"
6806
7097
  ).optional(),
6807
7098
  size: /* @__PURE__ */ number6().optional(),
6808
- snapToLines: /* @__PURE__ */ boolean3().optional(),
7099
+ snapToLines: /* @__PURE__ */ boolean4().optional(),
6809
7100
  vertical: /* @__PURE__ */ isOneOf4("", "rl", "lr").optional()
6810
7101
  });
6811
7102
 
6812
7103
  // src/text/SidecarTextTrackController.ts
7104
+ function resolveSelectedTrack(tracks, options) {
7105
+ var _a, _b, _c, _d;
7106
+ const mode = (_a = options.enabled) != null ? _a : "forced";
7107
+ if (mode === "off") return null;
7108
+ const selection = (_b = options.selection) != null ? _b : {};
7109
+ if (selection.id != null) {
7110
+ return (_c = tracks.find((t) => t.id === selection.id)) != null ? _c : null;
7111
+ }
7112
+ let pool = tracks;
7113
+ if (selection.kind != null) {
7114
+ pool = pool.filter((t) => t.kind === selection.kind);
7115
+ }
7116
+ const forced = (_d = selection.forced) != null ? _d : mode === "forced";
7117
+ pool = pool.filter((t) => t.forced === forced);
7118
+ return pickPreferredTextTrack(pool, selection.language);
7119
+ }
6813
7120
  var SidecarTextTrackController = class extends EventHostImpl13 {
6814
7121
  constructor(deps) {
6815
- var _a, _b;
6816
7122
  super();
6817
7123
  __publicField(this, "deps", deps);
7124
+ // Whether the owning media track is current (rendering allowed). Toggled by
7125
+ // activate()/deactivate() across suspensions such as ad breaks.
7126
+ __publicField(this, "_active", false);
6818
7127
  __publicField(this, "_tracks", []);
6819
- __publicField(this, "_active", null);
6820
- __publicField(this, "_domTrack", null);
6821
- __publicField(this, "loadAbort", null);
6822
- // True once the app has made an explicit selection (including null). Until
6823
- // then, forced tracks auto-select on discovery.
6824
- __publicField(this, "_userSelected", false);
6825
- __publicField(this, "preferredLanguageSub");
6826
- this.preferredLanguageSub = (_b = (_a = deps.preferredTextLanguage) == null ? void 0 : _a.onData((value, previous) => {
6827
- if (previous !== void 0) this.applyPreferredLanguage(value);
6828
- })) != null ? _b : null;
7128
+ __publicField(this, "_activeTextTrack", null);
7129
+ // The DOM text track currently rendering cues, or null when hidden. Owned by
7130
+ // the provider (never created/removed here).
7131
+ __publicField(this, "_ref", null);
7132
+ __publicField(this, "loadAbort", /* @__PURE__ */ createAbortSlot4());
7133
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer14());
7134
+ const { add } = this.disposer;
7135
+ add(deps.options.onData(() => this.refreshSelection()));
7136
+ add(
7137
+ deps.textTracks.onData((tracksPromise) => {
7138
+ tracksPromise.then((tracks) => this.setTracks(tracks)).catch((error) => {
7139
+ logError4(this, "text tracks promise rejected", error);
7140
+ });
7141
+ })
7142
+ );
6829
7143
  }
6830
7144
  get [Symbol.toStringTag]() {
6831
7145
  return "SidecarTextTrackController";
@@ -6834,120 +7148,89 @@ var SidecarTextTrackController = class extends EventHostImpl13 {
6834
7148
  return this._tracks;
6835
7149
  }
6836
7150
  get activeTextTrack() {
7151
+ return this._activeTextTrack;
7152
+ }
7153
+ get active() {
6837
7154
  return this._active;
6838
7155
  }
7156
+ get disposed() {
7157
+ return this.disposer.disposed;
7158
+ }
6839
7159
  /**
6840
- * Replaces the discovered text track list. Emits `textTracksChange`. If
6841
- * the previously active track is no longer present, clears the active
6842
- * selection and emits `activeTextTrackChange`.
7160
+ * Replaces the discovered track list, emits `textTracksChange`, then
7161
+ * re-applies the current selection against the new list.
6843
7162
  */
6844
- setTextTracks(tracks) {
6845
- var _a;
6846
- if (equalDeep(this._tracks, tracks)) return;
7163
+ setTracks(tracks) {
7164
+ if (this.disposed) return;
6847
7165
  const previous = this._tracks;
7166
+ if (equalDeep(previous, tracks)) return;
6848
7167
  this._tracks = tracks;
6849
7168
  this.dispatch("textTracksChange", { previous, current: tracks });
6850
- if (this._active && !tracks.some((t) => t.id === this._active.id)) {
6851
- this.selectById(null);
6852
- }
6853
- const preferred = (_a = this.deps.preferredTextLanguage) == null ? void 0 : _a.value;
6854
- if (preferred != null) {
6855
- this.applyPreferredLanguage(preferred);
6856
- } else if (!this._userSelected && !this._active) {
6857
- const forced = this.pickForcedTrack(tracks);
6858
- if (forced) this.selectById(forced.id);
6859
- }
6860
- }
6861
- setActiveTextTrack(id) {
6862
- this._userSelected = true;
6863
- this.selectById(id);
6864
- }
6865
- /**
6866
- * Selects the track best matching the preferred language(s), or clears the
6867
- * selection when the preference is null or nothing matches.
6868
- */
6869
- applyPreferredLanguage(preferred) {
6870
- var _a;
6871
- const target = pickPreferredTextTrack(this._tracks, preferred);
6872
- this.setActiveTextTrack((_a = target == null ? void 0 : target.id) != null ? _a : null);
6873
- }
6874
- /**
6875
- * Applies a selection by id (null clears it) without marking it as an
6876
- * explicit user choice. Shared by setActiveTextTrack and forced auto-select.
6877
- */
6878
- selectById(id) {
6879
- var _a, _b;
6880
- const next = id == null ? null : this._tracks.find((t) => t.id === id);
6881
- if (id != null && !next) return;
6882
- const target = next != null ? next : null;
6883
- if ((target == null ? void 0 : target.id) === ((_a = this._active) == null ? void 0 : _a.id)) return;
6884
- const previous = this._active;
6885
- this.clearDomTrack();
6886
- (_b = this.loadAbort) == null ? void 0 : _b.abort();
6887
- this.loadAbort = null;
6888
- this._active = target;
6889
- this.dispatch("activeTextTrackChange", {
6890
- previous,
6891
- current: target
6892
- });
6893
- if (target) this.startLoad(target);
7169
+ this.refreshSelection();
6894
7170
  }
6895
7171
  /**
6896
- * The forced track to auto-select, or null. Prefers the default track's
6897
- * language, else the first forced track.
7172
+ * Recomputes the selection from the current options and track list,
7173
+ * emitting `activeTextTrackChange` on change and (re)rendering when active.
6898
7174
  */
6899
- pickForcedTrack(tracks) {
6900
- var _a;
6901
- const forced = tracks.filter((t) => t.forced);
6902
- if (forced.length === 0) return null;
6903
- const defaultLang = (_a = tracks.find((t) => t.default)) == null ? void 0 : _a.language;
6904
- if (defaultLang != null) {
6905
- const match = forced.find((t) => t.language === defaultLang);
6906
- if (match) return match;
7175
+ refreshSelection() {
7176
+ const previous = this._activeTextTrack;
7177
+ const target = resolveSelectedTrack(
7178
+ this._tracks,
7179
+ this.deps.options.value
7180
+ );
7181
+ const trackChanged = (target == null ? void 0 : target.id) !== (previous == null ? void 0 : previous.id);
7182
+ if (trackChanged) {
7183
+ this._activeTextTrack = target;
7184
+ this.dispatch("activeTextTrackChange", {
7185
+ previous,
7186
+ current: target
7187
+ });
6907
7188
  }
6908
- return forced[0];
6909
- }
6910
- suspend() {
6911
- var _a;
6912
- (_a = this.loadAbort) == null ? void 0 : _a.abort();
6913
- this.loadAbort = null;
6914
- this.clearDomTrack();
7189
+ if (!this._active) return;
7190
+ if (!target) this.hideCurrent();
7191
+ else if (trackChanged || !this._ref) this.startLoad(target);
6915
7192
  }
6916
- resume() {
6917
- if (!this._active || this._domTrack) return;
6918
- this.startLoad(this._active);
7193
+ deactivate() {
7194
+ this._active = false;
7195
+ this.hideCurrent();
6919
7196
  }
6920
- /**
6921
- * Cancels any in-flight load, clears the DOM TextTrack, and resets state.
6922
- * Called by the host when the underlying media is unloaded.
6923
- */
6924
- dispose() {
6925
- var _a, _b;
6926
- super.dispose();
6927
- (_a = this.preferredLanguageSub) == null ? void 0 : _a.call(this);
6928
- (_b = this.loadAbort) == null ? void 0 : _b.abort();
6929
- this.loadAbort = null;
6930
- this.clearDomTrack();
6931
- this._tracks = [];
6932
- this._active = null;
7197
+ activate() {
7198
+ this._active = true;
7199
+ if (!this._activeTextTrack || this._ref) return;
7200
+ this.startLoad(this._activeTextTrack);
6933
7201
  }
6934
7202
  startLoad(track) {
6935
- const media = this.deps.media;
6936
- if (!media) return;
6937
- const abort = new Abort3();
6938
- this.loadAbort = abort;
6939
- const dom = this.ensureDomTrack(media, track);
7203
+ var _a, _b;
7204
+ this.hideCurrent();
7205
+ const abort = this.loadAbort.value;
7206
+ const ref = this.deps.textTrackProvider.getOrCreate(
7207
+ track.kind,
7208
+ track.label,
7209
+ (_a = track.language) != null ? _a : void 0
7210
+ );
7211
+ const renderer = this.deps.textTrackRenderer;
7212
+ ref.track.mode = renderer ? "hidden" : "showing";
7213
+ ref.clear();
7214
+ this._ref = ref;
7215
+ renderer == null ? void 0 : renderer.setTextTrack(ref.track);
6940
7216
  const CueCtor = getVttCueConstructor();
6941
7217
  const seen = /* @__PURE__ */ new Set();
7218
+ const styles = /* @__PURE__ */ new Set();
7219
+ const setStyles = (_b = renderer == null ? void 0 : renderer.setStyles) == null ? void 0 : _b.bind(renderer);
6942
7220
  loadWebVttCues(track.uri, {
6943
7221
  abort,
6944
7222
  requestInit: this.deps.requestInit,
6945
7223
  variables: track.variables,
6946
- getCurrentTime: () => media.currentTime,
7224
+ getCurrentTime: () => this.deps.playbackController.currentTime,
6947
7225
  onCues: (cues) => {
6948
7226
  if (abort.aborted()) return;
6949
- if (CueCtor) this.appendCues(dom, CueCtor, cues, seen);
6950
- }
7227
+ if (CueCtor) this.appendCues(ref.track, CueCtor, cues, seen);
7228
+ },
7229
+ onStyles: setStyles ? (blocks) => {
7230
+ if (abort.aborted()) return;
7231
+ for (const block of blocks) styles.add(block);
7232
+ setStyles([...styles]);
7233
+ } : void 0
6951
7234
  }).catch((error) => {
6952
7235
  if (abort.aborted()) return;
6953
7236
  this.dispatch("textTrackError", {
@@ -6956,43 +7239,45 @@ var SidecarTextTrackController = class extends EventHostImpl13 {
6956
7239
  });
6957
7240
  });
6958
7241
  }
6959
- ensureDomTrack(media, track) {
6960
- var _a;
6961
- const dom = media.addTextTrack(
6962
- track.kind,
6963
- track.label,
6964
- (_a = track.language) != null ? _a : void 0
6965
- );
6966
- dom.mode = "showing";
6967
- this._domTrack = dom;
6968
- return dom;
6969
- }
6970
7242
  appendCues(dom, CueCtor, cues, seen) {
6971
- var _a;
6972
7243
  for (const cue of cues) {
6973
7244
  const key = `${cue.startTime}|${cue.endTime}|${cue.text}`;
6974
7245
  if (seen.has(key)) continue;
6975
7246
  seen.add(key);
6976
7247
  const domCue = new CueCtor(cue.startTime, cue.endTime, cue.text);
6977
7248
  if (cue.id != null) domCue.id = cue.id;
6978
- const cueStyle = (_a = this.deps.cueStyle) == null ? void 0 : _a.value;
6979
- if (cueStyle && isVttCue(domCue)) {
6980
- applyVttCueStyle(domCue, cueStyle);
7249
+ if (cue.settings && isVttCue(domCue)) {
7250
+ applyVttCueStyle(domCue, cue.settings);
6981
7251
  }
6982
7252
  dom.addCue(domCue);
6983
7253
  }
6984
7254
  }
6985
- clearDomTrack() {
6986
- const dom = this._domTrack;
6987
- if (!dom) return;
6988
- dom.mode = "disabled";
6989
- if (dom.cues) {
6990
- const all = Array.from(
6991
- dom.cues
6992
- );
6993
- for (const cue of all) dom.removeCue(cue);
6994
- }
6995
- this._domTrack = null;
7255
+ /**
7256
+ * Clears cues from the current DOM track and hides it, keeping the track for
7257
+ * later reuse via the provider.
7258
+ */
7259
+ hideCurrent() {
7260
+ var _a;
7261
+ this.loadAbort.abort();
7262
+ const ref = this._ref;
7263
+ if (!ref) return;
7264
+ (_a = this.deps.textTrackRenderer) == null ? void 0 : _a.setTextTrack(null);
7265
+ ref.clear();
7266
+ ref.track.mode = "disabled";
7267
+ this._ref = null;
7268
+ }
7269
+ /**
7270
+ * Cancels any in-flight load, hides the DOM text track, and resets state.
7271
+ * Called by the host when the underlying media is unloaded.
7272
+ */
7273
+ dispose() {
7274
+ if (this.disposed) return;
7275
+ super.dispose();
7276
+ this.loadAbort.abort();
7277
+ this.hideCurrent();
7278
+ this.disposer.dispose();
7279
+ this._tracks = [];
7280
+ this._activeTextTrack = null;
6996
7281
  }
6997
7282
  };
6998
7283
  function getVttCueConstructor() {
@@ -7002,6 +7287,30 @@ function getVttCueConstructor() {
7002
7287
  }
7003
7288
 
7004
7289
  // src/text/TextTrack.ts
7290
+ import {
7291
+ array as array4,
7292
+ boolean as boolean5,
7293
+ isOneOf as isOneOf5,
7294
+ object as object11,
7295
+ string as string7
7296
+ } from "@amazon/vinyl-validation";
7297
+ var TEXT_TRACK_KINDS = [
7298
+ "subtitles",
7299
+ "captions",
7300
+ "descriptions",
7301
+ "chapters",
7302
+ "metadata"
7303
+ ];
7304
+ var textTrackSelectionValidator = /* @__PURE__ */ object11({
7305
+ id: /* @__PURE__ */ string7().orNull().optional(),
7306
+ kind: /* @__PURE__ */ isOneOf5(...TEXT_TRACK_KINDS).orNull().optional(),
7307
+ language: /* @__PURE__ */ string7().or(/* @__PURE__ */ array4(/* @__PURE__ */ string7()).readonly()).orNull().optional(),
7308
+ forced: /* @__PURE__ */ boolean5().orNull().optional()
7309
+ });
7310
+ var textTrackControllerOptionsValidator = /* @__PURE__ */ object11({
7311
+ enabled: /* @__PURE__ */ isOneOf5("on", "off", "forced").orNull().optional(),
7312
+ selection: /* @__PURE__ */ textTrackSelectionValidator.orNull().optional()
7313
+ });
7005
7314
  var ALL_TEXT_TRACK_EVENTS = [
7006
7315
  "textTracksChange",
7007
7316
  "activeTextTrackChange",
@@ -7010,7 +7319,7 @@ var ALL_TEXT_TRACK_EVENTS = [
7010
7319
 
7011
7320
  // src/track/AutoResetController.ts
7012
7321
  import {
7013
- createDisposer as createDisposer14,
7322
+ createDisposer as createDisposer15,
7014
7323
  EventHostImpl as EventHostImpl14,
7015
7324
  getNetworkState as getNetworkState2,
7016
7325
  logDebug as logDebug13,
@@ -7030,7 +7339,7 @@ var AutoResetControllerImpl = class extends EventHostImpl14 {
7030
7339
  __publicField(this, "_error", null);
7031
7340
  __publicField(this, "watchSub", null);
7032
7341
  __publicField(this, "currentRetry", 0);
7033
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer14());
7342
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer15());
7034
7343
  logDebug13(this, "constructor");
7035
7344
  this.options = __spreadValues(__spreadValues({}, defaultResetControllerOptions), options);
7036
7345
  this.disposer.add(
@@ -7068,7 +7377,7 @@ var AutoResetControllerImpl = class extends EventHostImpl14 {
7068
7377
  this.watchSub = null;
7069
7378
  if (value) {
7070
7379
  const networkState = getNetworkState2();
7071
- const { add, dispose: watchSub } = createDisposer14();
7380
+ const { add, dispose: watchSub } = createDisposer15();
7072
7381
  this.watchSub = watchSub;
7073
7382
  add(
7074
7383
  networkState.on("online", () => {
@@ -7177,25 +7486,25 @@ import {
7177
7486
  } from "@amazon/vinyl-util";
7178
7487
  import {
7179
7488
  any as any2,
7180
- isOneOf as isOneOf5,
7489
+ isOneOf as isOneOf6,
7181
7490
  number as number7,
7182
- object as object10,
7183
- string as string6
7491
+ object as object12,
7492
+ string as string8
7184
7493
  } from "@amazon/vinyl-validation";
7185
- var trackConfigOptionsValidator = /* @__PURE__ */ object10({
7494
+ var trackConfigOptionsValidator = /* @__PURE__ */ object12({
7186
7495
  extra: /* @__PURE__ */ any2().optional(),
7187
7496
  startTime: /* @__PURE__ */ number7().maybe().optional(),
7188
7497
  drm: /* @__PURE__ */ drmOptionsValidator.partial().optional()
7189
7498
  });
7190
- var trackLoadOptionsValidator = /* @__PURE__ */ object10(
7499
+ var trackLoadOptionsValidator = /* @__PURE__ */ object12(
7191
7500
  {
7192
- type: /* @__PURE__ */ string6(),
7193
- uri: /* @__PURE__ */ string6().notEmpty(),
7501
+ type: /* @__PURE__ */ string8(),
7502
+ uri: /* @__PURE__ */ string8().notEmpty(),
7194
7503
  config: /* @__PURE__ */ trackConfigOptionsValidator.maybe().optional()
7195
7504
  }
7196
7505
  );
7197
7506
  function createTrackFactory(factories) {
7198
- const typeValidator = isOneOf5(...ownKeys2(factories));
7507
+ const typeValidator = isOneOf6(...ownKeys2(factories));
7199
7508
  return {
7200
7509
  validate(options) {
7201
7510
  typeValidator.assert(options.type, ErrorOrigin17.API);
@@ -7209,12 +7518,12 @@ function createTrackFactory(factories) {
7209
7518
 
7210
7519
  // src/track/source/SourceObjectTrack.ts
7211
7520
  import { ErrorOrigin as ErrorOrigin18 } from "@amazon/vinyl-util";
7212
- import { func as func2, isOneOf as isOneOf6 } from "@amazon/vinyl-validation";
7521
+ import { func as func2, isOneOf as isOneOf7 } from "@amazon/vinyl-validation";
7213
7522
 
7214
7523
  // src/track/TrackBase.ts
7215
7524
  import {
7216
- createAbortSlot as createAbortSlot4,
7217
- createDisposer as createDisposer15,
7525
+ createAbortSlot as createAbortSlot5,
7526
+ createDisposer as createDisposer16,
7218
7527
  emptyRanges as emptyRanges2,
7219
7528
  equalDeep as equalDeep2,
7220
7529
  EventHostImpl as EventHostImpl15,
@@ -7242,8 +7551,8 @@ var TrackBase = class extends EventHostImpl15 {
7242
7551
  });
7243
7552
  }
7244
7553
  });
7245
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer15());
7246
- __publicField(this, "drmSessionAbort", /* @__PURE__ */ createAbortSlot4());
7554
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer16());
7555
+ __publicField(this, "drmSessionAbort", /* @__PURE__ */ createAbortSlot5());
7247
7556
  /**
7248
7557
  * Sets on handleError, cleared on 'reset'.
7249
7558
  */
@@ -7472,7 +7781,7 @@ var FixedPlaybackQuality = class extends EventHostImpl16 {
7472
7781
 
7473
7782
  // src/track/source/SourceTrackBase.ts
7474
7783
  import {
7475
- createDisposer as createDisposer16,
7784
+ createDisposer as createDisposer17,
7476
7785
  logDebug as logDebug15,
7477
7786
  redispatchEvents as redispatchEvents2
7478
7787
  } from "@amazon/vinyl-util";
@@ -7531,7 +7840,7 @@ var SourceTrackBase = class extends TrackBase {
7531
7840
  return this.fixedPlaybackQuality.getPlaybackQuality(contentType2);
7532
7841
  }
7533
7842
  onActivated() {
7534
- const { add, dispose } = createDisposer16();
7843
+ const { add, dispose } = createDisposer17();
7535
7844
  this.activeSub = dispose;
7536
7845
  add(
7537
7846
  this.deps.playbackController.on("durationChange", (event) => {
@@ -7565,7 +7874,7 @@ var SourceTrackBase = class extends TrackBase {
7565
7874
  // src/track/source/SourceObjectTrack.ts
7566
7875
  var loadOptionsValidator = /* @__PURE__ */ trackLoadOptionsValidator.extend({
7567
7876
  srcObjectProvider: /* @__PURE__ */ func2(),
7568
- type: /* @__PURE__ */ isOneOf6("srcObject"),
7877
+ type: /* @__PURE__ */ isOneOf7("srcObject"),
7569
7878
  config: /* @__PURE__ */ sourceTrackBaseOptionsValidator.maybe().optional()
7570
7879
  });
7571
7880
  function createSourceObjectTrackFactory(deps) {
@@ -7602,11 +7911,11 @@ var SourceObjectTrack = class extends SourceTrackBase {
7602
7911
 
7603
7912
  // src/track/source/SourceTrack.ts
7604
7913
  import { ErrorOrigin as ErrorOrigin19 } from "@amazon/vinyl-util";
7605
- import { func as func3, isOneOf as isOneOf7 } from "@amazon/vinyl-validation";
7914
+ import { func as func3, isOneOf as isOneOf8 } from "@amazon/vinyl-validation";
7606
7915
  var loadOptionsValidator2 = /* @__PURE__ */ trackLoadOptionsValidator.extend({
7607
7916
  config: /* @__PURE__ */ sourceTrackBaseOptionsValidator.maybe().optional(),
7608
7917
  srcProvider: /* @__PURE__ */ func3().maybe().optional(),
7609
- type: /* @__PURE__ */ isOneOf7("src")
7918
+ type: /* @__PURE__ */ isOneOf8("src")
7610
7919
  });
7611
7920
  function createSourceTrackFactory(deps) {
7612
7921
  return {
@@ -7646,13 +7955,13 @@ import {
7646
7955
  } from "@amazon/vinyl-util";
7647
7956
  import {
7648
7957
  func as func4,
7649
- isOneOf as isOneOf8,
7650
- object as object11
7958
+ isOneOf as isOneOf9,
7959
+ object as object13
7651
7960
  } from "@amazon/vinyl-validation";
7652
7961
 
7653
7962
  // src/track/mse/MseTrack.ts
7654
7963
  import {
7655
- Abort as Abort4,
7964
+ Abort as Abort3,
7656
7965
  equalDeep as equalDeep3,
7657
7966
  first as first2,
7658
7967
  IntersectionRanges,
@@ -7670,7 +7979,7 @@ var MseTrack = class extends TrackBase {
7670
7979
  super(uri, type, deps);
7671
7980
  __publicField(this, "streams", []);
7672
7981
  __publicField(this, "stallNudgeTimer", null);
7673
- __publicField(this, "disposeAbort", /* @__PURE__ */ new Abort4());
7982
+ __publicField(this, "disposeAbort", /* @__PURE__ */ new Abort3());
7674
7983
  __publicField(this, "lastPreloadOptions", null);
7675
7984
  __publicField(this, "allFetchedRanges", []);
7676
7985
  __publicField(this, "_fetchedRanges", /* @__PURE__ */ new IntersectionRanges(
@@ -7727,7 +8036,7 @@ var MseTrack = class extends TrackBase {
7727
8036
  )
7728
8037
  );
7729
8038
  add(
7730
- deps.preferredAudioLanguage.onData((_value, previous) => {
8039
+ deps.audio.onData((_value, previous) => {
7731
8040
  if (previous !== void 0) this.reloadStreams();
7732
8041
  })
7733
8042
  );
@@ -7736,11 +8045,6 @@ var MseTrack = class extends TrackBase {
7736
8045
  if (previous !== void 0) this.reloadStreams();
7737
8046
  })
7738
8047
  );
7739
- add(
7740
- deps.preferDescriptiveAudio.onData((_value, previous) => {
7741
- if (previous !== void 0) this.reloadStreams();
7742
- })
7743
- );
7744
8048
  add(
7745
8049
  deps.abr.onData((value, previous) => {
7746
8050
  if (previous === void 0) return;
@@ -7947,7 +8251,7 @@ var MseTrack = class extends TrackBase {
7947
8251
  onActivated(loadOptions) {
7948
8252
  var _a;
7949
8253
  if (this.disposed) return;
7950
- (_a = this.deps.textTrackController) == null ? void 0 : _a.resume();
8254
+ (_a = this.deps.textTrackController) == null ? void 0 : _a.activate();
7951
8255
  this.deps.playbackSource.disableRemotePlayback = true;
7952
8256
  this.streams.forEach((stream) => {
7953
8257
  this.deps.drmController.initializeForPlayback(
@@ -7980,7 +8284,7 @@ var MseTrack = class extends TrackBase {
7980
8284
  trackUri: this.uri,
7981
8285
  abort: this.disposeAbort
7982
8286
  });
7983
- (_b = this.deps.textTrackController) == null ? void 0 : _b.suspend();
8287
+ (_b = this.deps.textTrackController) == null ? void 0 : _b.deactivate();
7984
8288
  this.deps.playbackSource.src = null;
7985
8289
  this.deps.playbackSource.load();
7986
8290
  this.deps.mediaSourceController.deactivate();
@@ -8078,9 +8382,9 @@ var MseTrack = class extends TrackBase {
8078
8382
  // src/track/dash/DashTrack.ts
8079
8383
  var loadOptionsValidator3 = /* @__PURE__ */ trackLoadOptionsValidator.extend({
8080
8384
  manifestProvider: /* @__PURE__ */ func4().maybe().optional(),
8081
- requestInit: /* @__PURE__ */ object11({}).cast().maybe().optional(),
8082
- segmentRequestInit: /* @__PURE__ */ object11({}).cast().maybe().optional(),
8083
- type: /* @__PURE__ */ isOneOf8("dash")
8385
+ requestInit: /* @__PURE__ */ object13({}).cast().maybe().optional(),
8386
+ segmentRequestInit: /* @__PURE__ */ object13({}).cast().maybe().optional(),
8387
+ type: /* @__PURE__ */ isOneOf9("dash")
8084
8388
  });
8085
8389
  function createDashTrackFactory(deps) {
8086
8390
  return {
@@ -8101,14 +8405,14 @@ function createDashTrackFactory(deps) {
8101
8405
  import { ErrorOrigin as ErrorOrigin21 } from "@amazon/vinyl-util";
8102
8406
  import {
8103
8407
  func as func5,
8104
- isOneOf as isOneOf9,
8105
- object as object12
8408
+ isOneOf as isOneOf10,
8409
+ object as object14
8106
8410
  } from "@amazon/vinyl-validation";
8107
8411
  var loadOptionsValidator4 = /* @__PURE__ */ trackLoadOptionsValidator.extend({
8108
8412
  manifestProvider: /* @__PURE__ */ func5().maybe().optional(),
8109
- requestInit: /* @__PURE__ */ object12({}).cast().maybe().optional(),
8110
- segmentRequestInit: /* @__PURE__ */ object12({}).cast().maybe().optional(),
8111
- type: /* @__PURE__ */ isOneOf9("hls")
8413
+ requestInit: /* @__PURE__ */ object14({}).cast().maybe().optional(),
8414
+ segmentRequestInit: /* @__PURE__ */ object14({}).cast().maybe().optional(),
8415
+ type: /* @__PURE__ */ isOneOf10("hls")
8112
8416
  });
8113
8417
  function createHlsTrackFactory(deps) {
8114
8418
  return {
@@ -9089,9 +9393,8 @@ function createDashFactories(options) {
9089
9393
  qualitySelector: (deps2) => new QualitySelectorImpl({
9090
9394
  options: deps2.options.pick("abr")
9091
9395
  }),
9092
- preferredAudioLanguage: (deps2) => deps2.options.pick("preferredAudioLanguage"),
9396
+ audio: (deps2) => deps2.options.pick("audio"),
9093
9397
  allowedContentTypes: (deps2) => deps2.options.pick("allowedContentTypes"),
9094
- preferDescriptiveAudio: (deps2) => deps2.options.pick("preferDescriptiveAudio"),
9095
9398
  abr: (deps2) => deps2.options.pick("abr"),
9096
9399
  manifestTransformed: createDefaultDashManifestTransformer,
9097
9400
  mediaTimeline: (deps2) => deps2.manifestTransformed.map(async (manifestPromise) => {
@@ -9101,26 +9404,21 @@ function createDashFactories(options) {
9101
9404
  mediaTimelineTransformed: createDefaultMediaTimelineTransformer,
9102
9405
  textTrackController: (deps2) => {
9103
9406
  var _a;
9104
- const controller = new SidecarTextTrackController({
9105
- media: deps2.media,
9407
+ return new SidecarTextTrackController({
9408
+ textTrackProvider: deps2.textTrackProvider,
9409
+ textTrackRenderer: deps2.textTrackRenderer,
9410
+ playbackController: deps2.playbackController,
9106
9411
  requestInit: (_a = loadOptions.requestInit) != null ? _a : void 0,
9107
- preferredTextLanguage: deps2.options.pick(
9108
- "preferredTextLanguage"
9109
- ),
9110
- cueStyle: deps2.options.pick("textCueStyle")
9111
- });
9112
- deps2.manifestTransformed.onData((manifestPromise) => {
9113
- manifestPromise.then((data3) => {
9114
- controller.setTextTracks(
9115
- discoverDashTextTracks(
9412
+ options: deps2.options.pick("text"),
9413
+ textTracks: deps2.manifestTransformed.map(
9414
+ (manifestPromise) => manifestPromise.then(
9415
+ (data3) => discoverDashTextTracks(
9116
9416
  data3.manifest,
9117
9417
  data3.baseUrl
9118
9418
  )
9119
- );
9120
- }).catch(() => {
9121
- });
9419
+ )
9420
+ )
9122
9421
  });
9123
- return controller;
9124
9422
  }
9125
9423
  }));
9126
9424
  };
@@ -9508,9 +9806,8 @@ function createHlsFactories(options) {
9508
9806
  qualitySelector: (deps2) => new QualitySelectorImpl({
9509
9807
  options: deps2.options.pick("abr")
9510
9808
  }),
9511
- preferredAudioLanguage: (deps2) => deps2.options.pick("preferredAudioLanguage"),
9809
+ audio: (deps2) => deps2.options.pick("audio"),
9512
9810
  allowedContentTypes: (deps2) => deps2.options.pick("allowedContentTypes"),
9513
- preferDescriptiveAudio: (deps2) => deps2.options.pick("preferDescriptiveAudio"),
9514
9811
  abr: (deps2) => deps2.options.pick("abr"),
9515
9812
  mediaTimeline: (deps2) => deps2.manifestTransformed.map(async (manifestPromise) => {
9516
9813
  const data3 = await manifestPromise;
@@ -9519,26 +9816,21 @@ function createHlsFactories(options) {
9519
9816
  mediaTimelineTransformed: createDefaultMediaTimelineTransformer,
9520
9817
  textTrackController: (deps2) => {
9521
9818
  var _a;
9522
- const controller = new SidecarTextTrackController({
9523
- media: deps2.media,
9819
+ return new SidecarTextTrackController({
9820
+ textTrackProvider: deps2.textTrackProvider,
9821
+ textTrackRenderer: deps2.textTrackRenderer,
9822
+ playbackController: deps2.playbackController,
9524
9823
  requestInit: (_a = loadOptions.requestInit) != null ? _a : void 0,
9525
- preferredTextLanguage: deps2.options.pick(
9526
- "preferredTextLanguage"
9527
- ),
9528
- cueStyle: deps2.options.pick("textCueStyle")
9529
- });
9530
- deps2.manifestTransformed.onData((manifestPromise) => {
9531
- manifestPromise.then((data3) => {
9532
- controller.setTextTracks(
9533
- discoverHlsTextTracks(
9824
+ options: deps2.options.pick("text"),
9825
+ textTracks: deps2.manifestTransformed.map(
9826
+ (manifestPromise) => manifestPromise.then(
9827
+ (data3) => discoverHlsTextTracks(
9534
9828
  data3.mainPlaylist,
9535
9829
  data3.baseUrl
9536
9830
  )
9537
- );
9538
- }).catch(() => {
9539
- });
9831
+ )
9832
+ )
9540
9833
  });
9541
- return controller;
9542
9834
  }
9543
9835
  }));
9544
9836
  };
@@ -9548,13 +9840,13 @@ function createHlsFactories(options) {
9548
9840
  // src/track/TrackController.ts
9549
9841
  import {
9550
9842
  countElements,
9551
- createDisposer as createDisposer17,
9843
+ createDisposer as createDisposer18,
9552
9844
  EventHostImpl as EventHostImpl17,
9553
9845
  first as first3,
9554
9846
  getOrSet as getOrSet3,
9555
9847
  IllegalStateError as IllegalStateError4,
9556
9848
  logDebug as logDebug17,
9557
- logError as logError4,
9849
+ logError as logError5,
9558
9850
  logInfo as logInfo3,
9559
9851
  logVerbose as logVerbose4,
9560
9852
  logWarn as logWarn6,
@@ -9599,7 +9891,7 @@ var TrackControllerImpl = class extends EventHostImpl17 {
9599
9891
  // Ad tracks keyed by parent content URI, kept out of the content cache.
9600
9892
  // Pegged to the parent: disposed when the parent is evicted (see onEvict).
9601
9893
  __publicField(this, "adTracksByParent", /* @__PURE__ */ new Map());
9602
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer17());
9894
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer18());
9603
9895
  __publicField(this, "_options", defaultTrackControllerImplOptions);
9604
9896
  /**
9605
9897
  * The current track has ended naturally. On the next tick advance the queue or emit queue ended.
@@ -9630,7 +9922,7 @@ var TrackControllerImpl = class extends EventHostImpl17 {
9630
9922
  });
9631
9923
  }
9632
9924
  }).catch((error) => {
9633
- logError4(this, "enterPostroll failed", error);
9925
+ logError5(this, "enterPostroll failed", error);
9634
9926
  });
9635
9927
  });
9636
9928
  __publicField(this, "validateLoadOptions", (loadOptions) => this.deps.trackFactory.validate(loadOptions));
@@ -10071,7 +10363,7 @@ var TrackControllerImpl = class extends EventHostImpl17 {
10071
10363
  if (preroll) return;
10072
10364
  activate();
10073
10365
  }).catch((error) => {
10074
- logError4(this, "enterPreroll failed", error);
10366
+ logError5(this, "enterPreroll failed", error);
10075
10367
  activate();
10076
10368
  });
10077
10369
  }
@@ -10129,34 +10421,33 @@ import { validateFactories as validateFactories5 } from "@amazon/vinyl-di";
10129
10421
 
10130
10422
  // src/vinyl/VinylOptions.ts
10131
10423
  import {
10132
- array as array3,
10133
- boolean as boolean4,
10134
- isOneOf as isOneOf10,
10135
- object as object13,
10424
+ array as array5,
10425
+ isOneOf as isOneOf11,
10426
+ object as object15,
10136
10427
  record as record3,
10137
- string as string7
10428
+ string as string9
10138
10429
  } from "@amazon/vinyl-validation";
10139
10430
  var defaultVinylOptions = {
10140
10431
  abr: defaultQualitySelectorImplOptions,
10141
10432
  loudnessNormalization: defaultLoudnessNormalizationControllerImplOptions,
10142
- preferredAudioLanguage: null,
10143
- preferredTextLanguage: null,
10144
- preferDescriptiveAudio: false,
10433
+ audio: defaultAudioOptions,
10145
10434
  codecOverrides: {},
10146
10435
  allowedContentTypes: null,
10147
- textCueStyle: { size: 90 }
10436
+ text: {
10437
+ // Forced-only captions in the platform's preferred languages (no
10438
+ // explicit language → navigator.languages).
10439
+ enabled: "forced"
10440
+ }
10148
10441
  };
10149
- var vinylOptionsValidator = /* @__PURE__ */ object13({
10442
+ var vinylOptionsValidator = /* @__PURE__ */ object15({
10150
10443
  abr: qualitySelectorImplOptionsValidator,
10151
10444
  loudnessNormalization: loudnessNormalizationControllerImplOptionsValidator,
10152
- preferredAudioLanguage: /* @__PURE__ */ string7().or(/* @__PURE__ */ array3(/* @__PURE__ */ string7()).readonly()).orNull(),
10153
- preferredTextLanguage: /* @__PURE__ */ string7().or(/* @__PURE__ */ array3(/* @__PURE__ */ string7()).readonly()).orNull(),
10154
- preferDescriptiveAudio: /* @__PURE__ */ boolean4(),
10155
- codecOverrides: /* @__PURE__ */ record3(/* @__PURE__ */ string7(), /* @__PURE__ */ isOneOf10("allow", "deny")),
10156
- allowedContentTypes: /* @__PURE__ */ array3(/* @__PURE__ */ isOneOf10(...RESTRICTABLE_CONTENT_TYPES)).cast().describe(
10445
+ audio: audioOptionsValidator,
10446
+ codecOverrides: /* @__PURE__ */ record3(/* @__PURE__ */ string9(), /* @__PURE__ */ isOneOf11("allow", "deny")),
10447
+ allowedContentTypes: /* @__PURE__ */ array5(/* @__PURE__ */ isOneOf11(...RESTRICTABLE_CONTENT_TYPES)).readonly().describe(
10157
10448
  "Allow list of media content types (audio, video) to stream; other media streams are ignored. Text tracks are unaffected."
10158
10449
  ).orNull(),
10159
- textCueStyle: /* @__PURE__ */ vttCueStyleValidator.orNull()
10450
+ text: textTrackControllerOptionsValidator
10160
10451
  });
10161
10452
 
10162
10453
  // src/vinyl/playerConfigFactory.ts
@@ -10189,6 +10480,14 @@ function createVinylFactories(options) {
10189
10480
  return patchMediaElement(options.media, patches.media);
10190
10481
  },
10191
10482
  media: (deps) => deps.patchedMedia.patched,
10483
+ // One provider per media element (the player container creates each
10484
+ // dependency once), so text tracks are reused rather than accumulated.
10485
+ textTrackProvider: (deps) => createMediaTextTrackProvider({ media: deps.media }),
10486
+ // App-provided cue renderer (or null for native rendering).
10487
+ textTrackRenderer: () => {
10488
+ var _a2;
10489
+ return (_a2 = options.textTrackRenderer) != null ? _a2 : null;
10490
+ },
10192
10491
  playbackController: (deps) => new PlaybackControllerImpl(deps, options.playbackController),
10193
10492
  playbackSource: (deps) => new PlaybackSourceImpl(deps),
10194
10493
  loudnessNormalizationController: (deps) => new LoudnessNormalizationControllerImpl({
@@ -10211,7 +10510,7 @@ function createVinylFactories(options) {
10211
10510
 
10212
10511
  // src/vinyl/VinylPlayer.ts
10213
10512
  import {
10214
- createDisposer as createDisposer18,
10513
+ createDisposer as createDisposer19,
10215
10514
  emptyRanges as emptyRanges3,
10216
10515
  equalDeep as equalDeep4,
10217
10516
  EventHostImpl as EventHostImpl18,
@@ -10240,7 +10539,7 @@ var VinylPlayer = class extends EventHostImpl18 {
10240
10539
  */
10241
10540
  __publicField(this, "client");
10242
10541
  __publicField(this, "_error", null);
10243
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer18());
10542
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer19());
10244
10543
  const add = this.disposer.add;
10245
10544
  this.deps = add(createContainer3(factories)).dependencies;
10246
10545
  this.client = {
@@ -10324,10 +10623,6 @@ var VinylPlayer = class extends EventHostImpl18 {
10324
10623
  const previous = activeTrack;
10325
10624
  if (previous === current) return;
10326
10625
  activeTrack = current;
10327
- const prevTextController = previous == null ? void 0 : previous.textTrackController;
10328
- if (!this.deps.adController.currentAdBreak) {
10329
- prevTextController == null ? void 0 : prevTextController.setActiveTextTrack(null);
10330
- }
10331
10626
  sub == null ? void 0 : sub();
10332
10627
  sub = null;
10333
10628
  textSub == null ? void 0 : textSub();
@@ -10744,16 +11039,6 @@ var VinylPlayer = class extends EventHostImpl18 {
10744
11039
  var _a, _b, _c;
10745
11040
  return (_c = (_b = (_a = this.activeTrack) == null ? void 0 : _a.textTrackController) == null ? void 0 : _b.activeTextTrack) != null ? _c : null;
10746
11041
  }
10747
- /**
10748
- * Selects the text track with the given id, or clears the active text
10749
- * track when called with null. No-op when the current track does not
10750
- * surface text tracks or the id is unknown.
10751
- */
10752
- setActiveTextTrack(id) {
10753
- var _a;
10754
- const controller = (_a = this.deps.trackController.activeTrack) == null ? void 0 : _a.textTrackController;
10755
- controller == null ? void 0 : controller.setActiveTextTrack(id);
10756
- }
10757
11042
  emitTextTrackChangeEventsFor(previous, current) {
10758
11043
  var _a, _b, _c, _d, _e, _f;
10759
11044
  const prevList = (_a = previous == null ? void 0 : previous.textTrackController) == null ? void 0 : _a.textTracks;
@@ -10885,6 +11170,7 @@ export {
10885
11170
  DrmRobustness,
10886
11171
  FAIR_PLAY_KEY_SYSTEMS,
10887
11172
  FixedPlaybackQuality,
11173
+ HtmlTextTrackRenderer,
10888
11174
  InvalidSeekError,
10889
11175
  LICENSE_TIMEOUT,
10890
11176
  LIVE_DURATION,
@@ -10947,6 +11233,7 @@ export {
10947
11233
  applyVttCueStyle,
10948
11234
  assertMseSupported,
10949
11235
  audioContextRef,
11236
+ audioOptionsValidator,
10950
11237
  buildDashMediaTimeline,
10951
11238
  buildHlsMediaTimeline,
10952
11239
  buildSegmentTimeline,
@@ -10961,6 +11248,7 @@ export {
10961
11248
  codecToContentType,
10962
11249
  codecsToContentTypes,
10963
11250
  commonEmeFactory,
11251
+ computeCueLayout,
10964
11252
  configureVinylGlobal,
10965
11253
  contentProtectionToMetadata,
10966
11254
  contentTypeToMimeType,
@@ -10994,6 +11282,7 @@ export {
10994
11282
  createLanguageFilter,
10995
11283
  createMediaQualityMetadataFromDashRepresentation,
10996
11284
  createMediaSource,
11285
+ createMediaTextTrackProvider,
10997
11286
  createPreventStallsPatch,
10998
11287
  createSegmentControllerFactory,
10999
11288
  createSegmentDataProvider,
@@ -11008,6 +11297,7 @@ export {
11008
11297
  createVinylTrackFactories,
11009
11298
  defaultAdControllerImplOptions,
11010
11299
  defaultAdLoadOptionsResolver,
11300
+ defaultAudioOptions,
11011
11301
  defaultDrmKeySystemResolver,
11012
11302
  defaultLicenseProvider,
11013
11303
  defaultLoudnessNormalizationControllerImplOptions,
@@ -11101,11 +11391,13 @@ export {
11101
11391
  playerRegistryRef,
11102
11392
  prefetchPriorityQueuesRef,
11103
11393
  qualitySelectorImplOptionsValidator,
11394
+ renderCueText,
11104
11395
  requiresPreventStallsPatch,
11105
11396
  requiresUnreliablePlaybackEventsPatch,
11106
11397
  resolveCodecOverride,
11107
11398
  resolveDashUri,
11108
11399
  resolvePreferredLanguages,
11400
+ resolveSelectedTrack,
11109
11401
  sampleToMpdTime,
11110
11402
  segmentPriorityComparatorRef,
11111
11403
  segmentTemplateUrl,
@@ -11117,6 +11409,7 @@ export {
11117
11409
  supportsMse,
11118
11410
  supportsStandardEme,
11119
11411
  supportsWebKitEme,
11412
+ textTrackControllerOptionsValidator,
11120
11413
  throwKeySystemsUnsupported,
11121
11414
  throwLanguagesUnsupported,
11122
11415
  throwMimeTypesUnsupported,