shaka-player 4.5.0 → 4.6.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.
- package/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
- package/AUTHORS +2 -0
- package/CHANGELOG.md +109 -0
- package/CODE_OF_CONDUCT.md +1 -1
- package/CONTRIBUTORS +2 -0
- package/README.md +38 -32
- package/demo/common/asset.js +11 -17
- package/demo/common/assets.js +117 -11
- package/demo/config.js +28 -1
- package/demo/custom.js +52 -38
- package/demo/main.js +11 -3
- package/demo/search.js +7 -0
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +133 -124
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +133 -124
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +20 -18
- package/dist/locales.js +34 -30
- package/dist/receiver.compiled.debug.js +58 -50
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +58 -50
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +440 -390
- package/dist/shaka-player.compiled.debug.d.ts +440 -390
- package/dist/shaka-player.compiled.debug.externs.js +162 -77
- package/dist/shaka-player.compiled.debug.js +789 -738
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +162 -77
- package/dist/shaka-player.compiled.js +1147 -1113
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +491 -437
- package/dist/shaka-player.ui.debug.d.ts +491 -437
- package/dist/shaka-player.ui.debug.externs.js +167 -77
- package/dist/shaka-player.ui.debug.js +857 -791
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +167 -77
- package/dist/shaka-player.ui.js +1359 -1314
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/ad_monetization.md +54 -0
- package/docs/tutorials/basic-usage.md +2 -1
- package/docs/tutorials/errors.md +2 -1
- package/docs/tutorials/offline.md +10 -8
- package/docs/tutorials/plugins.md +5 -0
- package/docs/tutorials/ui-customization.md +13 -0
- package/docs/tutorials/ui.md +2 -1
- package/docs/tutorials/upgrade.md +3 -0
- package/externs/managedmediasource.js +24 -0
- package/externs/shaka/abr_manager.js +6 -2
- package/externs/shaka/cea.js +7 -0
- package/externs/shaka/codecs.js +5 -3
- package/externs/shaka/manifest.js +21 -5
- package/externs/shaka/manifest_parser.js +17 -0
- package/externs/shaka/net.js +2 -2
- package/externs/shaka/offline.js +9 -2
- package/externs/shaka/player.js +53 -7
- package/externs/shaka/text.js +3 -1
- package/externs/shaka/transmuxer.js +1 -1
- package/lib/abr/simple_abr_manager.js +25 -8
- package/lib/ads/media_tailor_ad_manager.js +14 -3
- package/lib/cast/cast_receiver.js +1 -1
- package/lib/cea/cea_decoder.js +28 -0
- package/lib/cea/dummy_caption_decoder.js +5 -0
- package/lib/dash/dash_parser.js +251 -84
- package/lib/dash/mpd_utils.js +52 -31
- package/lib/dash/segment_base.js +4 -5
- package/lib/dash/segment_list.js +5 -4
- package/lib/dash/segment_template.js +92 -29
- package/lib/hls/hls_classes.js +28 -43
- package/lib/hls/hls_parser.js +770 -652
- package/lib/hls/hls_utils.js +64 -5
- package/lib/hls/manifest_text_parser.js +7 -11
- package/lib/media/adaptation_set.js +20 -13
- package/lib/media/adaptation_set_criteria.js +70 -18
- package/lib/media/closed_caption_parser.js +13 -0
- package/lib/media/content_workarounds.js +6 -0
- package/lib/media/drm_engine.js +8 -13
- package/lib/media/manifest_parser.js +8 -113
- package/lib/media/media_source_capabilities.js +10 -3
- package/lib/media/media_source_engine.js +75 -21
- package/lib/media/play_rate_controller.js +8 -38
- package/lib/media/presentation_timeline.js +7 -1
- package/lib/media/quality_observer.js +1 -1
- package/lib/media/segment_index.js +5 -5
- package/lib/media/segment_prefetch.js +92 -24
- package/lib/media/segment_reference.js +67 -1
- package/lib/media/segment_utils.js +343 -0
- package/lib/media/stall_detector.js +0 -3
- package/lib/media/streaming_engine.js +72 -44
- package/lib/mss/mss_parser.js +18 -2
- package/lib/net/networking_engine.js +66 -12
- package/lib/net/networking_utils.js +95 -0
- package/lib/offline/indexeddb/v1_storage_cell.js +2 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +2 -0
- package/lib/offline/manifest_converter.js +2 -0
- package/lib/offline/offline_manifest_parser.js +10 -0
- package/lib/offline/storage.js +11 -7
- package/lib/player.js +998 -1503
- package/lib/polyfill/mediasource.js +22 -1
- package/lib/text/mp4_ttml_parser.js +2 -2
- package/lib/text/srt_text_parser.js +2 -2
- package/lib/text/stub_text_displayer.js +51 -0
- package/lib/text/text_engine.js +3 -2
- package/lib/text/ttml_text_parser.js +28 -5
- package/lib/text/ui_text_displayer.js +4 -0
- package/lib/text/vtt_text_parser.js +7 -2
- package/lib/transmuxer/aac_transmuxer.js +1 -1
- package/lib/transmuxer/ac3_transmuxer.js +1 -1
- package/lib/transmuxer/ec3_transmuxer.js +1 -1
- package/lib/transmuxer/h264.js +5 -4
- package/lib/transmuxer/h265.js +5 -4
- package/lib/transmuxer/mp3_transmuxer.js +1 -1
- package/lib/transmuxer/mpeg_ts_transmuxer.js +1 -1
- package/lib/transmuxer/mss_transmuxer.js +1 -1
- package/lib/transmuxer/ts_transmuxer.js +33 -13
- package/lib/util/buffer_utils.js +26 -4
- package/lib/util/content_steering_manager.js +358 -0
- package/lib/util/error.js +2 -6
- package/lib/util/fairplay_utils.js +1 -1
- package/lib/util/fake_event.js +5 -1
- package/lib/util/id3_utils.js +50 -1
- package/lib/util/manifest_parser_utils.js +12 -8
- package/lib/util/mp4_generator.js +2 -4
- package/lib/util/mutex.js +59 -0
- package/lib/util/object_utils.js +1 -1
- package/lib/util/periods.js +154 -179
- package/lib/util/platform.js +4 -3
- package/lib/util/player_configuration.js +35 -6
- package/lib/util/stream_utils.js +105 -98
- package/lib/util/ts_parser.js +124 -73
- package/lib/util/uint8array_utils.js +5 -1
- package/lib/util/xml_utils.js +5 -0
- package/maintained-branches.md +2 -2
- package/package.json +1 -1
- package/roadmap.md +15 -5
- package/shaka-player.uncompiled.js +0 -1
- package/test/abr/simple_abr_manager_unit.js +33 -33
- package/test/ads/ad_manager_unit.js +3 -2
- package/test/cast/cast_receiver_integration.js +3 -4
- package/test/cast/cast_utils_unit.js +2 -0
- package/test/cea/cea_decoder_unit.js +7 -0
- package/test/codec_switching/codec_switching_integration.js +2 -1
- package/test/dash/dash_parser_integration.js +2 -1
- package/test/dash/dash_parser_live_unit.js +0 -19
- package/test/dash/dash_parser_manifest_unit.js +494 -2
- package/test/dash/mpd_utils_unit.js +61 -30
- package/test/hls/hls_live_unit.js +12 -3
- package/test/hls/hls_parser_unit.js +417 -27
- package/test/hls/manifest_text_parser_unit.js +32 -99
- package/test/media/adaptation_set_criteria_unit.js +172 -21
- package/test/media/adaptation_set_unit.js +1 -0
- package/test/media/content_workarounds_unit.js +1 -1
- package/test/media/drm_engine_unit.js +3 -3
- package/test/media/media_source_engine_unit.js +1 -1
- package/test/media/play_rate_controller_unit.js +0 -48
- package/test/media/segment_index_unit.js +2 -1
- package/test/mss/mss_player_integration.js +3 -2
- package/test/net/networking_engine_unit.js +3 -3
- package/test/{media/manifest_parser_unit.js → net/networking_utils_unit.js} +2 -2
- package/test/offline/manifest_convert_unit.js +9 -0
- package/test/offline/offline_integration.js +2 -1
- package/test/offline/storage_integration.js +21 -9
- package/test/player_external.js +4 -2
- package/test/player_integration.js +15 -4
- package/test/player_load_graph_integration.js +47 -151
- package/test/player_src_equals_external.js +1 -0
- package/test/player_src_equals_integration.js +71 -4
- package/test/player_unit.js +80 -27
- package/test/test/util/fake_media_source_engine.js +5 -0
- package/test/test/util/fake_networking_engine.js +9 -1
- package/test/test/util/fake_segment_prefetch.js +3 -0
- package/test/test/util/manifest_generator.js +4 -0
- package/test/test/util/manifest_parser_util.js +14 -2
- package/test/test/util/offline_utils.js +1 -0
- package/test/test/util/simple_fakes.js +2 -2
- package/test/test/util/streaming_engine_util.js +3 -0
- package/test/test/util/test_scheme.js +6 -0
- package/test/test/util/ui_utils.js +4 -3
- package/test/text/mp4_ttml_parser_unit.js +4 -4
- package/test/text/srt_text_parser_unit.js +1 -1
- package/test/text/text_displayer_layout_unit.js +1 -1
- package/test/text/text_engine_unit.js +6 -0
- package/test/text/ttml_text_parser_unit.js +33 -2
- package/test/transmuxer/transmuxer_engine_integration.js +9 -0
- package/test/transmuxer/transmuxer_integration.js +33 -3
- package/test/ui/ad_ui_unit.js +2 -2
- package/test/ui/ui_customization_unit.js +17 -16
- package/test/ui/ui_integration.js +30 -20
- package/test/ui/ui_unit.js +25 -19
- package/test/util/buffer_utils_unit.js +1 -1
- package/test/util/content_steering_manager_unit.js +427 -0
- package/test/util/id3_utils_unit.js +52 -0
- package/test/util/stream_utils_unit.js +17 -113
- package/test/util/ts_parser_unit.js +3 -3
- package/third_party/closure-uri/uri.js +13 -1
- package/ui/audio_language_selection.js +9 -2
- package/ui/externs/ui.js +17 -2
- package/ui/language_utils.js +43 -8
- package/ui/less/range_elements.less +33 -0
- package/ui/locales/en.json +1 -0
- package/ui/locales/es-419.json +1 -0
- package/ui/locales/es.json +1 -0
- package/ui/locales/source.json +4 -0
- package/ui/localization.js +10 -0
- package/ui/remote_button.js +3 -1
- package/ui/resolution_selection.js +47 -10
- package/ui/seek_bar.js +296 -3
- package/ui/text_selection.js +2 -1
- package/ui/ui.js +6 -2
- package/lib/routing/node.js +0 -23
- package/lib/routing/payload.js +0 -47
- package/lib/routing/walker.js +0 -587
- package/test/routing/walker_unit.js +0 -505
|
@@ -15,8 +15,8 @@ describe('Player Load Graph', () => {
|
|
|
15
15
|
/** @type {!jasmine.Spy} */
|
|
16
16
|
let stateChangeSpy;
|
|
17
17
|
|
|
18
|
-
/** @type {
|
|
19
|
-
let
|
|
18
|
+
/** @type {?string} */
|
|
19
|
+
let lastStateChange = null;
|
|
20
20
|
|
|
21
21
|
beforeAll(() => {
|
|
22
22
|
video = shaka.test.UiUtils.createVideoElement();
|
|
@@ -29,57 +29,29 @@ describe('Player Load Graph', () => {
|
|
|
29
29
|
|
|
30
30
|
beforeEach(() => {
|
|
31
31
|
stateChangeSpy = jasmine.createSpy('stateChange');
|
|
32
|
-
|
|
32
|
+
lastStateChange = null;
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
*/
|
|
38
|
-
function createPlayer(attachedTo) {
|
|
39
|
-
player = new shaka.Player(attachedTo);
|
|
35
|
+
function createPlayer() {
|
|
36
|
+
player = new shaka.Player();
|
|
40
37
|
player.addEventListener(
|
|
41
38
|
'onstatechange',
|
|
42
39
|
shaka.test.Util.spyFunc(stateChangeSpy));
|
|
43
|
-
player.addEventListener(
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
player.addEventListener('onstatechange', (event) => {
|
|
41
|
+
lastStateChange = event['state'];
|
|
42
|
+
});
|
|
46
43
|
}
|
|
47
44
|
|
|
48
45
|
// Even though some test will destroy the player, we want to make sure that
|
|
49
46
|
// we don't allow the player to stay attached to the video element.
|
|
50
47
|
afterEach(async () => {
|
|
51
48
|
await player.destroy();
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
it('attach and initialize media source when constructed with media element',
|
|
55
|
-
async () => {
|
|
56
|
-
expect(video.src).toBeFalsy();
|
|
57
|
-
|
|
58
|
-
createPlayer(/* attachedTo= */ video);
|
|
59
|
-
|
|
60
|
-
// Wait until we enter the media source state.
|
|
61
|
-
await new Promise((resolve) => {
|
|
62
|
-
whenEnteringState('media-source', resolve);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
expect(video.src).toBeTruthy();
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('does not set video.src when no video is provided', async () => {
|
|
69
|
-
expect(video.src).toBeFalsy();
|
|
70
|
-
|
|
71
|
-
createPlayer(/* attachedTo= */ null);
|
|
72
|
-
|
|
73
|
-
// Wait until the player has hit an idle state (no more internal loading
|
|
74
|
-
// actions).
|
|
75
|
-
await spyIsCalled(stateIdleSpy);
|
|
76
|
-
|
|
77
|
-
expect(video.src).toBeFalsy();
|
|
49
|
+
player.releaseAllMutexes();
|
|
78
50
|
});
|
|
79
51
|
|
|
80
52
|
it('attach + initializeMediaSource=true will initialize media source',
|
|
81
53
|
async () => {
|
|
82
|
-
createPlayer(
|
|
54
|
+
createPlayer();
|
|
83
55
|
|
|
84
56
|
expect(video.src).toBeFalsy();
|
|
85
57
|
await player.attach(video, /* initializeMediaSource= */ true);
|
|
@@ -88,7 +60,7 @@ describe('Player Load Graph', () => {
|
|
|
88
60
|
|
|
89
61
|
it('attach + initializeMediaSource=false will not intialize media source',
|
|
90
62
|
async () => {
|
|
91
|
-
createPlayer(
|
|
63
|
+
createPlayer();
|
|
92
64
|
|
|
93
65
|
expect(video.src).toBeFalsy();
|
|
94
66
|
await player.attach(video, /* initializeMediaSource= */ false);
|
|
@@ -97,7 +69,7 @@ describe('Player Load Graph', () => {
|
|
|
97
69
|
|
|
98
70
|
it('unload + initializeMediaSource=false does not initialize media source',
|
|
99
71
|
async () => {
|
|
100
|
-
createPlayer(
|
|
72
|
+
createPlayer();
|
|
101
73
|
|
|
102
74
|
await player.attach(video);
|
|
103
75
|
await player.load('test:sintel');
|
|
@@ -108,7 +80,7 @@ describe('Player Load Graph', () => {
|
|
|
108
80
|
|
|
109
81
|
it('unload + initializeMediaSource=true initializes media source',
|
|
110
82
|
async () => {
|
|
111
|
-
createPlayer(
|
|
83
|
+
createPlayer();
|
|
112
84
|
|
|
113
85
|
await player.attach(video);
|
|
114
86
|
await player.load('test:sintel');
|
|
@@ -117,50 +89,8 @@ describe('Player Load Graph', () => {
|
|
|
117
89
|
expect(video.src).toBeTruthy();
|
|
118
90
|
});
|
|
119
91
|
|
|
120
|
-
// There was a bug when calling unload before calling load would cause
|
|
121
|
-
// the load to continue before the (first) unload was complete.
|
|
122
|
-
// https://github.com/shaka-project/shaka-player/issues/612
|
|
123
|
-
it('load will wait for unload to finish', async () => {
|
|
124
|
-
createPlayer(/* attachedTo= */ null);
|
|
125
|
-
|
|
126
|
-
await player.attach(video);
|
|
127
|
-
await player.load('test:sintel');
|
|
128
|
-
|
|
129
|
-
// We are going to call |unload| and |load| right after each other. What
|
|
130
|
-
// we expect to see is that the player is fully unloaded before the load
|
|
131
|
-
// occurs.
|
|
132
|
-
|
|
133
|
-
const unload = player.unload();
|
|
134
|
-
const load = player.load('test:sintel');
|
|
135
|
-
|
|
136
|
-
await unload;
|
|
137
|
-
await load;
|
|
138
|
-
|
|
139
|
-
expect(getVisitedStates()).toEqual([
|
|
140
|
-
'attach',
|
|
141
|
-
|
|
142
|
-
// First call to |load|.
|
|
143
|
-
'media-source',
|
|
144
|
-
'manifest-parser',
|
|
145
|
-
'manifest',
|
|
146
|
-
'drm-engine',
|
|
147
|
-
'load',
|
|
148
|
-
|
|
149
|
-
// Our call to |unload| would have started the transition to
|
|
150
|
-
// "unloaded", but since we called |load| right away, the transition
|
|
151
|
-
// to "unloaded" was most likely done by the call to |load|.
|
|
152
|
-
'unload',
|
|
153
|
-
'attach',
|
|
154
|
-
'media-source',
|
|
155
|
-
'manifest-parser',
|
|
156
|
-
'manifest',
|
|
157
|
-
'drm-engine',
|
|
158
|
-
'load',
|
|
159
|
-
]);
|
|
160
|
-
});
|
|
161
|
-
|
|
162
92
|
it('load and unload can be called multiple times', async () => {
|
|
163
|
-
createPlayer(
|
|
93
|
+
createPlayer();
|
|
164
94
|
|
|
165
95
|
await player.attach(video);
|
|
166
96
|
|
|
@@ -180,7 +110,6 @@ describe('Player Load Graph', () => {
|
|
|
180
110
|
'drm-engine',
|
|
181
111
|
'load',
|
|
182
112
|
'unload',
|
|
183
|
-
'attach',
|
|
184
113
|
'media-source',
|
|
185
114
|
|
|
186
115
|
// Load and unload 2
|
|
@@ -189,13 +118,12 @@ describe('Player Load Graph', () => {
|
|
|
189
118
|
'drm-engine',
|
|
190
119
|
'load',
|
|
191
120
|
'unload',
|
|
192
|
-
'attach',
|
|
193
121
|
'media-source',
|
|
194
122
|
]);
|
|
195
123
|
});
|
|
196
124
|
|
|
197
125
|
it('load can be called multiple times', async () => {
|
|
198
|
-
createPlayer(
|
|
126
|
+
createPlayer();
|
|
199
127
|
|
|
200
128
|
await player.attach(video);
|
|
201
129
|
|
|
@@ -215,7 +143,6 @@ describe('Player Load Graph', () => {
|
|
|
215
143
|
|
|
216
144
|
// Load 2
|
|
217
145
|
'unload',
|
|
218
|
-
'attach',
|
|
219
146
|
'media-source',
|
|
220
147
|
'manifest-parser',
|
|
221
148
|
'manifest',
|
|
@@ -224,7 +151,6 @@ describe('Player Load Graph', () => {
|
|
|
224
151
|
|
|
225
152
|
// Load 3
|
|
226
153
|
'unload',
|
|
227
|
-
'attach',
|
|
228
154
|
'media-source',
|
|
229
155
|
'manifest-parser',
|
|
230
156
|
'manifest',
|
|
@@ -234,7 +160,7 @@ describe('Player Load Graph', () => {
|
|
|
234
160
|
});
|
|
235
161
|
|
|
236
162
|
it('load will interrupt load', async () => {
|
|
237
|
-
createPlayer(
|
|
163
|
+
createPlayer();
|
|
238
164
|
|
|
239
165
|
await player.attach(video);
|
|
240
166
|
|
|
@@ -247,23 +173,8 @@ describe('Player Load Graph', () => {
|
|
|
247
173
|
await load2;
|
|
248
174
|
});
|
|
249
175
|
|
|
250
|
-
it('unload will interrupt load', async () => {
|
|
251
|
-
createPlayer(/* attachedTo= */ null);
|
|
252
|
-
|
|
253
|
-
await player.attach(video);
|
|
254
|
-
|
|
255
|
-
const load = player.load('test:sintel');
|
|
256
|
-
const unload = player.unload();
|
|
257
|
-
|
|
258
|
-
await expectAsync(load).toBeRejected();
|
|
259
|
-
await unload;
|
|
260
|
-
|
|
261
|
-
// We should never have gotten into the loaded state.
|
|
262
|
-
expect(getVisitedStates()).not.toContain('load');
|
|
263
|
-
});
|
|
264
|
-
|
|
265
176
|
it('destroy will interrupt load', async () => {
|
|
266
|
-
createPlayer(
|
|
177
|
+
createPlayer();
|
|
267
178
|
|
|
268
179
|
await player.attach(video);
|
|
269
180
|
|
|
@@ -280,7 +191,7 @@ describe('Player Load Graph', () => {
|
|
|
280
191
|
// When |destroy| is called, the player should move through the unload state
|
|
281
192
|
// on its way to the detached state.
|
|
282
193
|
it('destroy will unload and then detach', async () => {
|
|
283
|
-
createPlayer(
|
|
194
|
+
createPlayer();
|
|
284
195
|
|
|
285
196
|
await player.attach(video);
|
|
286
197
|
|
|
@@ -305,7 +216,7 @@ describe('Player Load Graph', () => {
|
|
|
305
216
|
// |unload| after another |unload| call should just have the player re-enter
|
|
306
217
|
// the state it was waiting in.
|
|
307
218
|
it('unloading multiple times is okay', async () => {
|
|
308
|
-
createPlayer(
|
|
219
|
+
createPlayer();
|
|
309
220
|
|
|
310
221
|
await player.attach(video);
|
|
311
222
|
|
|
@@ -326,12 +237,10 @@ describe('Player Load Graph', () => {
|
|
|
326
237
|
|
|
327
238
|
// |player.unload| (first call)
|
|
328
239
|
'unload',
|
|
329
|
-
'attach',
|
|
330
240
|
'media-source',
|
|
331
241
|
|
|
332
242
|
// |player.unload| (second call)
|
|
333
243
|
'unload',
|
|
334
|
-
'attach',
|
|
335
244
|
'media-source',
|
|
336
245
|
]);
|
|
337
246
|
});
|
|
@@ -339,7 +248,7 @@ describe('Player Load Graph', () => {
|
|
|
339
248
|
// When we destroy, it will allow a current unload operation to occur even
|
|
340
249
|
// though we are going to unload and detach as part of |destroy|.
|
|
341
250
|
it('destroy will not interrupt unload', async () => {
|
|
342
|
-
createPlayer(
|
|
251
|
+
createPlayer();
|
|
343
252
|
|
|
344
253
|
await player.attach(video);
|
|
345
254
|
await player.load('test:sintel');
|
|
@@ -355,7 +264,7 @@ describe('Player Load Graph', () => {
|
|
|
355
264
|
// afterEach), this test will explicitly express our intentions to support
|
|
356
265
|
// the use-case of calling |destroy| multiple times on a player instance.
|
|
357
266
|
it('destroying multiple times is okay', async () => {
|
|
358
|
-
createPlayer(
|
|
267
|
+
createPlayer();
|
|
359
268
|
|
|
360
269
|
await player.attach(video);
|
|
361
270
|
await player.load('test:sintel');
|
|
@@ -369,7 +278,7 @@ describe('Player Load Graph', () => {
|
|
|
369
278
|
// instance when loading.
|
|
370
279
|
it('pre-initialized media source is used when player continues loading',
|
|
371
280
|
async () => {
|
|
372
|
-
createPlayer(
|
|
281
|
+
createPlayer();
|
|
373
282
|
|
|
374
283
|
// After we attach and initialize media source, we should just see
|
|
375
284
|
// two states in our history.
|
|
@@ -409,7 +318,7 @@ describe('Player Load Graph', () => {
|
|
|
409
318
|
* @return {!Promise}
|
|
410
319
|
*/
|
|
411
320
|
async function testInterruptAfter(state) {
|
|
412
|
-
createPlayer(
|
|
321
|
+
createPlayer();
|
|
413
322
|
|
|
414
323
|
let pendingUnload;
|
|
415
324
|
whenEnteringState(state, () => {
|
|
@@ -446,7 +355,7 @@ describe('Player Load Graph', () => {
|
|
|
446
355
|
|
|
447
356
|
describe('error handling', () => {
|
|
448
357
|
beforeEach(() => {
|
|
449
|
-
createPlayer(
|
|
358
|
+
createPlayer();
|
|
450
359
|
});
|
|
451
360
|
|
|
452
361
|
it('returns to attach after load error', async () => {
|
|
@@ -472,12 +381,12 @@ describe('Player Load Graph', () => {
|
|
|
472
381
|
|
|
473
382
|
// Wait a couple interrupter cycles to allow the player to enter idle
|
|
474
383
|
// state.
|
|
475
|
-
|
|
384
|
+
await shaka.test.Util.delay(/* seconds= */ 0.25);
|
|
476
385
|
|
|
477
386
|
// Since attached and loaded in the same interrupter cycle, there won't be
|
|
478
387
|
// any idle time until we finish failing to load. We expect to idle in
|
|
479
388
|
// attach.
|
|
480
|
-
expect(
|
|
389
|
+
expect(lastStateChange).toBe('unload');
|
|
481
390
|
});
|
|
482
391
|
});
|
|
483
392
|
|
|
@@ -492,8 +401,8 @@ describe('Player Load Graph', () => {
|
|
|
492
401
|
mediaSource = window.MediaSource;
|
|
493
402
|
window['MediaSource'] = undefined;
|
|
494
403
|
|
|
495
|
-
createPlayer(
|
|
496
|
-
await
|
|
404
|
+
createPlayer();
|
|
405
|
+
await shaka.test.Util.delay(/* seconds= */ 0.25);
|
|
497
406
|
});
|
|
498
407
|
|
|
499
408
|
afterEach(() => {
|
|
@@ -508,8 +417,8 @@ describe('Player Load Graph', () => {
|
|
|
508
417
|
// should stop at the attach state.
|
|
509
418
|
player.attach(video, /* initMediaSource= */ true);
|
|
510
419
|
|
|
511
|
-
|
|
512
|
-
expect(
|
|
420
|
+
await shaka.test.Util.delay(/* seconds= */ 0.25);
|
|
421
|
+
expect(lastStateChange).toBe('attach');
|
|
513
422
|
});
|
|
514
423
|
|
|
515
424
|
it('loading ignores media source path', async () => {
|
|
@@ -520,8 +429,8 @@ describe('Player Load Graph', () => {
|
|
|
520
429
|
// src= path.
|
|
521
430
|
player.load(SMALL_MP4_CONTENT_URI);
|
|
522
431
|
|
|
523
|
-
|
|
524
|
-
expect(
|
|
432
|
+
await shaka.test.Util.delay(/* seconds= */ 0.25);
|
|
433
|
+
expect(lastStateChange).toBe('src-equals');
|
|
525
434
|
});
|
|
526
435
|
|
|
527
436
|
it('unloading ignores init media source flag', async () => {
|
|
@@ -533,8 +442,8 @@ describe('Player Load Graph', () => {
|
|
|
533
442
|
// don't have media source, it should stop at the attach state.
|
|
534
443
|
player.unload(/* initMediaSource= */ true);
|
|
535
444
|
|
|
536
|
-
|
|
537
|
-
expect(
|
|
445
|
+
await shaka.test.Util.delay(/* seconds= */ 0.25);
|
|
446
|
+
expect(lastStateChange).toBe('unload');
|
|
538
447
|
});
|
|
539
448
|
});
|
|
540
449
|
|
|
@@ -543,9 +452,8 @@ describe('Player Load Graph', () => {
|
|
|
543
452
|
// and then telling it to go to one of our destination states (e.g. attach,
|
|
544
453
|
// load with media source, load with src=).
|
|
545
454
|
describe('routing', () => {
|
|
546
|
-
beforeEach(
|
|
547
|
-
createPlayer(
|
|
548
|
-
await spyIsCalled(stateIdleSpy);
|
|
455
|
+
beforeEach(() => {
|
|
456
|
+
createPlayer();
|
|
549
457
|
});
|
|
550
458
|
|
|
551
459
|
it('goes from detach to detach', async () => {
|
|
@@ -600,7 +508,7 @@ describe('Player Load Graph', () => {
|
|
|
600
508
|
|
|
601
509
|
it('goes from media source to media source', async () => {
|
|
602
510
|
await startIn('media-source');
|
|
603
|
-
await goTo('media-source');
|
|
511
|
+
await goTo('media-source', 'attach'); // doesn't remake media source
|
|
604
512
|
});
|
|
605
513
|
|
|
606
514
|
it('goes from media source to load', async () => {
|
|
@@ -625,7 +533,7 @@ describe('Player Load Graph', () => {
|
|
|
625
533
|
|
|
626
534
|
it('goes from load to media source', async () => {
|
|
627
535
|
await startIn('load');
|
|
628
|
-
await goTo('media-source');
|
|
536
|
+
await goTo('media-source', 'attach'); // doesn't remake media source
|
|
629
537
|
});
|
|
630
538
|
|
|
631
539
|
it('goes from load to load', async () => {
|
|
@@ -677,7 +585,7 @@ describe('Player Load Graph', () => {
|
|
|
677
585
|
|
|
678
586
|
it('goes from manifest parser to media source', async () => {
|
|
679
587
|
await passingThrough('manifest-parser', () => {
|
|
680
|
-
return goTo('media-source');
|
|
588
|
+
return goTo('media-source', 'attach'); // doesn't remake media source
|
|
681
589
|
});
|
|
682
590
|
});
|
|
683
591
|
|
|
@@ -707,7 +615,7 @@ describe('Player Load Graph', () => {
|
|
|
707
615
|
|
|
708
616
|
it('goes from manifest to media source', async () => {
|
|
709
617
|
await passingThrough('manifest', () => {
|
|
710
|
-
return goTo('media-source');
|
|
618
|
+
return goTo('media-source', 'attach'); // doesn't remake media source
|
|
711
619
|
});
|
|
712
620
|
});
|
|
713
621
|
|
|
@@ -737,7 +645,7 @@ describe('Player Load Graph', () => {
|
|
|
737
645
|
|
|
738
646
|
it('goes from drm engine to media source', async () => {
|
|
739
647
|
await passingThrough('drm-engine', () => {
|
|
740
|
-
return goTo('media-source');
|
|
648
|
+
return goTo('media-source', 'attach'); // doesn't remake media source
|
|
741
649
|
});
|
|
742
650
|
});
|
|
743
651
|
|
|
@@ -818,15 +726,8 @@ describe('Player Load Graph', () => {
|
|
|
818
726
|
|
|
819
727
|
const action = actions.get(state);
|
|
820
728
|
expect(action).toBeTruthy();
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
// want to know where we stop, so using the idle spy is more accurate in
|
|
824
|
-
// this situation.
|
|
825
|
-
action();
|
|
826
|
-
|
|
827
|
-
// Make sure that the player stops in the state that we asked it go to.
|
|
828
|
-
const event = await spyIsCalled(stateIdleSpy);
|
|
829
|
-
expect(event.state).toBe(state);
|
|
729
|
+
await action();
|
|
730
|
+
expect(lastStateChange).toBe(state);
|
|
830
731
|
}
|
|
831
732
|
|
|
832
733
|
/**
|
|
@@ -891,9 +792,10 @@ describe('Player Load Graph', () => {
|
|
|
891
792
|
* starting the state change.
|
|
892
793
|
*
|
|
893
794
|
* @param {string} state
|
|
795
|
+
* @param {string=} expectedState
|
|
894
796
|
* @return {!Promise}
|
|
895
797
|
*/
|
|
896
|
-
async function goTo(state) {
|
|
798
|
+
async function goTo(state, expectedState) {
|
|
897
799
|
/** @type {!Map.<string, function():!Promise>} */
|
|
898
800
|
const actions = new Map()
|
|
899
801
|
.set('detach', () => {
|
|
@@ -914,14 +816,8 @@ describe('Player Load Graph', () => {
|
|
|
914
816
|
|
|
915
817
|
const action = actions.get(state);
|
|
916
818
|
expect(action).toBeTruthy();
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
// want to know where we stop, so using the idle spy is more accurate in
|
|
920
|
-
// this situation.
|
|
921
|
-
action();
|
|
922
|
-
|
|
923
|
-
const event = await spyIsCalled(stateIdleSpy);
|
|
924
|
-
expect(event.state).toBe(state);
|
|
819
|
+
await action();
|
|
820
|
+
expect(lastStateChange).toBe(expectedState || state);
|
|
925
821
|
}
|
|
926
822
|
});
|
|
927
823
|
|
|
@@ -37,6 +37,7 @@ describe('Player Src Equals', () => {
|
|
|
37
37
|
|
|
38
38
|
afterEach(async () => {
|
|
39
39
|
await player.destroy();
|
|
40
|
+
player.releaseAllMutexes();
|
|
40
41
|
|
|
41
42
|
eventManager.release();
|
|
42
43
|
});
|
|
@@ -165,10 +166,6 @@ describe('Player Src Equals', () => {
|
|
|
165
166
|
it('can control trick play rate', async () => {
|
|
166
167
|
await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
|
|
167
168
|
|
|
168
|
-
// Let playback run for a little.
|
|
169
|
-
await video.play();
|
|
170
|
-
await waiter.waitForMovementOrFailOnTimeout(video, /* timeout= */10);
|
|
171
|
-
|
|
172
169
|
let videoRateChange = false;
|
|
173
170
|
let playerRateChange = false;
|
|
174
171
|
eventManager.listen(video, 'ratechange', () => {
|
|
@@ -178,6 +175,10 @@ describe('Player Src Equals', () => {
|
|
|
178
175
|
playerRateChange = true;
|
|
179
176
|
});
|
|
180
177
|
|
|
178
|
+
// Let playback run for a little.
|
|
179
|
+
await video.play();
|
|
180
|
+
await waiter.waitForMovementOrFailOnTimeout(video, /* timeout= */10);
|
|
181
|
+
|
|
181
182
|
// Enabling trick play should change our playback rate to the same rate.
|
|
182
183
|
player.trickPlay(2);
|
|
183
184
|
expect(video.playbackRate).toBe(2);
|
|
@@ -422,6 +423,72 @@ describe('Player Src Equals', () => {
|
|
|
422
423
|
expect(player.getManifest()).toBeFalsy();
|
|
423
424
|
});
|
|
424
425
|
|
|
426
|
+
describe('addThumbnailsTrack', () => {
|
|
427
|
+
it('appends thumbnails for external thumbnails with sprites',
|
|
428
|
+
async () => {
|
|
429
|
+
await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
|
|
430
|
+
const locationUri = new goog.Uri(location.href);
|
|
431
|
+
const partialUri =
|
|
432
|
+
new goog.Uri('/base/test/test/assets/thumbnails-sprites.vtt');
|
|
433
|
+
const absoluteUri = locationUri.resolve(partialUri);
|
|
434
|
+
const newTrack =
|
|
435
|
+
await player.addThumbnailsTrack(absoluteUri.toString());
|
|
436
|
+
|
|
437
|
+
expect(player.getImageTracks()).toEqual([newTrack]);
|
|
438
|
+
|
|
439
|
+
const thumbnail1 = await player.getThumbnails(newTrack.id, 0);
|
|
440
|
+
expect(thumbnail1.startTime).toBe(0);
|
|
441
|
+
expect(thumbnail1.duration).toBe(5);
|
|
442
|
+
expect(thumbnail1.height).toBe(90);
|
|
443
|
+
expect(thumbnail1.positionX).toBe(0);
|
|
444
|
+
expect(thumbnail1.positionY).toBe(0);
|
|
445
|
+
expect(thumbnail1.width).toBe(160);
|
|
446
|
+
const thumbnail2 = await player.getThumbnails(newTrack.id, 10);
|
|
447
|
+
expect(thumbnail2.startTime).toBe(5);
|
|
448
|
+
expect(thumbnail2.duration).toBe(25);
|
|
449
|
+
expect(thumbnail2.height).toBe(90);
|
|
450
|
+
expect(thumbnail2.positionX).toBe(160);
|
|
451
|
+
expect(thumbnail2.positionY).toBe(0);
|
|
452
|
+
expect(thumbnail2.width).toBe(160);
|
|
453
|
+
const thumbnail3 = await player.getThumbnails(newTrack.id, 40);
|
|
454
|
+
expect(thumbnail3.startTime).toBe(30);
|
|
455
|
+
expect(thumbnail3.duration).toBe(30);
|
|
456
|
+
expect(thumbnail3.height).toBe(90);
|
|
457
|
+
expect(thumbnail3.positionX).toBe(160);
|
|
458
|
+
expect(thumbnail3.positionY).toBe(90);
|
|
459
|
+
expect(thumbnail3.width).toBe(160);
|
|
460
|
+
|
|
461
|
+
const thumbnails = await player.getAllThumbnails(newTrack.id);
|
|
462
|
+
expect(thumbnails.length).toBe(3);
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
it('appends thumbnails for external thumbnails without sprites',
|
|
466
|
+
async () => {
|
|
467
|
+
await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
|
|
468
|
+
const locationUri = new goog.Uri(location.href);
|
|
469
|
+
const partialUri =
|
|
470
|
+
new goog.Uri('/base/test/test/assets/thumbnails.vtt');
|
|
471
|
+
const absoluteUri = locationUri.resolve(partialUri);
|
|
472
|
+
const newTrack =
|
|
473
|
+
await player.addThumbnailsTrack(absoluteUri.toString());
|
|
474
|
+
|
|
475
|
+
expect(player.getImageTracks()).toEqual([newTrack]);
|
|
476
|
+
|
|
477
|
+
const thumbnail1 = await player.getThumbnails(newTrack.id, 0);
|
|
478
|
+
expect(thumbnail1.startTime).toBe(0);
|
|
479
|
+
expect(thumbnail1.duration).toBe(5);
|
|
480
|
+
const thumbnail2 = await player.getThumbnails(newTrack.id, 10);
|
|
481
|
+
expect(thumbnail2.startTime).toBe(5);
|
|
482
|
+
expect(thumbnail2.duration).toBe(25);
|
|
483
|
+
const thumbnail3 = await player.getThumbnails(newTrack.id, 40);
|
|
484
|
+
expect(thumbnail3.startTime).toBe(30);
|
|
485
|
+
expect(thumbnail3.duration).toBe(30);
|
|
486
|
+
|
|
487
|
+
const thumbnails = await player.getAllThumbnails(newTrack.id);
|
|
488
|
+
expect(thumbnails.length).toBe(3);
|
|
489
|
+
});
|
|
490
|
+
}); // describe('addThumbnailsTrack')
|
|
491
|
+
|
|
425
492
|
/**
|
|
426
493
|
* @param {string} contentUri
|
|
427
494
|
* @param {?number} startTime
|