@amazon/vinyl 2.0.4 → 3.0.1

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 (170) hide show
  1. package/dist/index.cjs +624 -338
  2. package/dist/index.cjs.map +4 -4
  3. package/dist/index.js +643 -350
  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 +183 -157
  9. package/dist/test/integ.js +1966 -817
  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/TrackController.d.ts.map +1 -1
  46. package/dist/types/current/track/TrackController.js +30 -30
  47. package/dist/types/current/track/dash/createDashFactories.d.ts +21 -10
  48. package/dist/types/current/track/dash/createDashFactories.d.ts.map +1 -1
  49. package/dist/types/current/track/dash/createDashFactories.js +9 -21
  50. package/dist/types/current/track/hls/createHlsFactories.d.ts +21 -10
  51. package/dist/types/current/track/hls/createHlsFactories.d.ts.map +1 -1
  52. package/dist/types/current/track/hls/createHlsFactories.js +9 -21
  53. package/dist/types/current/track/mse/MseTrack.d.ts +1 -2
  54. package/dist/types/current/track/mse/MseTrack.d.ts.map +1 -1
  55. package/dist/types/current/track/mse/MseTrack.js +3 -7
  56. package/dist/types/current/tsconfig.tsbuildinfo +1 -1
  57. package/dist/types/current/vinyl/VinylOptions.d.ts +18 -40
  58. package/dist/types/current/vinyl/VinylOptions.d.ts.map +1 -1
  59. package/dist/types/current/vinyl/VinylOptions.js +12 -11
  60. package/dist/types/current/vinyl/VinylPlayer.d.ts +0 -6
  61. package/dist/types/current/vinyl/VinylPlayer.d.ts.map +1 -1
  62. package/dist/types/current/vinyl/VinylPlayer.js +2 -23
  63. package/dist/types/current/vinyl/createVinylFactories.d.ts +32 -18
  64. package/dist/types/current/vinyl/createVinylFactories.d.ts.map +1 -1
  65. package/dist/types/current/vinyl/createVinylFactories.js +6 -0
  66. package/dist/types/ts3.7/index.d.ts +4 -0
  67. package/dist/types/ts3.7/streaming/AudioOptions.d.ts +39 -0
  68. package/dist/types/ts3.7/streaming/createDefaultMediaTimelineTransformer.d.ts +2 -2
  69. package/dist/types/ts3.7/text/HtmlTextTrackRenderer.d.ts +60 -0
  70. package/dist/types/ts3.7/text/SidecarTextTrackController.d.ts +65 -53
  71. package/dist/types/ts3.7/text/SidecarTextTrackLoader.d.ts +5 -0
  72. package/dist/types/ts3.7/text/TextTrack.d.ts +74 -20
  73. package/dist/types/ts3.7/text/TextTrackRenderer.d.ts +24 -0
  74. package/dist/types/ts3.7/text/mediaTextTrackProvider.d.ts +34 -0
  75. package/dist/types/ts3.7/text/parseWebVtt.d.ts +16 -2
  76. package/dist/types/ts3.7/text/pickPreferredTextTrack.d.ts +2 -1
  77. package/dist/types/ts3.7/track/Track.d.ts +1 -1
  78. package/dist/types/ts3.7/track/dash/createDashFactories.d.ts +21 -10
  79. package/dist/types/ts3.7/track/hls/createHlsFactories.d.ts +21 -10
  80. package/dist/types/ts3.7/track/mse/MseTrack.d.ts +1 -2
  81. package/dist/types/ts3.7/vinyl/VinylOptions.d.ts +18 -40
  82. package/dist/types/ts3.7/vinyl/VinylPlayer.d.ts +0 -6
  83. package/dist/types/ts3.7/vinyl/createVinylFactories.d.ts +32 -18
  84. package/dist/types/ts4.1/index.d.ts +4 -0
  85. package/dist/types/ts4.1/streaming/AudioOptions.d.ts +39 -0
  86. package/dist/types/ts4.1/streaming/createDefaultMediaTimelineTransformer.d.ts +2 -2
  87. package/dist/types/ts4.1/text/HtmlTextTrackRenderer.d.ts +60 -0
  88. package/dist/types/ts4.1/text/SidecarTextTrackController.d.ts +65 -53
  89. package/dist/types/ts4.1/text/SidecarTextTrackLoader.d.ts +5 -0
  90. package/dist/types/ts4.1/text/TextTrack.d.ts +74 -20
  91. package/dist/types/ts4.1/text/TextTrackRenderer.d.ts +24 -0
  92. package/dist/types/ts4.1/text/mediaTextTrackProvider.d.ts +34 -0
  93. package/dist/types/ts4.1/text/parseWebVtt.d.ts +16 -2
  94. package/dist/types/ts4.1/text/pickPreferredTextTrack.d.ts +2 -1
  95. package/dist/types/ts4.1/track/Track.d.ts +1 -1
  96. package/dist/types/ts4.1/track/dash/createDashFactories.d.ts +21 -10
  97. package/dist/types/ts4.1/track/hls/createHlsFactories.d.ts +21 -10
  98. package/dist/types/ts4.1/track/mse/MseTrack.d.ts +1 -2
  99. package/dist/types/ts4.1/vinyl/VinylOptions.d.ts +18 -40
  100. package/dist/types/ts4.1/vinyl/VinylPlayer.d.ts +0 -6
  101. package/dist/types/ts4.1/vinyl/createVinylFactories.d.ts +32 -18
  102. package/dist/types/ts4.7/index.d.ts +4 -0
  103. package/dist/types/ts4.7/streaming/AudioOptions.d.ts +39 -0
  104. package/dist/types/ts4.7/streaming/createDefaultMediaTimelineTransformer.d.ts +2 -2
  105. package/dist/types/ts4.7/text/HtmlTextTrackRenderer.d.ts +60 -0
  106. package/dist/types/ts4.7/text/SidecarTextTrackController.d.ts +65 -53
  107. package/dist/types/ts4.7/text/SidecarTextTrackLoader.d.ts +5 -0
  108. package/dist/types/ts4.7/text/TextTrack.d.ts +74 -20
  109. package/dist/types/ts4.7/text/TextTrackRenderer.d.ts +24 -0
  110. package/dist/types/ts4.7/text/mediaTextTrackProvider.d.ts +34 -0
  111. package/dist/types/ts4.7/text/parseWebVtt.d.ts +16 -2
  112. package/dist/types/ts4.7/text/pickPreferredTextTrack.d.ts +2 -1
  113. package/dist/types/ts4.7/track/Track.d.ts +1 -1
  114. package/dist/types/ts4.7/track/dash/createDashFactories.d.ts +21 -10
  115. package/dist/types/ts4.7/track/hls/createHlsFactories.d.ts +21 -10
  116. package/dist/types/ts4.7/track/mse/MseTrack.d.ts +1 -2
  117. package/dist/types/ts4.7/vinyl/VinylOptions.d.ts +18 -40
  118. package/dist/types/ts4.7/vinyl/VinylPlayer.d.ts +0 -6
  119. package/dist/types/ts4.7/vinyl/createVinylFactories.d.ts +32 -18
  120. package/dist/unit/types/current/index.d.ts +2 -0
  121. package/dist/unit/types/current/index.d.ts.map +1 -1
  122. package/dist/unit/types/current/index.js +2 -0
  123. package/dist/unit/types/current/streaming/MseTrack.test.js +13 -7
  124. package/dist/unit/types/current/streaming/createDefaultMediaTimelineTransformer.test.js +8 -4
  125. package/dist/unit/types/current/text/HtmlTextTrackRenderer.test.d.ts +2 -0
  126. package/dist/unit/types/current/text/HtmlTextTrackRenderer.test.d.ts.map +1 -0
  127. package/dist/unit/types/current/text/HtmlTextTrackRenderer.test.js +231 -0
  128. package/dist/unit/types/current/text/SidecarTextTrackController.test.js +432 -333
  129. package/dist/unit/types/current/text/SidecarTextTrackLoader.test.js +29 -0
  130. package/dist/unit/types/current/text/mediaTextTrackProvider.test.d.ts +2 -0
  131. package/dist/unit/types/current/text/mediaTextTrackProvider.test.d.ts.map +1 -0
  132. package/dist/unit/types/current/text/mediaTextTrackProvider.test.js +86 -0
  133. package/dist/unit/types/current/text/parseWebVtt.test.js +187 -6
  134. package/dist/unit/types/current/text/pickPreferredTextTrack.test.js +12 -1
  135. package/dist/unit/types/current/track/TrackController.test.js +36 -0
  136. package/dist/unit/types/current/track/dash/createDashFactories.test.js +1 -2
  137. package/dist/unit/types/current/track/hls/buildHlsMediaTimeline.test.js +1 -2
  138. package/dist/unit/types/current/track/hls/createHlsFactories.test.js +1 -2
  139. package/dist/unit/types/current/tsconfig.tsbuildinfo +1 -1
  140. package/dist/unit/types/current/vinyl/VinylPlayerTextTracks.test.js +102 -177
  141. package/dist/unit/types/current/vinyl/createVinylFactories.test.js +2 -0
  142. package/dist/vinylTestUtil/index.js +14 -8
  143. package/dist/vinylTestUtil/index.js.map +2 -2
  144. package/dist/vinylTestUtil/types/current/mock/player/MockVinylPlayerDependencies.d.ts +3 -2
  145. package/dist/vinylTestUtil/types/current/mock/player/MockVinylPlayerDependencies.d.ts.map +1 -1
  146. package/dist/vinylTestUtil/types/current/mock/player/MockVinylPlayerDependencies.js +5 -2
  147. package/dist/vinylTestUtil/types/current/mock/text/MockTextTrackController.d.ts +3 -3
  148. package/dist/vinylTestUtil/types/current/mock/text/MockTextTrackController.d.ts.map +1 -1
  149. package/dist/vinylTestUtil/types/current/mock/text/MockTextTrackController.js +3 -3
  150. package/dist/vinylTestUtil/types/current/mock/track/dash/createMockDashDependencies.d.ts +1 -2
  151. package/dist/vinylTestUtil/types/current/mock/track/dash/createMockDashDependencies.d.ts.map +1 -1
  152. package/dist/vinylTestUtil/types/current/mock/track/dash/createMockDashDependencies.js +3 -2
  153. package/dist/vinylTestUtil/types/current/mock/track/hls/createMockHlsDependencies.d.ts +1 -2
  154. package/dist/vinylTestUtil/types/current/mock/track/hls/createMockHlsDependencies.d.ts.map +1 -1
  155. package/dist/vinylTestUtil/types/current/mock/track/hls/createMockHlsDependencies.js +3 -2
  156. package/dist/vinylTestUtil/types/current/tsconfig.tsbuildinfo +1 -1
  157. package/dist/vinylTestUtil/types/ts3.7/mock/player/MockVinylPlayerDependencies.d.ts +3 -2
  158. package/dist/vinylTestUtil/types/ts3.7/mock/text/MockTextTrackController.d.ts +3 -3
  159. package/dist/vinylTestUtil/types/ts3.7/mock/track/dash/createMockDashDependencies.d.ts +1 -2
  160. package/dist/vinylTestUtil/types/ts3.7/mock/track/hls/createMockHlsDependencies.d.ts +1 -2
  161. package/dist/vinylTestUtil/types/ts4.1/mock/player/MockVinylPlayerDependencies.d.ts +3 -2
  162. package/dist/vinylTestUtil/types/ts4.1/mock/text/MockTextTrackController.d.ts +3 -3
  163. package/dist/vinylTestUtil/types/ts4.1/mock/track/dash/createMockDashDependencies.d.ts +1 -2
  164. package/dist/vinylTestUtil/types/ts4.1/mock/track/hls/createMockHlsDependencies.d.ts +1 -2
  165. package/dist/vinylTestUtil/types/ts4.7/mock/player/MockVinylPlayerDependencies.d.ts +3 -2
  166. package/dist/vinylTestUtil/types/ts4.7/mock/text/MockTextTrackController.d.ts +3 -3
  167. package/dist/vinylTestUtil/types/ts4.7/mock/track/dash/createMockDashDependencies.d.ts +1 -2
  168. package/dist/vinylTestUtil/types/ts4.7/mock/track/hls/createMockHlsDependencies.d.ts +1 -2
  169. package/docs/USAGE.md +82 -31
  170. package/package.json +9 -9
package/dist/index.cjs CHANGED
@@ -69,6 +69,7 @@ __export(index_exports, {
69
69
  DrmRobustness: () => DrmRobustness,
70
70
  FAIR_PLAY_KEY_SYSTEMS: () => FAIR_PLAY_KEY_SYSTEMS,
71
71
  FixedPlaybackQuality: () => FixedPlaybackQuality,
72
+ HtmlTextTrackRenderer: () => HtmlTextTrackRenderer,
72
73
  InvalidSeekError: () => InvalidSeekError,
73
74
  LICENSE_TIMEOUT: () => LICENSE_TIMEOUT,
74
75
  LIVE_DURATION: () => LIVE_DURATION,
@@ -131,6 +132,7 @@ __export(index_exports, {
131
132
  applyVttCueStyle: () => applyVttCueStyle,
132
133
  assertMseSupported: () => assertMseSupported,
133
134
  audioContextRef: () => audioContextRef,
135
+ audioOptionsValidator: () => audioOptionsValidator,
134
136
  buildDashMediaTimeline: () => buildDashMediaTimeline,
135
137
  buildHlsMediaTimeline: () => buildHlsMediaTimeline,
136
138
  buildSegmentTimeline: () => buildSegmentTimeline,
@@ -145,6 +147,7 @@ __export(index_exports, {
145
147
  codecToContentType: () => codecToContentType,
146
148
  codecsToContentTypes: () => codecsToContentTypes,
147
149
  commonEmeFactory: () => commonEmeFactory,
150
+ computeCueLayout: () => computeCueLayout,
148
151
  configureVinylGlobal: () => configureVinylGlobal,
149
152
  contentProtectionToMetadata: () => contentProtectionToMetadata,
150
153
  contentTypeToMimeType: () => contentTypeToMimeType,
@@ -178,6 +181,7 @@ __export(index_exports, {
178
181
  createLanguageFilter: () => createLanguageFilter,
179
182
  createMediaQualityMetadataFromDashRepresentation: () => createMediaQualityMetadataFromDashRepresentation,
180
183
  createMediaSource: () => createMediaSource,
184
+ createMediaTextTrackProvider: () => createMediaTextTrackProvider,
181
185
  createPreventStallsPatch: () => createPreventStallsPatch,
182
186
  createSegmentControllerFactory: () => createSegmentControllerFactory,
183
187
  createSegmentDataProvider: () => createSegmentDataProvider,
@@ -192,6 +196,7 @@ __export(index_exports, {
192
196
  createVinylTrackFactories: () => createVinylTrackFactories,
193
197
  defaultAdControllerImplOptions: () => defaultAdControllerImplOptions,
194
198
  defaultAdLoadOptionsResolver: () => defaultAdLoadOptionsResolver,
199
+ defaultAudioOptions: () => defaultAudioOptions,
195
200
  defaultDrmKeySystemResolver: () => defaultDrmKeySystemResolver,
196
201
  defaultLicenseProvider: () => defaultLicenseProvider,
197
202
  defaultLoudnessNormalizationControllerImplOptions: () => defaultLoudnessNormalizationControllerImplOptions,
@@ -285,11 +290,13 @@ __export(index_exports, {
285
290
  playerRegistryRef: () => playerRegistryRef,
286
291
  prefetchPriorityQueuesRef: () => prefetchPriorityQueuesRef,
287
292
  qualitySelectorImplOptionsValidator: () => qualitySelectorImplOptionsValidator,
293
+ renderCueText: () => renderCueText,
288
294
  requiresPreventStallsPatch: () => requiresPreventStallsPatch,
289
295
  requiresUnreliablePlaybackEventsPatch: () => requiresUnreliablePlaybackEventsPatch,
290
296
  resolveCodecOverride: () => resolveCodecOverride,
291
297
  resolveDashUri: () => resolveDashUri,
292
298
  resolvePreferredLanguages: () => resolvePreferredLanguages,
299
+ resolveSelectedTrack: () => resolveSelectedTrack,
293
300
  sampleToMpdTime: () => sampleToMpdTime,
294
301
  segmentPriorityComparatorRef: () => segmentPriorityComparatorRef,
295
302
  segmentTemplateUrl: () => segmentTemplateUrl,
@@ -301,6 +308,7 @@ __export(index_exports, {
301
308
  supportsMse: () => supportsMse,
302
309
  supportsStandardEme: () => supportsStandardEme,
303
310
  supportsWebKitEme: () => supportsWebKitEme,
311
+ textTrackControllerOptionsValidator: () => textTrackControllerOptionsValidator,
304
312
  throwKeySystemsUnsupported: () => throwKeySystemsUnsupported,
305
313
  throwLanguagesUnsupported: () => throwLanguagesUnsupported,
306
314
  throwMimeTypesUnsupported: () => throwMimeTypesUnsupported,
@@ -2767,7 +2775,7 @@ function configureVinylGlobal(options) {
2767
2775
  var import_vinyl_util27 = require("@amazon/vinyl-util");
2768
2776
  var vinylVersion = /* @__PURE__ */ (0, import_vinyl_util27.parseVersion)(
2769
2777
  /* istanbul ignore next */
2770
- "2.0.4"
2778
+ "3.0.1"
2771
2779
  );
2772
2780
 
2773
2781
  // src/global/globalRef.ts
@@ -4070,6 +4078,19 @@ var QualitySelectorImpl = class {
4070
4078
  }
4071
4079
  };
4072
4080
 
4081
+ // src/streaming/AudioOptions.ts
4082
+ var import_vinyl_validation8 = require("@amazon/vinyl-validation");
4083
+ var defaultAudioOptions = {
4084
+ selection: { language: null, descriptive: false }
4085
+ };
4086
+ var audioSelectionValidator = /* @__PURE__ */ (0, import_vinyl_validation8.object)({
4087
+ language: /* @__PURE__ */ (0, import_vinyl_validation8.string)().or(/* @__PURE__ */ (0, import_vinyl_validation8.array)(/* @__PURE__ */ (0, import_vinyl_validation8.string)()).readonly()).orNull().optional(),
4088
+ descriptive: /* @__PURE__ */ (0, import_vinyl_validation8.boolean)().optional()
4089
+ });
4090
+ var audioOptionsValidator = /* @__PURE__ */ (0, import_vinyl_validation8.object)({
4091
+ selection: /* @__PURE__ */ audioSelectionValidator.optional()
4092
+ });
4093
+
4073
4094
  // src/streaming/buffering/BufferingController.ts
4074
4095
  var import_vinyl_util50 = require("@amazon/vinyl-util");
4075
4096
 
@@ -5389,22 +5410,22 @@ function createLanguageFilter(preferredLanguage, contentType2) {
5389
5410
  return best;
5390
5411
  };
5391
5412
  const bestScoreForPeriod = (0, import_vinyl_util57.memoize)(
5392
- (array4) => {
5413
+ (array6) => {
5393
5414
  let best = 0;
5394
- for (const quality of Array.from(array4)) {
5415
+ for (const quality of Array.from(array6)) {
5395
5416
  if (quality.contentType === contentType2 && quality.lang) {
5396
5417
  best = Math.max(best, scoreLang(quality.lang));
5397
5418
  }
5398
5419
  }
5399
5420
  return best;
5400
5421
  },
5401
- (array4) => array4,
5422
+ (array6) => array6,
5402
5423
  1
5403
5424
  );
5404
- return (quality, _index, array4) => {
5425
+ return (quality, _index, array6) => {
5405
5426
  if (quality.contentType !== contentType2) return true;
5406
5427
  if (!quality.lang) return true;
5407
- const best = bestScoreForPeriod(array4);
5428
+ const best = bestScoreForPeriod(array6);
5408
5429
  if (best === 0) return true;
5409
5430
  return scoreLang(quality.lang) === best;
5410
5431
  };
@@ -5468,22 +5489,22 @@ function isAudioDescription(quality) {
5468
5489
  }
5469
5490
  function createAudioDescriptionFilter(preferDescription) {
5470
5491
  const periodFlags = (0, import_vinyl_util59.memoize)(
5471
- (array4) => {
5492
+ (array6) => {
5472
5493
  let hasDescription = false;
5473
5494
  let hasMain = false;
5474
- for (const quality of Array.from(array4)) {
5495
+ for (const quality of Array.from(array6)) {
5475
5496
  if (quality.contentType !== "audio") continue;
5476
5497
  if (isAudioDescription(quality)) hasDescription = true;
5477
5498
  else hasMain = true;
5478
5499
  }
5479
5500
  return { hasDescription, hasMain };
5480
5501
  },
5481
- (array4) => array4,
5502
+ (array6) => array6,
5482
5503
  1
5483
5504
  );
5484
- return (quality, _index, array4) => {
5505
+ return (quality, _index, array6) => {
5485
5506
  if (quality.contentType !== "audio") return true;
5486
- const { hasDescription, hasMain } = periodFlags(array4);
5507
+ const { hasDescription, hasMain } = periodFlags(array6);
5487
5508
  if (preferDescription) {
5488
5509
  if (!hasDescription) return true;
5489
5510
  return isAudioDescription(quality);
@@ -5521,7 +5542,7 @@ var import_vinyl_util62 = require("@amazon/vinyl-util");
5521
5542
  function throwSamplingRatesUnsupported() {
5522
5543
  throw new import_vinyl_util62.MediaUnsupportedError("No supported sample rate", "sampling-rate");
5523
5544
  }
5524
- function supportsAudioSamplingRate(deps, metadata, _index, array4) {
5545
+ function supportsAudioSamplingRate(deps, metadata, _index, array6) {
5525
5546
  const isFirefox = (0, import_vinyl_util62.hasBrowser)(import_vinyl_util62.Browser.FIREFOX);
5526
5547
  const maxSampleRate = deps.capabilities.sampleRate;
5527
5548
  const samplingRate = (0, import_vinyl_util62.last)(metadata.audioSamplingRate);
@@ -5530,13 +5551,13 @@ function supportsAudioSamplingRate(deps, metadata, _index, array4) {
5530
5551
  return samplingRate <= 48e3;
5531
5552
  }
5532
5553
  if (samplingRate <= maxSampleRate) return true;
5533
- const allAboveMax = (0, import_vinyl_util62.every)(array4, (item) => {
5554
+ const allAboveMax = (0, import_vinyl_util62.every)(array6, (item) => {
5534
5555
  const itemSamplingRate = (0, import_vinyl_util62.last)(item.audioSamplingRate);
5535
5556
  return itemSamplingRate != null && itemSamplingRate > maxSampleRate;
5536
5557
  });
5537
5558
  if (allAboveMax) {
5538
5559
  const samplingRates = (0, import_vinyl_util62.map)(
5539
- array4,
5560
+ array6,
5540
5561
  (item) => (0, import_vinyl_util62.last)(item.audioSamplingRate)
5541
5562
  ).filter((rate) => rate != null);
5542
5563
  const lowestSamplingRate = (0, import_vinyl_util62.min)(samplingRates);
@@ -5578,7 +5599,7 @@ function createDefaultMediaTimelineTransformer(deps) {
5578
5599
  return canPlayMimeType(deps, quality);
5579
5600
  }
5580
5601
  async function transformTimeline(timeline) {
5581
- var _a;
5602
+ var _a, _b;
5582
5603
  const codecOverrides = deps.options.value.codecOverrides;
5583
5604
  let t = filterTimelineQualities(
5584
5605
  (quality) => canPlayWithOverrides(quality, codecOverrides),
@@ -5591,22 +5612,18 @@ function createDefaultMediaTimelineTransformer(deps) {
5591
5612
  t
5592
5613
  );
5593
5614
  t = filterTimelineQualities(
5594
- (quality, index, array4) => supportsAudioSamplingRate(deps, quality, index, array4),
5615
+ (quality, index, array6) => supportsAudioSamplingRate(deps, quality, index, array6),
5595
5616
  throwSamplingRatesUnsupported,
5596
5617
  t
5597
5618
  );
5619
+ const selection = deps.options.value.audio.selection;
5598
5620
  t = filterTimelineQualities(
5599
- createAudioDescriptionFilter(
5600
- (_a = deps.options.value.preferDescriptiveAudio) != null ? _a : false
5601
- ),
5621
+ createAudioDescriptionFilter((_a = selection == null ? void 0 : selection.descriptive) != null ? _a : false),
5602
5622
  throwNoPlayableAudio,
5603
5623
  t
5604
5624
  );
5605
5625
  t = filterTimelineQualities(
5606
- createLanguageFilter(
5607
- deps.options.value.preferredAudioLanguage,
5608
- "audio"
5609
- ),
5626
+ createLanguageFilter((_b = selection == null ? void 0 : selection.language) != null ? _b : null, "audio"),
5610
5627
  throwLanguagesUnsupported,
5611
5628
  t
5612
5629
  );
@@ -5614,8 +5631,7 @@ function createDefaultMediaTimelineTransformer(deps) {
5614
5631
  }
5615
5632
  return (0, import_vinyl_observable2.combineData)({
5616
5633
  timeline: deps.mediaTimeline,
5617
- preferredAudioLanguage: deps.options.pick("preferredAudioLanguage"),
5618
- preferDescriptiveAudio: deps.options.pick("preferDescriptiveAudio"),
5634
+ audio: deps.options.pick("audio"),
5619
5635
  codecOverrides: deps.options.pick("codecOverrides")
5620
5636
  }).map(async ({ timeline }) => {
5621
5637
  return transformTimeline(await timeline);
@@ -5623,7 +5639,7 @@ function createDefaultMediaTimelineTransformer(deps) {
5623
5639
  }
5624
5640
 
5625
5641
  // src/streaming/DescriptorRecord.ts
5626
- var import_vinyl_validation8 = require("@amazon/vinyl-validation");
5642
+ var import_vinyl_validation9 = require("@amazon/vinyl-validation");
5627
5643
  var import_vinyl_util63 = require("@amazon/vinyl-util");
5628
5644
  function getDescriptorValue(record4, uri, id) {
5629
5645
  var _a, _b;
@@ -5632,11 +5648,11 @@ function getDescriptorValue(record4, uri, id) {
5632
5648
  if (id !== void 0) arr = arr.filter((descriptor) => descriptor.id === id);
5633
5649
  return (_b = (_a = (0, import_vinyl_util63.first)(arr)) == null ? void 0 : _a.value) != null ? _b : null;
5634
5650
  }
5635
- var descriptorValidator = /* @__PURE__ */ (0, import_vinyl_validation8.object)({
5636
- id: /* @__PURE__ */ (0, import_vinyl_validation8.string)().maybe().optional(),
5637
- value: /* @__PURE__ */ (0, import_vinyl_validation8.string)().maybe().optional()
5651
+ var descriptorValidator = /* @__PURE__ */ (0, import_vinyl_validation9.object)({
5652
+ id: /* @__PURE__ */ (0, import_vinyl_validation9.string)().maybe().optional(),
5653
+ value: /* @__PURE__ */ (0, import_vinyl_validation9.string)().maybe().optional()
5638
5654
  });
5639
- var descriptorRecordValidator = /* @__PURE__ */ (0, import_vinyl_validation8.record)(/* @__PURE__ */ (0, import_vinyl_validation8.string)(), /* @__PURE__ */ (0, import_vinyl_validation8.array)(descriptorValidator).readonly().orUndefined());
5655
+ var descriptorRecordValidator = /* @__PURE__ */ (0, import_vinyl_validation9.record)(/* @__PURE__ */ (0, import_vinyl_validation9.string)(), /* @__PURE__ */ (0, import_vinyl_validation9.array)(descriptorValidator).readonly().orUndefined());
5640
5656
 
5641
5657
  // src/streaming/ManifestControllerImpl.ts
5642
5658
  var import_vinyl_observable3 = require("@amazon/vinyl-observable");
@@ -5741,7 +5757,7 @@ var ManifestControllerImpl = class {
5741
5757
 
5742
5758
  // src/streaming/MediaQualityMetadata.ts
5743
5759
  var import_vinyl_util65 = require("@amazon/vinyl-util");
5744
- var import_vinyl_validation9 = require("@amazon/vinyl-validation");
5760
+ var import_vinyl_validation10 = require("@amazon/vinyl-validation");
5745
5761
  var ALL_CONTENT_TYPES = [
5746
5762
  "video",
5747
5763
  "audio",
@@ -5752,16 +5768,16 @@ var RESTRICTABLE_CONTENT_TYPES = [
5752
5768
  "audio"
5753
5769
  ];
5754
5770
  var drmProtectionValidator = /* @__PURE__ */ descriptorValidator.extend({
5755
- keySystem: /* @__PURE__ */ (0, import_vinyl_validation9.enumOf)(DrmKeySystem),
5756
- pro: /* @__PURE__ */ (0, import_vinyl_validation9.string)().maybe().optional(),
5757
- pssh: /* @__PURE__ */ (0, import_vinyl_validation9.string)().maybe().optional()
5771
+ keySystem: /* @__PURE__ */ (0, import_vinyl_validation10.enumOf)(DrmKeySystem),
5772
+ pro: /* @__PURE__ */ (0, import_vinyl_validation10.string)().maybe().optional(),
5773
+ pssh: /* @__PURE__ */ (0, import_vinyl_validation10.string)().maybe().optional()
5758
5774
  });
5759
- var mediaFormatMetadataValidator = /* @__PURE__ */ (0, import_vinyl_validation9.object)({
5760
- contentProtections: /* @__PURE__ */ (0, import_vinyl_validation9.array)(drmProtectionValidator).readonly(),
5761
- contentType: /* @__PURE__ */ (0, import_vinyl_validation9.isOneOf)("audio", "video", "text").orNull(),
5762
- initDataType: /* @__PURE__ */ (0, import_vinyl_validation9.string)().orNull(),
5763
- encryptionScheme: /* @__PURE__ */ (0, import_vinyl_validation9.string)().orNull(),
5764
- mimeType: /* @__PURE__ */ (0, import_vinyl_validation9.string)().orNull()
5775
+ var mediaFormatMetadataValidator = /* @__PURE__ */ (0, import_vinyl_validation10.object)({
5776
+ contentProtections: /* @__PURE__ */ (0, import_vinyl_validation10.array)(drmProtectionValidator).readonly(),
5777
+ contentType: /* @__PURE__ */ (0, import_vinyl_validation10.isOneOf)("audio", "video", "text").orNull(),
5778
+ initDataType: /* @__PURE__ */ (0, import_vinyl_validation10.string)().orNull(),
5779
+ encryptionScheme: /* @__PURE__ */ (0, import_vinyl_validation10.string)().orNull(),
5780
+ mimeType: /* @__PURE__ */ (0, import_vinyl_validation10.string)().orNull()
5765
5781
  });
5766
5782
  function createEmptyMediaFormatMetadata() {
5767
5783
  return {
@@ -5791,20 +5807,20 @@ function createEmptyMediaQualityMetadata() {
5791
5807
  });
5792
5808
  }
5793
5809
  var mediaQualityMetadataValidator = /* @__PURE__ */ mediaFormatMetadataValidator.extend({
5794
- audioSamplingRate: /* @__PURE__ */ (0, import_vinyl_validation9.array)(/* @__PURE__ */ (0, import_vinyl_validation9.number)()).readonly().orNull(),
5795
- bandwidth: /* @__PURE__ */ (0, import_vinyl_validation9.number)().orNull(),
5796
- bandwidthTotal: /* @__PURE__ */ (0, import_vinyl_validation9.number)().orNull(),
5797
- codecs: /* @__PURE__ */ (0, import_vinyl_validation9.string)().orNull(),
5798
- decoderId: /* @__PURE__ */ (0, import_vinyl_validation9.string)(),
5799
- frameRate: /* @__PURE__ */ (0, import_vinyl_validation9.tuple)(/* @__PURE__ */ (0, import_vinyl_validation9.number)(), /* @__PURE__ */ (0, import_vinyl_validation9.number)()).readonly().orNull(),
5800
- height: /* @__PURE__ */ (0, import_vinyl_validation9.number)().orNull(),
5801
- qualityId: /* @__PURE__ */ (0, import_vinyl_validation9.string)(),
5810
+ audioSamplingRate: /* @__PURE__ */ (0, import_vinyl_validation10.array)(/* @__PURE__ */ (0, import_vinyl_validation10.number)()).readonly().orNull(),
5811
+ bandwidth: /* @__PURE__ */ (0, import_vinyl_validation10.number)().orNull(),
5812
+ bandwidthTotal: /* @__PURE__ */ (0, import_vinyl_validation10.number)().orNull(),
5813
+ codecs: /* @__PURE__ */ (0, import_vinyl_validation10.string)().orNull(),
5814
+ decoderId: /* @__PURE__ */ (0, import_vinyl_validation10.string)(),
5815
+ frameRate: /* @__PURE__ */ (0, import_vinyl_validation10.tuple)(/* @__PURE__ */ (0, import_vinyl_validation10.number)(), /* @__PURE__ */ (0, import_vinyl_validation10.number)()).readonly().orNull(),
5816
+ height: /* @__PURE__ */ (0, import_vinyl_validation10.number)().orNull(),
5817
+ qualityId: /* @__PURE__ */ (0, import_vinyl_validation10.string)(),
5802
5818
  supplementalProperties: descriptorRecordValidator,
5803
- width: /* @__PURE__ */ (0, import_vinyl_validation9.number)().orNull(),
5804
- lang: /* @__PURE__ */ (0, import_vinyl_validation9.string)().orNull(),
5805
- characteristics: /* @__PURE__ */ (0, import_vinyl_validation9.array)(/* @__PURE__ */ (0, import_vinyl_validation9.string)()).readonly(),
5806
- groupId: /* @__PURE__ */ (0, import_vinyl_validation9.string)(),
5807
- switchingGroupIds: /* @__PURE__ */ (0, import_vinyl_validation9.array)(/* @__PURE__ */ (0, import_vinyl_validation9.string)()).readonly().orNull()
5819
+ width: /* @__PURE__ */ (0, import_vinyl_validation10.number)().orNull(),
5820
+ lang: /* @__PURE__ */ (0, import_vinyl_validation10.string)().orNull(),
5821
+ characteristics: /* @__PURE__ */ (0, import_vinyl_validation10.array)(/* @__PURE__ */ (0, import_vinyl_validation10.string)()).readonly(),
5822
+ groupId: /* @__PURE__ */ (0, import_vinyl_validation10.string)(),
5823
+ switchingGroupIds: /* @__PURE__ */ (0, import_vinyl_validation10.array)(/* @__PURE__ */ (0, import_vinyl_validation10.string)()).readonly().orNull()
5808
5824
  });
5809
5825
 
5810
5826
  // src/streaming/MediaTimeline.ts
@@ -6584,10 +6600,202 @@ function discoverHlsTextTracks(mainPlaylist, baseUrl) {
6584
6600
  return out;
6585
6601
  }
6586
6602
 
6603
+ // src/text/HtmlTextTrackRenderer.ts
6604
+ var ROW_EM = 1.5;
6605
+ function computeCueLayout(cue) {
6606
+ const style = {};
6607
+ style.textAlign = cue.align || "center";
6608
+ if (cue.vertical === "rl") style.writingMode = "vertical-rl";
6609
+ else if (cue.vertical === "lr") style.writingMode = "vertical-lr";
6610
+ const size = typeof cue.size === "number" ? cue.size : 100;
6611
+ style.maxWidth = `${size}%`;
6612
+ const line = typeof cue.line === "number" ? cue.line : null;
6613
+ const position = typeof cue.position === "number" ? cue.position : null;
6614
+ if (line == null && position == null) return style;
6615
+ style.position = "absolute";
6616
+ const transforms = [];
6617
+ if (position == null) {
6618
+ style.left = "50%";
6619
+ transforms.push("translateX(-50%)");
6620
+ } else {
6621
+ if (cue.positionAlign === "line-right") {
6622
+ style.right = `${100 - position}%`;
6623
+ } else if (cue.positionAlign === "line-left") {
6624
+ style.left = `${position}%`;
6625
+ } else {
6626
+ style.left = `${position}%`;
6627
+ transforms.push("translateX(-50%)");
6628
+ }
6629
+ }
6630
+ if (line == null) {
6631
+ style.bottom = "0";
6632
+ } else {
6633
+ if (cue.snapToLines === false) {
6634
+ if (cue.lineAlign === "end") {
6635
+ style.bottom = `${100 - line}%`;
6636
+ } else if (cue.lineAlign === "center") {
6637
+ style.top = `${line}%`;
6638
+ transforms.push("translateY(-50%)");
6639
+ } else {
6640
+ style.top = `${line}%`;
6641
+ }
6642
+ } else if (line < 0) {
6643
+ style.bottom = `${(-line - 1) * ROW_EM}em`;
6644
+ } else {
6645
+ style.top = `${line * ROW_EM}em`;
6646
+ }
6647
+ }
6648
+ if (transforms.length > 0) style.transform = transforms.join(" ");
6649
+ return style;
6650
+ }
6651
+ var HTML_ESCAPE = {
6652
+ "&": "&amp;",
6653
+ "<": "&lt;",
6654
+ ">": "&gt;",
6655
+ '"': "&quot;"
6656
+ };
6657
+ function escapeHtml(text) {
6658
+ return text.replace(/["&<>]/g, (ch) => HTML_ESCAPE[ch]);
6659
+ }
6660
+ var PASSTHROUGH_TAGS = /* @__PURE__ */ new Set(["i", "b", "u", "ruby", "rt"]);
6661
+ var SPAN_TAGS = /* @__PURE__ */ new Set(["c", "v", "lang"]);
6662
+ function openTag(inner) {
6663
+ if (/^\d/.test(inner)) return "";
6664
+ const head = inner.split(/\s/, 1)[0];
6665
+ const [name, ...classes] = head.split(".");
6666
+ const annotation = inner.slice(head.length).trim();
6667
+ const classAttr = classes.filter(Boolean).length ? ` class="${escapeHtml(classes.filter(Boolean).join(" "))}"` : "";
6668
+ if (PASSTHROUGH_TAGS.has(name)) return `<${name}${classAttr}>`;
6669
+ if (name === "v") {
6670
+ const title = annotation ? ` title="${escapeHtml(annotation)}"` : "";
6671
+ return `<span${classAttr}${title}>`;
6672
+ }
6673
+ if (name === "lang") {
6674
+ const lang = annotation ? ` lang="${escapeHtml(annotation)}"` : "";
6675
+ return `<span${classAttr}${lang}>`;
6676
+ }
6677
+ if (name === "c") return `<span${classAttr}>`;
6678
+ return "";
6679
+ }
6680
+ function closeTag(name) {
6681
+ if (PASSTHROUGH_TAGS.has(name)) return `</${name}>`;
6682
+ if (SPAN_TAGS.has(name)) return "</span>";
6683
+ return "";
6684
+ }
6685
+ function renderCueText(text) {
6686
+ var _a;
6687
+ let html = "";
6688
+ for (const token of (_a = text.match(/<[^<>]*>|[^<]+|</g)) != null ? _a : []) {
6689
+ if (token[0] !== "<" || token === "<") {
6690
+ html += escapeHtml(token).replace(/\n/g, "<br>");
6691
+ } else {
6692
+ const inner = token.slice(1, -1);
6693
+ html += inner[0] === "/" ? closeTag(
6694
+ inner.slice(1).split(/[.\s]/, 1)[0].toLowerCase()
6695
+ ) : openTag(inner);
6696
+ }
6697
+ }
6698
+ return html;
6699
+ }
6700
+ function scopeCueRules(css) {
6701
+ return css.replace(/::cue\(([^)]*)\)/g, ".vinyl-text-cue $1").replace(/::cue\b/g, ".vinyl-text-cue");
6702
+ }
6703
+ var HtmlTextTrackRenderer = class {
6704
+ constructor() {
6705
+ /** The overlay container to mount over the video. */
6706
+ __publicField(this, "element");
6707
+ __publicField(this, "track", null);
6708
+ // Holds the authored STYLE-block CSS (::cue rules rewritten to target our
6709
+ // cue elements). A <style> renders nothing itself, so it lives in-container.
6710
+ __publicField(this, "styleElement");
6711
+ __publicField(this, "onCueChange", () => this.renderActiveCues());
6712
+ this.element = document.createElement("div");
6713
+ this.element.className = "vinyl-text-container";
6714
+ Object.assign(this.element.style, {
6715
+ display: "flex",
6716
+ flexDirection: "column",
6717
+ justifyContent: "flex-end",
6718
+ alignItems: "center",
6719
+ pointerEvents: "none"
6720
+ });
6721
+ this.styleElement = document.createElement("style");
6722
+ this.element.appendChild(this.styleElement);
6723
+ }
6724
+ setTextTrack(track) {
6725
+ var _a;
6726
+ if (track === this.track) return;
6727
+ (_a = this.track) == null ? void 0 : _a.removeEventListener("cuechange", this.onCueChange);
6728
+ this.track = track;
6729
+ this.styleElement.textContent = "";
6730
+ if (!track) {
6731
+ this.element.replaceChildren(this.styleElement);
6732
+ return;
6733
+ }
6734
+ track.addEventListener("cuechange", this.onCueChange);
6735
+ this.renderActiveCues();
6736
+ }
6737
+ setStyles(styles) {
6738
+ this.styleElement.textContent = styles.map(scopeCueRules).join("\n");
6739
+ }
6740
+ dispose() {
6741
+ this.setTextTrack(null);
6742
+ }
6743
+ renderActiveCues() {
6744
+ var _a;
6745
+ const active = (_a = this.track.activeCues) != null ? _a : [];
6746
+ const children = [this.styleElement];
6747
+ for (let i = 0; i < active.length; i++) {
6748
+ children.push(this.createCueBox(active[i]));
6749
+ }
6750
+ this.element.replaceChildren(...children);
6751
+ }
6752
+ createCueBox(cue) {
6753
+ var _a;
6754
+ const box = document.createElement("div");
6755
+ box.className = "vinyl-text-cue";
6756
+ Object.assign(box.style, computeCueLayout(cue));
6757
+ box.innerHTML = renderCueText((_a = cue.text) != null ? _a : "");
6758
+ return box;
6759
+ }
6760
+ };
6761
+
6762
+ // src/text/mediaTextTrackProvider.ts
6763
+ function createMediaTextTrackProvider(deps) {
6764
+ const { media } = deps;
6765
+ const cache = /* @__PURE__ */ new Map();
6766
+ const isAttached = (track) => {
6767
+ for (let i = 0; i < media.textTracks.length; i++) {
6768
+ if (media.textTracks[i] === track) return true;
6769
+ }
6770
+ return false;
6771
+ };
6772
+ const create = (kind, label, language) => {
6773
+ const track = media.addTextTrack(kind, label, language);
6774
+ return {
6775
+ track,
6776
+ clear() {
6777
+ if (!track.cues) return;
6778
+ const all = Array.from(track.cues);
6779
+ for (const cue of all) track.removeCue(cue);
6780
+ }
6781
+ };
6782
+ };
6783
+ return {
6784
+ getOrCreate(kind, label, language) {
6785
+ const key = `${kind}-${label}-${language}`;
6786
+ const cached = cache.get(key);
6787
+ if (cached && isAttached(cached.track)) return cached;
6788
+ const ref = create(kind, label, language);
6789
+ cache.set(key, ref);
6790
+ return ref;
6791
+ }
6792
+ };
6793
+ }
6794
+
6587
6795
  // src/text/parseWebVtt.ts
6588
6796
  var import_vinyl_util73 = require("@amazon/vinyl-util");
6589
6797
  var WEBVTT_HEADER = "WEBVTT";
6590
- 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.*)?$/;
6798
+ var TIMESTAMP_RE = /^(?:(\d+):)?([0-5]\d):([0-5]\d)\.(\d{3})/;
6591
6799
  function parseWebVtt(input) {
6592
6800
  if (typeof input !== "string") {
6593
6801
  throw new import_vinyl_util73.ValidationError(
@@ -6605,6 +6813,7 @@ function parseWebVtt(input) {
6605
6813
  );
6606
6814
  }
6607
6815
  const cues = [];
6816
+ const styles = [];
6608
6817
  let i = 1;
6609
6818
  while (i < lines.length && lines[i] !== "") i++;
6610
6819
  while (i < lines.length) {
@@ -6612,49 +6821,71 @@ function parseWebVtt(input) {
6612
6821
  i++;
6613
6822
  continue;
6614
6823
  }
6615
- if (lines[i] === "NOTE" || lines[i].startsWith("NOTE ")) {
6824
+ if (lines[i] === "NOTE" || lines[i].startsWith("NOTE ") || lines[i].startsWith("NOTE ") || lines[i] === "REGION") {
6616
6825
  i++;
6617
6826
  while (i < lines.length && lines[i] !== "") i++;
6618
6827
  continue;
6619
6828
  }
6620
- if (lines[i] === "STYLE" || lines[i] === "REGION") {
6829
+ if (lines[i] === "STYLE") {
6621
6830
  i++;
6831
+ const start = i;
6622
6832
  while (i < lines.length && lines[i] !== "") i++;
6833
+ const css = lines.slice(start, i).join("\n").trim();
6834
+ if (css) styles.push(css);
6623
6835
  continue;
6624
6836
  }
6625
6837
  let id = null;
6626
- let timingLine;
6627
- const firstLine = lines[i];
6628
- if (TIME_RE.test(firstLine)) {
6629
- timingLine = firstLine;
6630
- i++;
6631
- } else {
6632
- id = firstLine;
6838
+ if (!lines[i].includes("-->")) {
6839
+ id = lines[i];
6633
6840
  i++;
6634
6841
  if (i >= lines.length) break;
6635
- timingLine = lines[i];
6636
- i++;
6637
6842
  }
6638
- const match = TIME_RE.exec(timingLine);
6639
- if (!match) {
6843
+ const timing = parseTiming(lines[i]);
6844
+ i++;
6845
+ if (!timing) {
6640
6846
  while (i < lines.length && lines[i] !== "") i++;
6641
6847
  continue;
6642
6848
  }
6643
- const startTime = toSeconds(match[1], match[2], match[3], match[4]);
6644
- const endTime = toSeconds(match[5], match[6], match[7], match[8]);
6645
6849
  const payloadLines = [];
6646
6850
  while (i < lines.length && lines[i] !== "") {
6647
6851
  payloadLines.push(lines[i]);
6648
6852
  i++;
6649
6853
  }
6650
- cues.push({
6651
- id,
6652
- startTime,
6653
- endTime,
6654
- text: payloadLines.join("\n")
6655
- });
6854
+ const text2 = payloadLines.join("\n");
6855
+ cues.push(
6856
+ timing.settings === void 0 ? {
6857
+ id,
6858
+ startTime: timing.startTime,
6859
+ endTime: timing.endTime,
6860
+ text: text2
6861
+ } : {
6862
+ id,
6863
+ startTime: timing.startTime,
6864
+ endTime: timing.endTime,
6865
+ text: text2,
6866
+ settings: timing.settings
6867
+ }
6868
+ );
6656
6869
  }
6657
- return { cues };
6870
+ return { cues, styles };
6871
+ }
6872
+ function parseTiming(line) {
6873
+ const arrow = line.indexOf("-->");
6874
+ if (arrow < 0) return null;
6875
+ const before = line.slice(0, arrow).trim();
6876
+ const start = TIMESTAMP_RE.exec(before);
6877
+ if (!start || start[0].length !== before.length) return null;
6878
+ const rest = line.slice(arrow + 3).trim();
6879
+ const end = TIMESTAMP_RE.exec(rest);
6880
+ if (!end) return null;
6881
+ return {
6882
+ startTime: toSeconds(start[1], start[2], start[3], start[4]),
6883
+ endTime: toSeconds(end[1], end[2], end[3], end[4]),
6884
+ settings: parseCueSettings(rest.slice(end[0].length))
6885
+ };
6886
+ }
6887
+ function toSeconds(hours, minutes, seconds, millis) {
6888
+ return (hours ? Number(hours) * 3600 : 0) + Number(minutes) * 60 + Number(seconds) + Number(millis) / 1e3;
6658
6889
  }
6659
6890
  function isWebVttHeader(line) {
6660
6891
  if (!line.startsWith(WEBVTT_HEADER)) return false;
@@ -6662,18 +6893,80 @@ function isWebVttHeader(line) {
6662
6893
  const next = line.charCodeAt(WEBVTT_HEADER.length);
6663
6894
  return next === 32 || next === 9;
6664
6895
  }
6665
- function toSeconds(hours, minutes, seconds, millis) {
6666
- const h = hours ? Number(hours) : 0;
6667
- const m = Number(minutes);
6668
- const s = Number(seconds);
6669
- const ms = Number(millis);
6670
- return h * 3600 + m * 60 + s + ms / 1e3;
6896
+ var ALIGN = /* @__PURE__ */ new Set(["start", "center", "end", "left", "right"]);
6897
+ var LINE_ALIGN = /* @__PURE__ */ new Set(["start", "center", "end"]);
6898
+ var POSITION_ALIGN = /* @__PURE__ */ new Set(["line-left", "center", "line-right", "auto"]);
6899
+ var VERTICAL = /* @__PURE__ */ new Set(["rl", "lr"]);
6900
+ function parseCueSettings(text) {
6901
+ if (!text) return void 0;
6902
+ const settings = {};
6903
+ for (const token of text.trim().split(/\s+/)) {
6904
+ const colon = token.indexOf(":");
6905
+ if (colon <= 0) continue;
6906
+ const key = token.slice(0, colon);
6907
+ const value = token.slice(colon + 1);
6908
+ switch (key) {
6909
+ case "align": {
6910
+ const align = value === "middle" ? "center" : value;
6911
+ if (ALIGN.has(align)) settings.align = align;
6912
+ break;
6913
+ }
6914
+ case "vertical":
6915
+ if (VERTICAL.has(value))
6916
+ settings.vertical = value;
6917
+ break;
6918
+ case "size": {
6919
+ const size = parsePercent(value);
6920
+ if (size != null) settings.size = size;
6921
+ break;
6922
+ }
6923
+ case "line":
6924
+ parseLine(value, settings);
6925
+ break;
6926
+ case "position":
6927
+ parsePosition(value, settings);
6928
+ break;
6929
+ }
6930
+ }
6931
+ return Object.keys(settings).length > 0 ? settings : void 0;
6932
+ }
6933
+ function parseLine(value, settings) {
6934
+ const [pos, align] = value.split(",");
6935
+ if (pos.endsWith("%")) {
6936
+ const percent = parsePercent(pos);
6937
+ if (percent == null) return;
6938
+ settings.line = percent;
6939
+ settings.snapToLines = false;
6940
+ } else {
6941
+ const n = Number(pos);
6942
+ if (!Number.isInteger(n)) return;
6943
+ settings.line = n;
6944
+ settings.snapToLines = true;
6945
+ }
6946
+ const lineAlign = align === "middle" ? "center" : align;
6947
+ if (lineAlign && LINE_ALIGN.has(lineAlign))
6948
+ settings.lineAlign = lineAlign;
6949
+ }
6950
+ function parsePosition(value, settings) {
6951
+ const [pos, align] = value.split(",");
6952
+ const percent = parsePercent(pos);
6953
+ if (percent == null) return;
6954
+ settings.position = percent;
6955
+ const positionAlign = align === "middle" ? "center" : align;
6956
+ if (positionAlign && POSITION_ALIGN.has(positionAlign))
6957
+ settings.positionAlign = positionAlign;
6958
+ }
6959
+ function parsePercent(value) {
6960
+ if (!value.endsWith("%")) return null;
6961
+ const n = Number(value.slice(0, -1));
6962
+ return Number.isFinite(n) ? n : null;
6671
6963
  }
6672
6964
 
6673
6965
  // src/text/pickPreferredTextTrack.ts
6674
6966
  function resolvePreferredTextLanguages(preferred) {
6675
6967
  if (typeof preferred === "string") return [preferred];
6676
6968
  if (preferred) return preferred;
6969
+ if (typeof navigator !== "undefined") return [...navigator.languages];
6677
6970
  return [];
6678
6971
  }
6679
6972
  function pickPreferredTextTrack(tracks, preferred) {
@@ -6716,7 +7009,7 @@ var DEFAULT_TEXT_LOOK_BEHIND = 2;
6716
7009
  var IDLE_POLL_SECONDS = 0.25;
6717
7010
  async function loadWebVttCues(uri, options) {
6718
7011
  var _a, _b, _c;
6719
- const { abort, requestInit, variables, onCues, getCurrentTime } = options;
7012
+ const { abort, requestInit, variables, onCues, onStyles, getCurrentTime } = options;
6720
7013
  const lookAhead = (_a = options.lookAhead) != null ? _a : DEFAULT_TEXT_LOOK_AHEAD;
6721
7014
  const lookBehind = (_b = options.lookBehind) != null ? _b : DEFAULT_TEXT_LOOK_BEHIND;
6722
7015
  const init = requestInit != null ? requestInit : void 0;
@@ -6727,6 +7020,7 @@ async function loadWebVttCues(uri, options) {
6727
7020
  abort,
6728
7021
  variables: variables != null ? variables : void 0,
6729
7022
  onCues,
7023
+ onStyles,
6730
7024
  getCurrentTime,
6731
7025
  lookAhead,
6732
7026
  lookBehind
@@ -6743,13 +7037,15 @@ async function loadWebVttCues(uri, options) {
6743
7037
  abort,
6744
7038
  variables: variables != null ? variables : void 0,
6745
7039
  onCues,
7040
+ onStyles,
6746
7041
  getCurrentTime,
6747
7042
  lookAhead,
6748
7043
  lookBehind
6749
7044
  });
6750
7045
  }
6751
- const cues = parseWebVtt(body).cues;
6752
- if (cues.length > 0) onCues(cues);
7046
+ const doc = parseWebVtt(body);
7047
+ if (doc.cues.length > 0) onCues(doc.cues);
7048
+ if (onStyles && doc.styles.length > 0) onStyles(doc.styles);
6753
7049
  }
6754
7050
  function looksLikeMediaPlaylist(uri) {
6755
7051
  const path = uri.split(/[?#]/)[0];
@@ -6789,8 +7085,9 @@ async function streamMediaPlaylistText(ctx) {
6789
7085
  abort: ctx.abort
6790
7086
  });
6791
7087
  const body = await res.text();
6792
- const cues = parseWebVtt(body).cues;
6793
- if (cues.length > 0) ctx.onCues(cues);
7088
+ const doc = parseWebVtt(body);
7089
+ if (doc.cues.length > 0) ctx.onCues(doc.cues);
7090
+ if (ctx.onStyles && doc.styles.length > 0) ctx.onStyles(doc.styles);
6794
7091
  }
6795
7092
  }
6796
7093
  function pickInWindow(pending, ranges, ctx) {
@@ -6813,7 +7110,7 @@ function pickInWindow(pending, ranges, ctx) {
6813
7110
  }
6814
7111
 
6815
7112
  // src/text/VttCueStyle.ts
6816
- var import_vinyl_validation10 = require("@amazon/vinyl-validation");
7113
+ var import_vinyl_validation11 = require("@amazon/vinyl-validation");
6817
7114
  function isVttCue(cue) {
6818
7115
  return typeof VTTCue !== "undefined" && cue instanceof VTTCue;
6819
7116
  }
@@ -6828,39 +7125,62 @@ function applyVttCueStyle(cue, style) {
6828
7125
  if (style.snapToLines !== void 0) cue.snapToLines = style.snapToLines;
6829
7126
  if (style.vertical !== void 0) cue.vertical = style.vertical;
6830
7127
  }
6831
- var vttCueStyleValidator = /* @__PURE__ */ (0, import_vinyl_validation10.object)({
6832
- align: /* @__PURE__ */ (0, import_vinyl_validation10.isOneOf)("start", "center", "end", "left", "right").optional(),
6833
- line: /* @__PURE__ */ (0, import_vinyl_validation10.number)().or(/* @__PURE__ */ (0, import_vinyl_validation10.isOneOf)("auto")).optional(),
6834
- lineAlign: /* @__PURE__ */ (0, import_vinyl_validation10.isOneOf)("start", "center", "end").optional(),
6835
- position: /* @__PURE__ */ (0, import_vinyl_validation10.number)().or(/* @__PURE__ */ (0, import_vinyl_validation10.isOneOf)("auto")).optional(),
6836
- positionAlign: /* @__PURE__ */ (0, import_vinyl_validation10.isOneOf)(
7128
+ var vttCueStyleValidator = /* @__PURE__ */ (0, import_vinyl_validation11.object)({
7129
+ align: /* @__PURE__ */ (0, import_vinyl_validation11.isOneOf)("start", "center", "end", "left", "right").optional(),
7130
+ line: /* @__PURE__ */ (0, import_vinyl_validation11.number)().or(/* @__PURE__ */ (0, import_vinyl_validation11.isOneOf)("auto")).optional(),
7131
+ lineAlign: /* @__PURE__ */ (0, import_vinyl_validation11.isOneOf)("start", "center", "end").optional(),
7132
+ position: /* @__PURE__ */ (0, import_vinyl_validation11.number)().or(/* @__PURE__ */ (0, import_vinyl_validation11.isOneOf)("auto")).optional(),
7133
+ positionAlign: /* @__PURE__ */ (0, import_vinyl_validation11.isOneOf)(
6837
7134
  "line-left",
6838
7135
  "center",
6839
7136
  "line-right",
6840
7137
  "auto"
6841
7138
  ).optional(),
6842
- size: /* @__PURE__ */ (0, import_vinyl_validation10.number)().optional(),
6843
- snapToLines: /* @__PURE__ */ (0, import_vinyl_validation10.boolean)().optional(),
6844
- vertical: /* @__PURE__ */ (0, import_vinyl_validation10.isOneOf)("", "rl", "lr").optional()
7139
+ size: /* @__PURE__ */ (0, import_vinyl_validation11.number)().optional(),
7140
+ snapToLines: /* @__PURE__ */ (0, import_vinyl_validation11.boolean)().optional(),
7141
+ vertical: /* @__PURE__ */ (0, import_vinyl_validation11.isOneOf)("", "rl", "lr").optional()
6845
7142
  });
6846
7143
 
6847
7144
  // src/text/SidecarTextTrackController.ts
7145
+ function resolveSelectedTrack(tracks, options) {
7146
+ var _a, _b, _c, _d;
7147
+ const mode = (_a = options.enabled) != null ? _a : "forced";
7148
+ if (mode === "off") return null;
7149
+ const selection = (_b = options.selection) != null ? _b : {};
7150
+ if (selection.id != null) {
7151
+ return (_c = tracks.find((t) => t.id === selection.id)) != null ? _c : null;
7152
+ }
7153
+ let pool = tracks;
7154
+ if (selection.kind != null) {
7155
+ pool = pool.filter((t) => t.kind === selection.kind);
7156
+ }
7157
+ const forced = (_d = selection.forced) != null ? _d : mode === "forced";
7158
+ pool = pool.filter((t) => t.forced === forced);
7159
+ return pickPreferredTextTrack(pool, selection.language);
7160
+ }
6848
7161
  var SidecarTextTrackController = class extends import_vinyl_util75.EventHostImpl {
6849
7162
  constructor(deps) {
6850
- var _a, _b;
6851
7163
  super();
6852
7164
  __publicField(this, "deps", deps);
7165
+ // Whether the owning media track is current (rendering allowed). Toggled by
7166
+ // activate()/deactivate() across suspensions such as ad breaks.
7167
+ __publicField(this, "_active", false);
6853
7168
  __publicField(this, "_tracks", []);
6854
- __publicField(this, "_active", null);
6855
- __publicField(this, "_domTrack", null);
6856
- __publicField(this, "loadAbort", null);
6857
- // True once the app has made an explicit selection (including null). Until
6858
- // then, forced tracks auto-select on discovery.
6859
- __publicField(this, "_userSelected", false);
6860
- __publicField(this, "preferredLanguageSub");
6861
- this.preferredLanguageSub = (_b = (_a = deps.preferredTextLanguage) == null ? void 0 : _a.onData((value, previous) => {
6862
- if (previous !== void 0) this.applyPreferredLanguage(value);
6863
- })) != null ? _b : null;
7169
+ __publicField(this, "_activeTextTrack", null);
7170
+ // The DOM text track currently rendering cues, or null when hidden. Owned by
7171
+ // the provider (never created/removed here).
7172
+ __publicField(this, "_ref", null);
7173
+ __publicField(this, "loadAbort", /* @__PURE__ */ (0, import_vinyl_util75.createAbortSlot)());
7174
+ __publicField(this, "disposer", /* @__PURE__ */ (0, import_vinyl_util75.createDisposer)());
7175
+ const { add } = this.disposer;
7176
+ add(deps.options.onData(() => this.refreshSelection()));
7177
+ add(
7178
+ deps.textTracks.onData((tracksPromise) => {
7179
+ tracksPromise.then((tracks) => this.setTracks(tracks)).catch((error) => {
7180
+ (0, import_vinyl_util75.logError)(this, "text tracks promise rejected", error);
7181
+ });
7182
+ })
7183
+ );
6864
7184
  }
6865
7185
  get [Symbol.toStringTag]() {
6866
7186
  return "SidecarTextTrackController";
@@ -6869,120 +7189,89 @@ var SidecarTextTrackController = class extends import_vinyl_util75.EventHostImpl
6869
7189
  return this._tracks;
6870
7190
  }
6871
7191
  get activeTextTrack() {
7192
+ return this._activeTextTrack;
7193
+ }
7194
+ get active() {
6872
7195
  return this._active;
6873
7196
  }
7197
+ get disposed() {
7198
+ return this.disposer.disposed;
7199
+ }
6874
7200
  /**
6875
- * Replaces the discovered text track list. Emits `textTracksChange`. If
6876
- * the previously active track is no longer present, clears the active
6877
- * selection and emits `activeTextTrackChange`.
7201
+ * Replaces the discovered track list, emits `textTracksChange`, then
7202
+ * re-applies the current selection against the new list.
6878
7203
  */
6879
- setTextTracks(tracks) {
6880
- var _a;
6881
- if ((0, import_vinyl_util75.equalDeep)(this._tracks, tracks)) return;
7204
+ setTracks(tracks) {
7205
+ if (this.disposed) return;
6882
7206
  const previous = this._tracks;
7207
+ if ((0, import_vinyl_util75.equalDeep)(previous, tracks)) return;
6883
7208
  this._tracks = tracks;
6884
7209
  this.dispatch("textTracksChange", { previous, current: tracks });
6885
- if (this._active && !tracks.some((t) => t.id === this._active.id)) {
6886
- this.selectById(null);
6887
- }
6888
- const preferred = (_a = this.deps.preferredTextLanguage) == null ? void 0 : _a.value;
6889
- if (preferred != null) {
6890
- this.applyPreferredLanguage(preferred);
6891
- } else if (!this._userSelected && !this._active) {
6892
- const forced = this.pickForcedTrack(tracks);
6893
- if (forced) this.selectById(forced.id);
6894
- }
6895
- }
6896
- setActiveTextTrack(id) {
6897
- this._userSelected = true;
6898
- this.selectById(id);
7210
+ this.refreshSelection();
6899
7211
  }
6900
7212
  /**
6901
- * Selects the track best matching the preferred language(s), or clears the
6902
- * selection when the preference is null or nothing matches.
7213
+ * Recomputes the selection from the current options and track list,
7214
+ * emitting `activeTextTrackChange` on change and (re)rendering when active.
6903
7215
  */
6904
- applyPreferredLanguage(preferred) {
6905
- var _a;
6906
- const target = pickPreferredTextTrack(this._tracks, preferred);
6907
- this.setActiveTextTrack((_a = target == null ? void 0 : target.id) != null ? _a : null);
6908
- }
6909
- /**
6910
- * Applies a selection by id (null clears it) without marking it as an
6911
- * explicit user choice. Shared by setActiveTextTrack and forced auto-select.
6912
- */
6913
- selectById(id) {
6914
- var _a, _b;
6915
- const next = id == null ? null : this._tracks.find((t) => t.id === id);
6916
- if (id != null && !next) return;
6917
- const target = next != null ? next : null;
6918
- if ((target == null ? void 0 : target.id) === ((_a = this._active) == null ? void 0 : _a.id)) return;
6919
- const previous = this._active;
6920
- this.clearDomTrack();
6921
- (_b = this.loadAbort) == null ? void 0 : _b.abort();
6922
- this.loadAbort = null;
6923
- this._active = target;
6924
- this.dispatch("activeTextTrackChange", {
6925
- previous,
6926
- current: target
6927
- });
6928
- if (target) this.startLoad(target);
6929
- }
6930
- /**
6931
- * The forced track to auto-select, or null. Prefers the default track's
6932
- * language, else the first forced track.
6933
- */
6934
- pickForcedTrack(tracks) {
6935
- var _a;
6936
- const forced = tracks.filter((t) => t.forced);
6937
- if (forced.length === 0) return null;
6938
- const defaultLang = (_a = tracks.find((t) => t.default)) == null ? void 0 : _a.language;
6939
- if (defaultLang != null) {
6940
- const match = forced.find((t) => t.language === defaultLang);
6941
- if (match) return match;
7216
+ refreshSelection() {
7217
+ const previous = this._activeTextTrack;
7218
+ const target = resolveSelectedTrack(
7219
+ this._tracks,
7220
+ this.deps.options.value
7221
+ );
7222
+ const trackChanged = (target == null ? void 0 : target.id) !== (previous == null ? void 0 : previous.id);
7223
+ if (trackChanged) {
7224
+ this._activeTextTrack = target;
7225
+ this.dispatch("activeTextTrackChange", {
7226
+ previous,
7227
+ current: target
7228
+ });
6942
7229
  }
6943
- return forced[0];
6944
- }
6945
- suspend() {
6946
- var _a;
6947
- (_a = this.loadAbort) == null ? void 0 : _a.abort();
6948
- this.loadAbort = null;
6949
- this.clearDomTrack();
7230
+ if (!this._active) return;
7231
+ if (!target) this.hideCurrent();
7232
+ else if (trackChanged || !this._ref) this.startLoad(target);
6950
7233
  }
6951
- resume() {
6952
- if (!this._active || this._domTrack) return;
6953
- this.startLoad(this._active);
7234
+ deactivate() {
7235
+ this._active = false;
7236
+ this.hideCurrent();
6954
7237
  }
6955
- /**
6956
- * Cancels any in-flight load, clears the DOM TextTrack, and resets state.
6957
- * Called by the host when the underlying media is unloaded.
6958
- */
6959
- dispose() {
6960
- var _a, _b;
6961
- super.dispose();
6962
- (_a = this.preferredLanguageSub) == null ? void 0 : _a.call(this);
6963
- (_b = this.loadAbort) == null ? void 0 : _b.abort();
6964
- this.loadAbort = null;
6965
- this.clearDomTrack();
6966
- this._tracks = [];
6967
- this._active = null;
7238
+ activate() {
7239
+ this._active = true;
7240
+ if (!this._activeTextTrack || this._ref) return;
7241
+ this.startLoad(this._activeTextTrack);
6968
7242
  }
6969
7243
  startLoad(track) {
6970
- const media = this.deps.media;
6971
- if (!media) return;
6972
- const abort = new import_vinyl_util75.Abort();
6973
- this.loadAbort = abort;
6974
- const dom = this.ensureDomTrack(media, track);
7244
+ var _a, _b;
7245
+ this.hideCurrent();
7246
+ const abort = this.loadAbort.value;
7247
+ const ref = this.deps.textTrackProvider.getOrCreate(
7248
+ track.kind,
7249
+ track.label,
7250
+ (_a = track.language) != null ? _a : void 0
7251
+ );
7252
+ const renderer = this.deps.textTrackRenderer;
7253
+ ref.track.mode = renderer ? "hidden" : "showing";
7254
+ ref.clear();
7255
+ this._ref = ref;
7256
+ renderer == null ? void 0 : renderer.setTextTrack(ref.track);
6975
7257
  const CueCtor = getVttCueConstructor();
6976
7258
  const seen = /* @__PURE__ */ new Set();
7259
+ const styles = /* @__PURE__ */ new Set();
7260
+ const setStyles = (_b = renderer == null ? void 0 : renderer.setStyles) == null ? void 0 : _b.bind(renderer);
6977
7261
  loadWebVttCues(track.uri, {
6978
7262
  abort,
6979
7263
  requestInit: this.deps.requestInit,
6980
7264
  variables: track.variables,
6981
- getCurrentTime: () => media.currentTime,
7265
+ getCurrentTime: () => this.deps.playbackController.currentTime,
6982
7266
  onCues: (cues) => {
6983
7267
  if (abort.aborted()) return;
6984
- if (CueCtor) this.appendCues(dom, CueCtor, cues, seen);
6985
- }
7268
+ if (CueCtor) this.appendCues(ref.track, CueCtor, cues, seen);
7269
+ },
7270
+ onStyles: setStyles ? (blocks) => {
7271
+ if (abort.aborted()) return;
7272
+ for (const block of blocks) styles.add(block);
7273
+ setStyles([...styles]);
7274
+ } : void 0
6986
7275
  }).catch((error) => {
6987
7276
  if (abort.aborted()) return;
6988
7277
  this.dispatch("textTrackError", {
@@ -6991,43 +7280,45 @@ var SidecarTextTrackController = class extends import_vinyl_util75.EventHostImpl
6991
7280
  });
6992
7281
  });
6993
7282
  }
6994
- ensureDomTrack(media, track) {
6995
- var _a;
6996
- const dom = media.addTextTrack(
6997
- track.kind,
6998
- track.label,
6999
- (_a = track.language) != null ? _a : void 0
7000
- );
7001
- dom.mode = "showing";
7002
- this._domTrack = dom;
7003
- return dom;
7004
- }
7005
7283
  appendCues(dom, CueCtor, cues, seen) {
7006
- var _a;
7007
7284
  for (const cue of cues) {
7008
7285
  const key = `${cue.startTime}|${cue.endTime}|${cue.text}`;
7009
7286
  if (seen.has(key)) continue;
7010
7287
  seen.add(key);
7011
7288
  const domCue = new CueCtor(cue.startTime, cue.endTime, cue.text);
7012
7289
  if (cue.id != null) domCue.id = cue.id;
7013
- const cueStyle = (_a = this.deps.cueStyle) == null ? void 0 : _a.value;
7014
- if (cueStyle && isVttCue(domCue)) {
7015
- applyVttCueStyle(domCue, cueStyle);
7290
+ if (cue.settings && isVttCue(domCue)) {
7291
+ applyVttCueStyle(domCue, cue.settings);
7016
7292
  }
7017
7293
  dom.addCue(domCue);
7018
7294
  }
7019
7295
  }
7020
- clearDomTrack() {
7021
- const dom = this._domTrack;
7022
- if (!dom) return;
7023
- dom.mode = "disabled";
7024
- if (dom.cues) {
7025
- const all = Array.from(
7026
- dom.cues
7027
- );
7028
- for (const cue of all) dom.removeCue(cue);
7029
- }
7030
- this._domTrack = null;
7296
+ /**
7297
+ * Clears cues from the current DOM track and hides it, keeping the track for
7298
+ * later reuse via the provider.
7299
+ */
7300
+ hideCurrent() {
7301
+ var _a;
7302
+ this.loadAbort.abort();
7303
+ const ref = this._ref;
7304
+ if (!ref) return;
7305
+ (_a = this.deps.textTrackRenderer) == null ? void 0 : _a.setTextTrack(null);
7306
+ ref.clear();
7307
+ ref.track.mode = "disabled";
7308
+ this._ref = null;
7309
+ }
7310
+ /**
7311
+ * Cancels any in-flight load, hides the DOM text track, and resets state.
7312
+ * Called by the host when the underlying media is unloaded.
7313
+ */
7314
+ dispose() {
7315
+ if (this.disposed) return;
7316
+ super.dispose();
7317
+ this.loadAbort.abort();
7318
+ this.hideCurrent();
7319
+ this.disposer.dispose();
7320
+ this._tracks = [];
7321
+ this._activeTextTrack = null;
7031
7322
  }
7032
7323
  };
7033
7324
  function getVttCueConstructor() {
@@ -7037,6 +7328,24 @@ function getVttCueConstructor() {
7037
7328
  }
7038
7329
 
7039
7330
  // src/text/TextTrack.ts
7331
+ var import_vinyl_validation12 = require("@amazon/vinyl-validation");
7332
+ var TEXT_TRACK_KINDS = [
7333
+ "subtitles",
7334
+ "captions",
7335
+ "descriptions",
7336
+ "chapters",
7337
+ "metadata"
7338
+ ];
7339
+ var textTrackSelectionValidator = /* @__PURE__ */ (0, import_vinyl_validation12.object)({
7340
+ id: /* @__PURE__ */ (0, import_vinyl_validation12.string)().orNull().optional(),
7341
+ kind: /* @__PURE__ */ (0, import_vinyl_validation12.isOneOf)(...TEXT_TRACK_KINDS).orNull().optional(),
7342
+ language: /* @__PURE__ */ (0, import_vinyl_validation12.string)().or(/* @__PURE__ */ (0, import_vinyl_validation12.array)(/* @__PURE__ */ (0, import_vinyl_validation12.string)()).readonly()).orNull().optional(),
7343
+ forced: /* @__PURE__ */ (0, import_vinyl_validation12.boolean)().orNull().optional()
7344
+ });
7345
+ var textTrackControllerOptionsValidator = /* @__PURE__ */ (0, import_vinyl_validation12.object)({
7346
+ enabled: /* @__PURE__ */ (0, import_vinyl_validation12.isOneOf)("on", "off", "forced").orNull().optional(),
7347
+ selection: /* @__PURE__ */ textTrackSelectionValidator.orNull().optional()
7348
+ });
7040
7349
  var ALL_TEXT_TRACK_EVENTS = [
7041
7350
  "textTracksChange",
7042
7351
  "activeTextTrackChange",
@@ -7194,21 +7503,21 @@ function createSegmentDataProvider(deps, options) {
7194
7503
 
7195
7504
  // src/track/TrackFactory.ts
7196
7505
  var import_vinyl_util78 = require("@amazon/vinyl-util");
7197
- var import_vinyl_validation11 = require("@amazon/vinyl-validation");
7198
- var trackConfigOptionsValidator = /* @__PURE__ */ (0, import_vinyl_validation11.object)({
7199
- extra: /* @__PURE__ */ (0, import_vinyl_validation11.any)().optional(),
7200
- startTime: /* @__PURE__ */ (0, import_vinyl_validation11.number)().maybe().optional(),
7506
+ var import_vinyl_validation13 = require("@amazon/vinyl-validation");
7507
+ var trackConfigOptionsValidator = /* @__PURE__ */ (0, import_vinyl_validation13.object)({
7508
+ extra: /* @__PURE__ */ (0, import_vinyl_validation13.any)().optional(),
7509
+ startTime: /* @__PURE__ */ (0, import_vinyl_validation13.number)().maybe().optional(),
7201
7510
  drm: /* @__PURE__ */ drmOptionsValidator.partial().optional()
7202
7511
  });
7203
- var trackLoadOptionsValidator = /* @__PURE__ */ (0, import_vinyl_validation11.object)(
7512
+ var trackLoadOptionsValidator = /* @__PURE__ */ (0, import_vinyl_validation13.object)(
7204
7513
  {
7205
- type: /* @__PURE__ */ (0, import_vinyl_validation11.string)(),
7206
- uri: /* @__PURE__ */ (0, import_vinyl_validation11.string)().notEmpty(),
7514
+ type: /* @__PURE__ */ (0, import_vinyl_validation13.string)(),
7515
+ uri: /* @__PURE__ */ (0, import_vinyl_validation13.string)().notEmpty(),
7207
7516
  config: /* @__PURE__ */ trackConfigOptionsValidator.maybe().optional()
7208
7517
  }
7209
7518
  );
7210
7519
  function createTrackFactory(factories) {
7211
- const typeValidator = (0, import_vinyl_validation11.isOneOf)(...(0, import_vinyl_util78.ownKeys)(factories));
7520
+ const typeValidator = (0, import_vinyl_validation13.isOneOf)(...(0, import_vinyl_util78.ownKeys)(factories));
7212
7521
  return {
7213
7522
  validate(options) {
7214
7523
  typeValidator.assert(options.type, import_vinyl_util78.ErrorOrigin.API);
@@ -7222,7 +7531,7 @@ function createTrackFactory(factories) {
7222
7531
 
7223
7532
  // src/track/source/SourceObjectTrack.ts
7224
7533
  var import_vinyl_util82 = require("@amazon/vinyl-util");
7225
- var import_vinyl_validation12 = require("@amazon/vinyl-validation");
7534
+ var import_vinyl_validation14 = require("@amazon/vinyl-validation");
7226
7535
 
7227
7536
  // src/track/TrackBase.ts
7228
7537
  var import_vinyl_util79 = require("@amazon/vinyl-util");
@@ -7564,8 +7873,8 @@ var SourceTrackBase = class extends TrackBase {
7564
7873
 
7565
7874
  // src/track/source/SourceObjectTrack.ts
7566
7875
  var loadOptionsValidator = /* @__PURE__ */ trackLoadOptionsValidator.extend({
7567
- srcObjectProvider: /* @__PURE__ */ (0, import_vinyl_validation12.func)(),
7568
- type: /* @__PURE__ */ (0, import_vinyl_validation12.isOneOf)("srcObject"),
7876
+ srcObjectProvider: /* @__PURE__ */ (0, import_vinyl_validation14.func)(),
7877
+ type: /* @__PURE__ */ (0, import_vinyl_validation14.isOneOf)("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
  var import_vinyl_util83 = require("@amazon/vinyl-util");
7605
- var import_vinyl_validation13 = require("@amazon/vinyl-validation");
7914
+ var import_vinyl_validation15 = require("@amazon/vinyl-validation");
7606
7915
  var loadOptionsValidator2 = /* @__PURE__ */ trackLoadOptionsValidator.extend({
7607
7916
  config: /* @__PURE__ */ sourceTrackBaseOptionsValidator.maybe().optional(),
7608
- srcProvider: /* @__PURE__ */ (0, import_vinyl_validation13.func)().maybe().optional(),
7609
- type: /* @__PURE__ */ (0, import_vinyl_validation13.isOneOf)("src")
7917
+ srcProvider: /* @__PURE__ */ (0, import_vinyl_validation15.func)().maybe().optional(),
7918
+ type: /* @__PURE__ */ (0, import_vinyl_validation15.isOneOf)("src")
7610
7919
  });
7611
7920
  function createSourceTrackFactory(deps) {
7612
7921
  return {
@@ -7642,7 +7951,7 @@ var SourceTrack = class extends SourceTrackBase {
7642
7951
 
7643
7952
  // src/track/dash/DashTrack.ts
7644
7953
  var import_vinyl_util85 = require("@amazon/vinyl-util");
7645
- var import_vinyl_validation14 = require("@amazon/vinyl-validation");
7954
+ var import_vinyl_validation16 = require("@amazon/vinyl-validation");
7646
7955
 
7647
7956
  // src/track/mse/MseTrack.ts
7648
7957
  var import_vinyl_util84 = require("@amazon/vinyl-util");
@@ -7713,7 +8022,7 @@ var MseTrack = class extends TrackBase {
7713
8022
  )
7714
8023
  );
7715
8024
  add(
7716
- deps.preferredAudioLanguage.onData((_value, previous) => {
8025
+ deps.audio.onData((_value, previous) => {
7717
8026
  if (previous !== void 0) this.reloadStreams();
7718
8027
  })
7719
8028
  );
@@ -7722,11 +8031,6 @@ var MseTrack = class extends TrackBase {
7722
8031
  if (previous !== void 0) this.reloadStreams();
7723
8032
  })
7724
8033
  );
7725
- add(
7726
- deps.preferDescriptiveAudio.onData((_value, previous) => {
7727
- if (previous !== void 0) this.reloadStreams();
7728
- })
7729
- );
7730
8034
  add(
7731
8035
  deps.abr.onData((value, previous) => {
7732
8036
  if (previous === void 0) return;
@@ -7933,7 +8237,7 @@ var MseTrack = class extends TrackBase {
7933
8237
  onActivated(loadOptions) {
7934
8238
  var _a;
7935
8239
  if (this.disposed) return;
7936
- (_a = this.deps.textTrackController) == null ? void 0 : _a.resume();
8240
+ (_a = this.deps.textTrackController) == null ? void 0 : _a.activate();
7937
8241
  this.deps.playbackSource.disableRemotePlayback = true;
7938
8242
  this.streams.forEach((stream) => {
7939
8243
  this.deps.drmController.initializeForPlayback(
@@ -7966,7 +8270,7 @@ var MseTrack = class extends TrackBase {
7966
8270
  trackUri: this.uri,
7967
8271
  abort: this.disposeAbort
7968
8272
  });
7969
- (_b = this.deps.textTrackController) == null ? void 0 : _b.suspend();
8273
+ (_b = this.deps.textTrackController) == null ? void 0 : _b.deactivate();
7970
8274
  this.deps.playbackSource.src = null;
7971
8275
  this.deps.playbackSource.load();
7972
8276
  this.deps.mediaSourceController.deactivate();
@@ -8063,10 +8367,10 @@ var MseTrack = class extends TrackBase {
8063
8367
 
8064
8368
  // src/track/dash/DashTrack.ts
8065
8369
  var loadOptionsValidator3 = /* @__PURE__ */ trackLoadOptionsValidator.extend({
8066
- manifestProvider: /* @__PURE__ */ (0, import_vinyl_validation14.func)().maybe().optional(),
8067
- requestInit: /* @__PURE__ */ (0, import_vinyl_validation14.object)({}).cast().maybe().optional(),
8068
- segmentRequestInit: /* @__PURE__ */ (0, import_vinyl_validation14.object)({}).cast().maybe().optional(),
8069
- type: /* @__PURE__ */ (0, import_vinyl_validation14.isOneOf)("dash")
8370
+ manifestProvider: /* @__PURE__ */ (0, import_vinyl_validation16.func)().maybe().optional(),
8371
+ requestInit: /* @__PURE__ */ (0, import_vinyl_validation16.object)({}).cast().maybe().optional(),
8372
+ segmentRequestInit: /* @__PURE__ */ (0, import_vinyl_validation16.object)({}).cast().maybe().optional(),
8373
+ type: /* @__PURE__ */ (0, import_vinyl_validation16.isOneOf)("dash")
8070
8374
  });
8071
8375
  function createDashTrackFactory(deps) {
8072
8376
  return {
@@ -8085,12 +8389,12 @@ function createDashTrackFactory(deps) {
8085
8389
 
8086
8390
  // src/track/hls/HlsTrack.ts
8087
8391
  var import_vinyl_util86 = require("@amazon/vinyl-util");
8088
- var import_vinyl_validation15 = require("@amazon/vinyl-validation");
8392
+ var import_vinyl_validation17 = require("@amazon/vinyl-validation");
8089
8393
  var loadOptionsValidator4 = /* @__PURE__ */ trackLoadOptionsValidator.extend({
8090
- manifestProvider: /* @__PURE__ */ (0, import_vinyl_validation15.func)().maybe().optional(),
8091
- requestInit: /* @__PURE__ */ (0, import_vinyl_validation15.object)({}).cast().maybe().optional(),
8092
- segmentRequestInit: /* @__PURE__ */ (0, import_vinyl_validation15.object)({}).cast().maybe().optional(),
8093
- type: /* @__PURE__ */ (0, import_vinyl_validation15.isOneOf)("hls")
8394
+ manifestProvider: /* @__PURE__ */ (0, import_vinyl_validation17.func)().maybe().optional(),
8395
+ requestInit: /* @__PURE__ */ (0, import_vinyl_validation17.object)({}).cast().maybe().optional(),
8396
+ segmentRequestInit: /* @__PURE__ */ (0, import_vinyl_validation17.object)({}).cast().maybe().optional(),
8397
+ type: /* @__PURE__ */ (0, import_vinyl_validation17.isOneOf)("hls")
8094
8398
  });
8095
8399
  function createHlsTrackFactory(deps) {
8096
8400
  return {
@@ -9043,9 +9347,8 @@ function createDashFactories(options) {
9043
9347
  qualitySelector: (deps2) => new QualitySelectorImpl({
9044
9348
  options: deps2.options.pick("abr")
9045
9349
  }),
9046
- preferredAudioLanguage: (deps2) => deps2.options.pick("preferredAudioLanguage"),
9350
+ audio: (deps2) => deps2.options.pick("audio"),
9047
9351
  allowedContentTypes: (deps2) => deps2.options.pick("allowedContentTypes"),
9048
- preferDescriptiveAudio: (deps2) => deps2.options.pick("preferDescriptiveAudio"),
9049
9352
  abr: (deps2) => deps2.options.pick("abr"),
9050
9353
  manifestTransformed: createDefaultDashManifestTransformer,
9051
9354
  mediaTimeline: (deps2) => deps2.manifestTransformed.map(async (manifestPromise) => {
@@ -9055,26 +9358,21 @@ function createDashFactories(options) {
9055
9358
  mediaTimelineTransformed: createDefaultMediaTimelineTransformer,
9056
9359
  textTrackController: (deps2) => {
9057
9360
  var _a;
9058
- const controller = new SidecarTextTrackController({
9059
- media: deps2.media,
9361
+ return new SidecarTextTrackController({
9362
+ textTrackProvider: deps2.textTrackProvider,
9363
+ textTrackRenderer: deps2.textTrackRenderer,
9364
+ playbackController: deps2.playbackController,
9060
9365
  requestInit: (_a = loadOptions.requestInit) != null ? _a : void 0,
9061
- preferredTextLanguage: deps2.options.pick(
9062
- "preferredTextLanguage"
9063
- ),
9064
- cueStyle: deps2.options.pick("textCueStyle")
9065
- });
9066
- deps2.manifestTransformed.onData((manifestPromise) => {
9067
- manifestPromise.then((data3) => {
9068
- controller.setTextTracks(
9069
- discoverDashTextTracks(
9366
+ options: deps2.options.pick("text"),
9367
+ textTracks: deps2.manifestTransformed.map(
9368
+ (manifestPromise) => manifestPromise.then(
9369
+ (data3) => discoverDashTextTracks(
9070
9370
  data3.manifest,
9071
9371
  data3.baseUrl
9072
9372
  )
9073
- );
9074
- }).catch(() => {
9075
- });
9373
+ )
9374
+ )
9076
9375
  });
9077
- return controller;
9078
9376
  }
9079
9377
  }));
9080
9378
  };
@@ -9456,9 +9754,8 @@ function createHlsFactories(options) {
9456
9754
  qualitySelector: (deps2) => new QualitySelectorImpl({
9457
9755
  options: deps2.options.pick("abr")
9458
9756
  }),
9459
- preferredAudioLanguage: (deps2) => deps2.options.pick("preferredAudioLanguage"),
9757
+ audio: (deps2) => deps2.options.pick("audio"),
9460
9758
  allowedContentTypes: (deps2) => deps2.options.pick("allowedContentTypes"),
9461
- preferDescriptiveAudio: (deps2) => deps2.options.pick("preferDescriptiveAudio"),
9462
9759
  abr: (deps2) => deps2.options.pick("abr"),
9463
9760
  mediaTimeline: (deps2) => deps2.manifestTransformed.map(async (manifestPromise) => {
9464
9761
  const data3 = await manifestPromise;
@@ -9467,26 +9764,21 @@ function createHlsFactories(options) {
9467
9764
  mediaTimelineTransformed: createDefaultMediaTimelineTransformer,
9468
9765
  textTrackController: (deps2) => {
9469
9766
  var _a;
9470
- const controller = new SidecarTextTrackController({
9471
- media: deps2.media,
9767
+ return new SidecarTextTrackController({
9768
+ textTrackProvider: deps2.textTrackProvider,
9769
+ textTrackRenderer: deps2.textTrackRenderer,
9770
+ playbackController: deps2.playbackController,
9472
9771
  requestInit: (_a = loadOptions.requestInit) != null ? _a : void 0,
9473
- preferredTextLanguage: deps2.options.pick(
9474
- "preferredTextLanguage"
9475
- ),
9476
- cueStyle: deps2.options.pick("textCueStyle")
9477
- });
9478
- deps2.manifestTransformed.onData((manifestPromise) => {
9479
- manifestPromise.then((data3) => {
9480
- controller.setTextTracks(
9481
- discoverHlsTextTracks(
9772
+ options: deps2.options.pick("text"),
9773
+ textTracks: deps2.manifestTransformed.map(
9774
+ (manifestPromise) => manifestPromise.then(
9775
+ (data3) => discoverHlsTextTracks(
9482
9776
  data3.mainPlaylist,
9483
9777
  data3.baseUrl
9484
9778
  )
9485
- );
9486
- }).catch(() => {
9487
- });
9779
+ )
9780
+ )
9488
9781
  });
9489
- return controller;
9490
9782
  }
9491
9783
  }));
9492
9784
  };
@@ -9637,36 +9929,36 @@ var TrackControllerImpl = class extends import_vinyl_util101.EventHostImpl {
9637
9929
  (0, import_vinyl_util101.logDebug)(this, "more adbreaks");
9638
9930
  return;
9639
9931
  }
9640
- if (adParent.active) {
9641
- (0, import_vinyl_util101.logDebug)(this, "no ads began");
9642
- return;
9643
- }
9644
9932
  const adParentLoad = this._current;
9645
9933
  const placement = event.adBreak.placement;
9646
9934
  const isPreroll = placement === "preroll";
9647
9935
  const isPostroll = placement === "postroll";
9936
+ const noAdBegan = adParent.active;
9937
+ const resumeContent = (startTime) => this.setCurrentTrack(adParent, {
9938
+ config: __spreadProps(__spreadValues({}, adParentLoad.config), { startTime }),
9939
+ isAd: false,
9940
+ checkPreroll: false
9941
+ });
9648
9942
  if (isPostroll) {
9649
9943
  (0, import_vinyl_util101.logDebug)(this, "trackEnded after postroll");
9650
9944
  this.dispatch("trackEnded", { track: adParentLoad });
9651
- }
9652
- if (isPostroll && this.hasNext()) {
9653
- this.next();
9654
- } else {
9655
- const startTime = isPreroll ? (_a = adParentLoad.config) == null ? void 0 : _a.startTime : event.resumePosition;
9656
- this.setCurrentTrack(adParent, {
9657
- config: __spreadProps(__spreadValues({}, adParentLoad.config), {
9658
- startTime
9659
- }),
9660
- isAd: false,
9661
- checkPreroll: false
9662
- });
9663
- if (isPostroll) {
9664
- (0, import_vinyl_util101.logInfo)(this, "queueEnded after postroll ad(s)");
9665
- this.dispatch("queueEnded", {});
9666
- } else {
9667
- playbackController.play().catch(import_vinyl_util101.noop);
9945
+ if (this.hasNext()) {
9946
+ this.next();
9947
+ return;
9668
9948
  }
9949
+ if (!noAdBegan) resumeContent(event.resumePosition);
9950
+ (0, import_vinyl_util101.logInfo)(this, "queueEnded after postroll");
9951
+ this.dispatch("queueEnded", {});
9952
+ return;
9669
9953
  }
9954
+ if (noAdBegan) {
9955
+ (0, import_vinyl_util101.logDebug)(this, "no ads began");
9956
+ return;
9957
+ }
9958
+ resumeContent(
9959
+ isPreroll ? (_a = adParentLoad.config) == null ? void 0 : _a.startTime : event.resumePosition
9960
+ );
9961
+ playbackController.play().catch(import_vinyl_util101.noop);
9670
9962
  })
9671
9963
  );
9672
9964
  }
@@ -10061,28 +10353,28 @@ var defaultPatchOptions = /* @__PURE__ */ (0, import_vinyl_util102.lazy)(() => {
10061
10353
  var import_vinyl_di7 = require("@amazon/vinyl-di");
10062
10354
 
10063
10355
  // src/vinyl/VinylOptions.ts
10064
- var import_vinyl_validation16 = require("@amazon/vinyl-validation");
10356
+ var import_vinyl_validation18 = require("@amazon/vinyl-validation");
10065
10357
  var defaultVinylOptions = {
10066
10358
  abr: defaultQualitySelectorImplOptions,
10067
10359
  loudnessNormalization: defaultLoudnessNormalizationControllerImplOptions,
10068
- preferredAudioLanguage: null,
10069
- preferredTextLanguage: null,
10070
- preferDescriptiveAudio: false,
10360
+ audio: defaultAudioOptions,
10071
10361
  codecOverrides: {},
10072
10362
  allowedContentTypes: null,
10073
- textCueStyle: { size: 90 }
10363
+ text: {
10364
+ // Forced-only captions in the platform's preferred languages (no
10365
+ // explicit language → navigator.languages).
10366
+ enabled: "forced"
10367
+ }
10074
10368
  };
10075
- var vinylOptionsValidator = /* @__PURE__ */ (0, import_vinyl_validation16.object)({
10369
+ var vinylOptionsValidator = /* @__PURE__ */ (0, import_vinyl_validation18.object)({
10076
10370
  abr: qualitySelectorImplOptionsValidator,
10077
10371
  loudnessNormalization: loudnessNormalizationControllerImplOptionsValidator,
10078
- preferredAudioLanguage: /* @__PURE__ */ (0, import_vinyl_validation16.string)().or(/* @__PURE__ */ (0, import_vinyl_validation16.array)(/* @__PURE__ */ (0, import_vinyl_validation16.string)()).readonly()).orNull(),
10079
- preferredTextLanguage: /* @__PURE__ */ (0, import_vinyl_validation16.string)().or(/* @__PURE__ */ (0, import_vinyl_validation16.array)(/* @__PURE__ */ (0, import_vinyl_validation16.string)()).readonly()).orNull(),
10080
- preferDescriptiveAudio: /* @__PURE__ */ (0, import_vinyl_validation16.boolean)(),
10081
- codecOverrides: /* @__PURE__ */ (0, import_vinyl_validation16.record)(/* @__PURE__ */ (0, import_vinyl_validation16.string)(), /* @__PURE__ */ (0, import_vinyl_validation16.isOneOf)("allow", "deny")),
10082
- allowedContentTypes: /* @__PURE__ */ (0, import_vinyl_validation16.array)(/* @__PURE__ */ (0, import_vinyl_validation16.isOneOf)(...RESTRICTABLE_CONTENT_TYPES)).cast().describe(
10372
+ audio: audioOptionsValidator,
10373
+ codecOverrides: /* @__PURE__ */ (0, import_vinyl_validation18.record)(/* @__PURE__ */ (0, import_vinyl_validation18.string)(), /* @__PURE__ */ (0, import_vinyl_validation18.isOneOf)("allow", "deny")),
10374
+ allowedContentTypes: /* @__PURE__ */ (0, import_vinyl_validation18.array)(/* @__PURE__ */ (0, import_vinyl_validation18.isOneOf)(...RESTRICTABLE_CONTENT_TYPES)).readonly().describe(
10083
10375
  "Allow list of media content types (audio, video) to stream; other media streams are ignored. Text tracks are unaffected."
10084
10376
  ).orNull(),
10085
- textCueStyle: /* @__PURE__ */ vttCueStyleValidator.orNull()
10377
+ text: textTrackControllerOptionsValidator
10086
10378
  });
10087
10379
 
10088
10380
  // src/vinyl/playerConfigFactory.ts
@@ -10115,6 +10407,14 @@ function createVinylFactories(options) {
10115
10407
  return patchMediaElement(options.media, patches.media);
10116
10408
  },
10117
10409
  media: (deps) => deps.patchedMedia.patched,
10410
+ // One provider per media element (the player container creates each
10411
+ // dependency once), so text tracks are reused rather than accumulated.
10412
+ textTrackProvider: (deps) => createMediaTextTrackProvider({ media: deps.media }),
10413
+ // App-provided cue renderer (or null for native rendering).
10414
+ textTrackRenderer: () => {
10415
+ var _a2;
10416
+ return (_a2 = options.textTrackRenderer) != null ? _a2 : null;
10417
+ },
10118
10418
  playbackController: (deps) => new PlaybackControllerImpl(deps, options.playbackController),
10119
10419
  playbackSource: (deps) => new PlaybackSourceImpl(deps),
10120
10420
  loudnessNormalizationController: (deps) => new LoudnessNormalizationControllerImpl({
@@ -10239,10 +10539,6 @@ var VinylPlayer = class extends import_vinyl_util104.EventHostImpl {
10239
10539
  const previous = activeTrack;
10240
10540
  if (previous === current) return;
10241
10541
  activeTrack = current;
10242
- const prevTextController = previous == null ? void 0 : previous.textTrackController;
10243
- if (!this.deps.adController.currentAdBreak) {
10244
- prevTextController == null ? void 0 : prevTextController.setActiveTextTrack(null);
10245
- }
10246
10542
  sub == null ? void 0 : sub();
10247
10543
  sub = null;
10248
10544
  textSub == null ? void 0 : textSub();
@@ -10659,16 +10955,6 @@ var VinylPlayer = class extends import_vinyl_util104.EventHostImpl {
10659
10955
  var _a, _b, _c;
10660
10956
  return (_c = (_b = (_a = this.activeTrack) == null ? void 0 : _a.textTrackController) == null ? void 0 : _b.activeTextTrack) != null ? _c : null;
10661
10957
  }
10662
- /**
10663
- * Selects the text track with the given id, or clears the active text
10664
- * track when called with null. No-op when the current track does not
10665
- * surface text tracks or the id is unknown.
10666
- */
10667
- setActiveTextTrack(id) {
10668
- var _a;
10669
- const controller = (_a = this.deps.trackController.activeTrack) == null ? void 0 : _a.textTrackController;
10670
- controller == null ? void 0 : controller.setActiveTextTrack(id);
10671
- }
10672
10958
  emitTextTrackChangeEventsFor(previous, current) {
10673
10959
  var _a, _b, _c, _d, _e, _f;
10674
10960
  const prevList = (_a = previous == null ? void 0 : previous.textTrackController) == null ? void 0 : _a.textTracks;