@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
@@ -2,11 +2,17 @@
2
2
  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { createVinylPlayer, SidecarTextTrackController, } from '@amazon/vinyl';
5
+ import { createVinylPlayer, } from '@amazon/vinyl';
6
6
  import { externalDependencies } from '@amazon/vinyl-di';
7
- import { createMockVinylDependencies, MockTrack, } from '@amazon/vinyl/vinylTestUtil';
7
+ import { createMockVinylDependencies, MockTextTrackController, MockTrack, } from '@amazon/vinyl/vinylTestUtil';
8
8
  import { MockHTMLAudioElement } from '@amazon/vinyl-util/browserTestUtil';
9
9
  import { createEventSpy } from '@amazon/vinyl-util/testUtil';
10
+ /**
11
+ * These tests cover the player's read-through getters and event redispatch
12
+ * across track changes. Selection itself is declarative (driven by
13
+ * `VinylOptions.text`), so the tests drive a {@link MockTextTrackController}'s
14
+ * state and events directly rather than calling any imperative select API.
15
+ */
10
16
  describe('VinylPlayer text track API', () => {
11
17
  let deps;
12
18
  let depFactories;
@@ -19,167 +25,93 @@ describe('VinylPlayer text track API', () => {
19
25
  afterEach(() => {
20
26
  player.dispose();
21
27
  });
28
+ function info(overrides = {}) {
29
+ return {
30
+ id: 't1',
31
+ kind: 'subtitles',
32
+ language: 'en',
33
+ label: 'A',
34
+ default: false,
35
+ forced: false,
36
+ characteristics: [],
37
+ uri: 'a.vtt',
38
+ mimeType: 'text/vtt',
39
+ ...overrides,
40
+ };
41
+ }
22
42
  function makeTrackWithController() {
23
43
  const track = new MockTrack();
24
- const controller = new SidecarTextTrackController({ media: null });
44
+ const controller = new MockTextTrackController();
25
45
  track.textTrackController = controller;
26
46
  return { track, controller };
27
47
  }
48
+ /** Sets the controller's track list and emits the change (as the real one does). */
49
+ function setTracks(controller, tracks) {
50
+ const previous = controller.textTracks;
51
+ controller.textTracks = tracks;
52
+ controller.dispatch('textTracksChange', { previous, current: tracks });
53
+ }
54
+ /** Sets the controller's active selection and emits the change. */
55
+ function setActive(controller, current) {
56
+ const previous = controller.activeTextTrack;
57
+ controller.activeTextTrack = current;
58
+ controller.dispatch('activeTextTrackChange', { previous, current });
59
+ }
60
+ function activate(track) {
61
+ deps.trackController.activeTrack = track;
62
+ deps.trackController.dispatch('trackActivated', { track });
63
+ }
28
64
  it('returns empty defaults when no current track', () => {
29
65
  expect(player.textTracks).toEqual([]);
30
66
  expect(player.activeTextTrack).toBeNull();
31
67
  });
32
68
  it('returns text tracks from the current track', () => {
33
69
  const { track, controller } = makeTrackWithController();
34
- controller.setTextTracks([
35
- {
36
- id: 't1',
37
- kind: 'subtitles',
38
- language: 'en',
39
- label: 'English',
40
- default: false,
41
- forced: false,
42
- characteristics: [],
43
- uri: 'https://x/sub.vtt',
44
- mimeType: 'text/vtt',
45
- },
46
- ]);
47
- deps.trackController.activeTrack = track;
48
- deps.trackController.dispatch('trackActivated', { track: track });
70
+ controller.textTracks = [info()];
71
+ activate(track);
49
72
  expect(player.textTracks.length).toBe(1);
50
73
  });
51
- it('selects an active text track via setActiveTextTrack', () => {
74
+ it('reflects the current track controller active selection', () => {
52
75
  const { track, controller } = makeTrackWithController();
53
- controller.setTextTracks([
54
- {
55
- id: 't1',
56
- kind: 'subtitles',
57
- language: 'en',
58
- label: 'English',
59
- default: false,
60
- forced: false,
61
- characteristics: [],
62
- uri: 'https://x/sub.vtt',
63
- mimeType: 'text/vtt',
64
- },
65
- ]);
66
- deps.trackController.activeTrack = track;
67
- deps.trackController.dispatch('trackActivated', { track: track });
68
- player.setActiveTextTrack('t1');
76
+ controller.textTracks = [info()];
77
+ activate(track);
78
+ setActive(controller, info());
69
79
  expect(player.activeTextTrack?.id).toBe('t1');
70
- player.setActiveTextTrack(null);
80
+ setActive(controller, null);
71
81
  expect(player.activeTextTrack).toBeNull();
72
82
  });
73
- it('ignores setActiveTextTrack when current track has no controller', () => {
83
+ it('reports null active when the current track has no controller', () => {
74
84
  const track = new MockTrack();
75
- deps.trackController.activeTrack = track;
76
- deps.trackController.dispatch('trackActivated', { track: track });
77
- // No throw, and activeTextTrack stays null.
78
- player.setActiveTextTrack('anything');
85
+ activate(track);
79
86
  expect(player.activeTextTrack).toBeNull();
80
87
  });
81
88
  it('redispatches textTracksChange events from the active controller', () => {
82
89
  const { track, controller } = makeTrackWithController();
83
- deps.trackController.activeTrack = track;
84
- deps.trackController.dispatch('trackActivated', { track: track });
90
+ activate(track);
85
91
  const spy = createEventSpy(player, 'textTracksChange');
86
- controller.setTextTracks([
87
- {
88
- id: 't1',
89
- kind: 'subtitles',
90
- language: null,
91
- label: 'A',
92
- default: false,
93
- forced: false,
94
- characteristics: [],
95
- uri: 'a.vtt',
96
- mimeType: 'text/vtt',
97
- },
98
- ]);
92
+ setTracks(controller, [info({ language: null })]);
99
93
  expect(spy).toHaveBeenCalled();
100
94
  });
101
- it('fires textTracksChange when switching to a track with different list', () => {
95
+ it('fires textTracksChange when switching to a track with a different list', () => {
102
96
  const a = makeTrackWithController();
103
97
  const b = makeTrackWithController();
104
- const trackInfoA = {
105
- id: 't1',
106
- kind: 'subtitles',
107
- language: 'en',
108
- label: 'A',
109
- default: false,
110
- forced: false,
111
- characteristics: [],
112
- uri: 'a.vtt',
113
- mimeType: 'text/vtt',
114
- };
115
- const trackInfoB = {
116
- id: 't2',
117
- kind: 'subtitles',
118
- language: 'fr',
119
- label: 'B',
120
- default: false,
121
- forced: false,
122
- characteristics: [],
123
- uri: 'b.vtt',
124
- mimeType: 'text/vtt',
125
- };
126
- a.controller.setTextTracks([trackInfoA]);
127
- b.controller.setTextTracks([trackInfoB]);
128
- deps.trackController.activeTrack = a.track;
129
- deps.trackController.dispatch('trackActivated', { track: a.track });
98
+ setTracks(a.controller, [info({ id: 't1', language: 'en' })]);
99
+ setTracks(b.controller, [
100
+ info({ id: 't2', language: 'fr', label: 'B' }),
101
+ ]);
102
+ activate(a.track);
130
103
  const spy = createEventSpy(player, 'textTracksChange');
131
- deps.trackController.activeTrack = b.track;
132
- deps.trackController.dispatch('trackActivated', { track: b.track });
104
+ activate(b.track);
133
105
  expect(spy).toHaveBeenCalled();
134
106
  });
135
- it("deactivates the previous track's captions on trackDeactivated", () => {
136
- // Tracks are cached, not disposed, when unloaded. The previous
137
- // controller retains its DOM TextTrack unless we deactivate it.
138
- const a = makeTrackWithController();
139
- a.controller.setTextTracks([
140
- {
141
- id: 't1',
142
- kind: 'subtitles',
143
- language: 'en',
144
- label: 'A',
145
- default: false,
146
- forced: false,
147
- characteristics: [],
148
- uri: 'a.vtt',
149
- mimeType: 'text/vtt',
150
- },
151
- ]);
152
- deps.trackController.activeTrack = a.track;
153
- deps.trackController.dispatch('trackActivated', { track: a.track });
154
- a.controller.setActiveTextTrack('t1');
155
- expect(a.controller.activeTextTrack?.id).toBe('t1');
156
- // Unload: current → null.
157
- deps.trackController.activeTrack = null;
158
- deps.trackController.dispatch('trackDeactivated', { track: a.track });
159
- expect(a.controller.activeTextTrack).toBeNull();
160
- });
161
107
  it('fires activeTextTrackChange when switching tracks', () => {
162
108
  const a = makeTrackWithController();
163
109
  const b = makeTrackWithController();
164
- a.controller.setTextTracks([
165
- {
166
- id: 't1',
167
- kind: 'subtitles',
168
- language: 'en',
169
- label: 'A',
170
- default: false,
171
- forced: false,
172
- characteristics: [],
173
- uri: 'a.vtt',
174
- mimeType: 'text/vtt',
175
- },
176
- ]);
177
- a.controller.setActiveTextTrack('t1');
178
- deps.trackController.activeTrack = a.track;
179
- deps.trackController.dispatch('trackActivated', { track: a.track });
110
+ setTracks(a.controller, [info({ id: 't1' })]);
111
+ setActive(a.controller, info({ id: 't1' }));
112
+ activate(a.track);
180
113
  const spy = createEventSpy(player, 'activeTextTrackChange');
181
- deps.trackController.activeTrack = b.track;
182
- deps.trackController.dispatch('trackActivated', { track: b.track });
114
+ activate(b.track);
183
115
  expect(spy).toHaveBeenCalled();
184
116
  });
185
117
  it('re-announces the content caption after an ad break so it does not read as off', () => {
@@ -187,59 +119,35 @@ describe('VinylPlayer text track API', () => {
187
119
  // resume left consumers that track state via activeTextTrackChange
188
120
  // believing captions were off, because the outgoing ad controller emits
189
121
  // a clearing activeTextTrackChange(null) while the content's preserved
190
- // (here forced) selection is restored silently by resume().
122
+ // (here forced) selection is restored silently on activate().
191
123
  const content = makeTrackWithController();
192
- content.controller.setTextTracks([
193
- {
194
- id: 'c-forced',
195
- kind: 'subtitles',
196
- language: 'en',
197
- label: 'English (Forced)',
198
- default: true,
199
- forced: true,
200
- characteristics: [],
201
- uri: 'c.vtt',
202
- mimeType: 'text/vtt',
203
- },
204
- ]);
205
- // Forced caption auto-selects for content.
206
- expect(content.controller.activeTextTrack?.id).toBe('c-forced');
124
+ const contentForced = info({
125
+ id: 'c-forced',
126
+ label: 'English (Forced)',
127
+ default: true,
128
+ forced: true,
129
+ uri: 'c.vtt',
130
+ });
131
+ setTracks(content.controller, [contentForced]);
132
+ setActive(content.controller, contentForced);
207
133
  const ad = makeTrackWithController();
208
- ad.controller.setTextTracks([
209
- {
210
- id: 'ad-cc',
211
- kind: 'subtitles',
212
- language: 'en',
213
- label: 'English',
214
- default: false,
215
- forced: false,
216
- characteristics: [],
217
- uri: 'ad.vtt',
218
- mimeType: 'text/vtt',
219
- },
220
- ]);
134
+ const adCc = info({ id: 'ad-cc', label: 'English', uri: 'ad.vtt' });
135
+ setTracks(ad.controller, [adCc]);
221
136
  // Content becomes current.
222
- deps.trackController.activeTrack = content.track;
223
- deps.trackController.dispatch('trackActivated', {
224
- track: content.track,
225
- });
226
- // Enter the ad break: the swap preserves the content selection
227
- // (suspend keeps _active) rather than clearing it.
137
+ activate(content.track);
138
+ // Enter the ad break: the content selection is preserved (deactivate
139
+ // keeps the selection) rather than cleared.
228
140
  deps.adController.currentAdBreak = { placement: 'midroll' };
229
- content.controller.suspend();
230
- deps.trackController.activeTrack = ad.track;
231
- deps.trackController.dispatch('trackActivated', { track: ad.track });
141
+ content.controller.deactivate();
142
+ activate(ad.track);
232
143
  // Viewer enables the ad's captions during the break.
233
- player.setActiveTextTrack('ad-cc');
144
+ setActive(ad.controller, adCc);
234
145
  expect(player.activeTextTrack?.id).toBe('ad-cc');
235
146
  // Ad ends, content resumes.
236
147
  deps.adController.currentAdBreak = null;
237
148
  const spy = createEventSpy(player, 'activeTextTrackChange');
238
- deps.trackController.activeTrack = content.track;
239
- content.controller.resume();
240
- deps.trackController.dispatch('trackActivated', {
241
- track: content.track,
242
- });
149
+ content.controller.activate();
150
+ activate(content.track);
243
151
  // The player reports the content's forced caption as active again and,
244
152
  // crucially, the last active-change event announces it — not the ad's
245
153
  // clearing null.
@@ -248,16 +156,33 @@ describe('VinylPlayer text track API', () => {
248
156
  const lastCurrent = spy.calls.mostRecent().args[0].current;
249
157
  expect(lastCurrent?.id).toBe('c-forced');
250
158
  });
159
+ it('announces empty tracks and null active when the track is torn down', () => {
160
+ // Real teardown (unload) transitions to null: the player must emit the
161
+ // cleared list/selection so consumers see captions go away.
162
+ const a = makeTrackWithController();
163
+ const t = info({ id: 't1' });
164
+ setTracks(a.controller, [t]);
165
+ setActive(a.controller, t);
166
+ activate(a.track);
167
+ const tracksSpy = createEventSpy(player, 'textTracksChange');
168
+ const activeSpy = createEventSpy(player, 'activeTextTrackChange');
169
+ // trackDeactivated with no ad break tears the current track down to null.
170
+ deps.trackController.activeTrack = null;
171
+ deps.trackController.dispatch('trackDeactivated', { track: a.track });
172
+ expect(tracksSpy).toHaveBeenCalled();
173
+ expect(tracksSpy.calls.mostRecent().args[0].current).toEqual([]);
174
+ expect(activeSpy).toHaveBeenCalled();
175
+ expect(activeSpy.calls.mostRecent().args[0].current).toBeNull();
176
+ expect(player.activeTextTrack).toBeNull();
177
+ });
251
178
  it('does not emit activeTextTrackChange when neither track has an active selection', () => {
252
179
  // Both tracks are text-capable but nothing is active — the current
253
180
  // track change should not manufacture a spurious active-change event.
254
181
  const a = makeTrackWithController();
255
182
  const b = makeTrackWithController();
256
- deps.trackController.activeTrack = a.track;
257
- deps.trackController.dispatch('trackActivated', { track: a.track });
183
+ activate(a.track);
258
184
  const spy = createEventSpy(player, 'activeTextTrackChange');
259
- deps.trackController.activeTrack = b.track;
260
- deps.trackController.dispatch('trackActivated', { track: b.track });
185
+ activate(b.track);
261
186
  expect(spy).not.toHaveBeenCalled();
262
187
  });
263
188
  });
@@ -81,6 +81,8 @@ describe('createVinylFactories', () => {
81
81
  expect(container.dependencies).toEqual(objectContaining({
82
82
  patchedMedia: any(Object),
83
83
  media: any(Object),
84
+ textTrackProvider: any(Object),
85
+ textTrackRenderer: null,
84
86
  playbackController: any(PlaybackControllerImpl),
85
87
  playbackSource: any(PlaybackSourceImpl),
86
88
  loudnessNormalizationController: any(LoudnessNormalizationControllerImpl),
@@ -2407,6 +2407,7 @@ var MockPlaybackSource = class {
2407
2407
 
2408
2408
  // test/vinylTestUtil/mock/player/MockVinylPlayerDependencies.ts
2409
2409
  import {
2410
+ createMediaTextTrackProvider,
2410
2411
  defaultVinylOptions
2411
2412
  } from "@amazon/vinyl";
2412
2413
 
@@ -2491,9 +2492,9 @@ var MockTextTrackController = class extends MockEventHost9 {
2491
2492
  super(...arguments);
2492
2493
  __publicField(this, "textTracks", []);
2493
2494
  __publicField(this, "activeTextTrack", null);
2494
- __publicField(this, "setActiveTextTrack", spyFactory21("setActiveTextTrack"));
2495
- __publicField(this, "suspend", spyFactory21("suspend"));
2496
- __publicField(this, "resume", spyFactory21("resume"));
2495
+ __publicField(this, "active", false);
2496
+ __publicField(this, "deactivate", spyFactory21("deactivate"));
2497
+ __publicField(this, "activate", spyFactory21("activate"));
2497
2498
  }
2498
2499
  };
2499
2500
 
@@ -2533,9 +2534,10 @@ function createMockDashDependencies() {
2533
2534
  mediaQualityMetadataResolver: createSpy().and.callFake(
2534
2535
  () => createEmptyMediaQualityMetadata()
2535
2536
  ),
2536
- preferredAudioLanguage: data3(null),
2537
+ audio: data3({
2538
+ selection: { language: null, descriptive: false }
2539
+ }),
2537
2540
  allowedContentTypes: data3(null),
2538
- preferDescriptiveAudio: data3(false),
2539
2541
  abr: data3(defaultQualitySelectorImplOptions)
2540
2542
  };
2541
2543
  }
@@ -2560,6 +2562,7 @@ import { data as data4 } from "@amazon/vinyl-observable";
2560
2562
  var createSpy2 = jasmine.createSpy;
2561
2563
  function createMockVinylDependencies() {
2562
2564
  const playbackController = new MockPlaybackController();
2565
+ const media = createMockMedia();
2563
2566
  return {
2564
2567
  options: data4(defaultVinylOptions),
2565
2568
  trackController: new MockTrackController(),
@@ -2567,7 +2570,9 @@ function createMockVinylDependencies() {
2567
2570
  playbackController,
2568
2571
  capabilities: new MockCapabilities(),
2569
2572
  drmController: new MockDrmController(),
2570
- media: createMockMedia(),
2573
+ media,
2574
+ textTrackProvider: createMediaTextTrackProvider({ media }),
2575
+ textTrackRenderer: null,
2571
2576
  createDashFactories: (_loadOptions) => externalDependencies(createMockDashDependencies()),
2572
2577
  createHlsFactories: (_loadOptions) => externalDependencies(createMockDashDependencies()),
2573
2578
  autoResetController: new MockAutoResetController(),
@@ -2700,9 +2705,10 @@ function createMockHlsDependencies() {
2700
2705
  mediaQualityMetadataResolver: createSpy3().and.callFake(
2701
2706
  () => createEmptyMediaQualityMetadata2()
2702
2707
  ),
2703
- preferredAudioLanguage: data5(null),
2708
+ audio: data5({
2709
+ selection: { language: null, descriptive: false }
2710
+ }),
2704
2711
  allowedContentTypes: data5(null),
2705
- preferDescriptiveAudio: data5(false),
2706
2712
  abr: data5(defaultQualitySelectorImplOptions2)
2707
2713
  };
2708
2714
  }