shaka-player 4.2.12 → 4.2.13
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 +11 -0
- package/.github/workflows/build-and-test.yaml +15 -0
- package/.github/workflows/selenium-lab-tests.yaml +3 -2
- package/.github/workflows/update-issues.yaml +1 -0
- package/CHANGELOG.md +17 -0
- package/dist/deps.js +1 -1
- package/dist/locales.js +31 -31
- package/dist/shaka-player.compiled.debug.js +23 -24
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.js +368 -369
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.debug.js +27 -29
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.js +383 -383
- package/dist/shaka-player.ui.map +2 -2
- package/docs/tutorials/selenium-grid-config.md +60 -8
- package/karma.conf.js +50 -7
- package/lib/abr/simple_abr_manager.js +5 -5
- package/lib/player.js +1 -5
- package/lib/polyfill/orientation.js +34 -7
- package/lib/text/vtt_text_parser.js +1 -0
- package/lib/util/manifest_parser_utils.js +4 -2
- package/lib/util/platform.js +14 -0
- package/lib/util/stream_utils.js +69 -26
- package/package.json +2 -2
- package/test/cast/cast_utils_unit.js +4 -1
- package/test/hls/hls_parser_unit.js +72 -0
- package/test/media/drm_engine_integration.js +2 -2
- package/test/media/segment_index_unit.js +3 -3
- package/test/media/streaming_engine_integration.js +14 -11
- package/test/offline/offline_integration.js +6 -3
- package/test/player_external.js +19 -16
- package/test/player_integration.js +35 -48
- package/test/player_src_equals_integration.js +9 -5
- package/test/test/util/fake_demo_main.js +7 -3
- package/test/test/util/layout_tests.js +2 -2
- package/test/test/util/ui_utils.js +9 -2
- package/test/test/util/util.js +6 -27
- package/test/test/util/waiter.js +73 -3
- package/test/ui/ad_ui_unit.js +9 -9
- package/test/util/stream_utils_unit.js +46 -0
- package/ui/range_element.js +5 -0
|
@@ -573,6 +573,78 @@ describe('HlsParser', () => {
|
|
|
573
573
|
await testHlsParser(master, media, manifest);
|
|
574
574
|
});
|
|
575
575
|
|
|
576
|
+
it('accepts fLaC codec as audio/mp4', async () => {
|
|
577
|
+
const master = [
|
|
578
|
+
'#EXTM3U\n',
|
|
579
|
+
'#EXT-X-STREAM-INF:BANDWIDTH=1000000,CODECS="fLaC"\n',
|
|
580
|
+
'audio\n',
|
|
581
|
+
'#EXT-X-STREAM-INF:BANDWIDTH=1000000,CODECS="flac"\n',
|
|
582
|
+
'audio2\n',
|
|
583
|
+
].join('');
|
|
584
|
+
|
|
585
|
+
const media = [
|
|
586
|
+
'#EXTM3U\n',
|
|
587
|
+
'#EXT-X-PLAYLIST-TYPE:VOD\n',
|
|
588
|
+
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
589
|
+
'#EXTINF:5,\n',
|
|
590
|
+
'#EXT-X-BYTERANGE:121090@616\n',
|
|
591
|
+
'main.mp4',
|
|
592
|
+
].join('');
|
|
593
|
+
|
|
594
|
+
const manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
595
|
+
manifest.anyTimeline();
|
|
596
|
+
manifest.addPartialVariant((variant) => {
|
|
597
|
+
variant.addPartialStream(ContentType.AUDIO, (stream) => {
|
|
598
|
+
stream.mime('audio/mp4', 'fLaC');
|
|
599
|
+
});
|
|
600
|
+
});
|
|
601
|
+
manifest.addPartialVariant((variant) => {
|
|
602
|
+
variant.addPartialStream(ContentType.AUDIO, (stream) => {
|
|
603
|
+
stream.mime('audio/mp4', 'flac');
|
|
604
|
+
});
|
|
605
|
+
});
|
|
606
|
+
manifest.sequenceMode = true;
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
await testHlsParser(master, media, manifest);
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
it('accepts Opus codec as audio/mp4', async () => {
|
|
613
|
+
const master = [
|
|
614
|
+
'#EXTM3U\n',
|
|
615
|
+
'#EXT-X-STREAM-INF:BANDWIDTH=128000,CODECS="Opus"\n',
|
|
616
|
+
'audio\n',
|
|
617
|
+
'#EXT-X-STREAM-INF:BANDWIDTH=128000,CODECS="opus"\n',
|
|
618
|
+
'audio2\n',
|
|
619
|
+
].join('');
|
|
620
|
+
|
|
621
|
+
const media = [
|
|
622
|
+
'#EXTM3U\n',
|
|
623
|
+
'#EXT-X-PLAYLIST-TYPE:VOD\n',
|
|
624
|
+
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
625
|
+
'#EXTINF:5,\n',
|
|
626
|
+
'#EXT-X-BYTERANGE:121090@616\n',
|
|
627
|
+
'main.mp4',
|
|
628
|
+
].join('');
|
|
629
|
+
|
|
630
|
+
const manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
631
|
+
manifest.anyTimeline();
|
|
632
|
+
manifest.addPartialVariant((variant) => {
|
|
633
|
+
variant.addPartialStream(ContentType.AUDIO, (stream) => {
|
|
634
|
+
stream.mime('audio/mp4', 'Opus');
|
|
635
|
+
});
|
|
636
|
+
});
|
|
637
|
+
manifest.addPartialVariant((variant) => {
|
|
638
|
+
variant.addPartialStream(ContentType.AUDIO, (stream) => {
|
|
639
|
+
stream.mime('audio/mp4', 'opus');
|
|
640
|
+
});
|
|
641
|
+
});
|
|
642
|
+
manifest.sequenceMode = true;
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
await testHlsParser(master, media, manifest);
|
|
646
|
+
});
|
|
647
|
+
|
|
576
648
|
it('parses audio+video variant with closed captions', async () => {
|
|
577
649
|
const master = [
|
|
578
650
|
'#EXTM3U\n',
|
|
@@ -242,7 +242,7 @@ describe('DrmEngine', () => {
|
|
|
242
242
|
/* hasClosedCaptions= */ false);
|
|
243
243
|
|
|
244
244
|
expect(video.buffered.end(0)).toBeGreaterThan(0);
|
|
245
|
-
video.play();
|
|
245
|
+
await video.play();
|
|
246
246
|
|
|
247
247
|
const waiter = new shaka.test.Waiter(eventManager).timeoutAfter(15);
|
|
248
248
|
waiter.setMediaSourceEngine(mediaSourceEngine);
|
|
@@ -325,7 +325,7 @@ describe('DrmEngine', () => {
|
|
|
325
325
|
/* hasClosedCaptions= */ false);
|
|
326
326
|
|
|
327
327
|
expect(video.buffered.end(0)).toBeGreaterThan(0);
|
|
328
|
-
video.play();
|
|
328
|
+
await video.play();
|
|
329
329
|
|
|
330
330
|
const waiter = new shaka.test.Waiter(eventManager).timeoutAfter(15);
|
|
331
331
|
waiter.setMediaSourceEngine(mediaSourceEngine);
|
|
@@ -974,9 +974,9 @@ describe('SegmentIndex', /** @suppress {accessControls} */ () => {
|
|
|
974
974
|
return [newRefs.shift()];
|
|
975
975
|
});
|
|
976
976
|
});
|
|
977
|
-
|
|
978
|
-
//
|
|
979
|
-
await
|
|
977
|
+
|
|
978
|
+
// Wait for the new refs to be appended.
|
|
979
|
+
await done;
|
|
980
980
|
|
|
981
981
|
expect(Array.from(metaIndex)).toEqual(oldRefs.concat(inputRefs2));
|
|
982
982
|
});
|
|
@@ -57,6 +57,9 @@ describe('StreamingEngine', () => {
|
|
|
57
57
|
beforeEach(() => {
|
|
58
58
|
config = shaka.util.PlayerConfiguration.createDefault().streaming;
|
|
59
59
|
|
|
60
|
+
// Disable stall detection, which can interfere with playback tests.
|
|
61
|
+
config.stallEnabled = false;
|
|
62
|
+
|
|
60
63
|
onError = jasmine.createSpy('onError');
|
|
61
64
|
onError.and.callFake(fail);
|
|
62
65
|
onEvent = jasmine.createSpy('onEvent');
|
|
@@ -276,7 +279,7 @@ describe('StreamingEngine', () => {
|
|
|
276
279
|
// Let's go!
|
|
277
280
|
streamingEngine.switchVariant(variant);
|
|
278
281
|
await streamingEngine.start();
|
|
279
|
-
video.play();
|
|
282
|
+
await video.play();
|
|
280
283
|
// The overall test timeout is 120 seconds, and the content is 40
|
|
281
284
|
// seconds. It should be possible to complete this test in 100 seconds,
|
|
282
285
|
// and if not, we want the error thrown to be within the overall test's
|
|
@@ -296,7 +299,7 @@ describe('StreamingEngine', () => {
|
|
|
296
299
|
// Let's go!
|
|
297
300
|
streamingEngine.switchVariant(variant);
|
|
298
301
|
await streamingEngine.start();
|
|
299
|
-
video.play();
|
|
302
|
+
await video.play();
|
|
300
303
|
|
|
301
304
|
// Wait for playback to begin before increasing the playback rate. This
|
|
302
305
|
// improves test reliability on slow platforms like Chromecast.
|
|
@@ -310,7 +313,7 @@ describe('StreamingEngine', () => {
|
|
|
310
313
|
// Let's go!
|
|
311
314
|
streamingEngine.switchVariant(variant);
|
|
312
315
|
await streamingEngine.start();
|
|
313
|
-
video.play();
|
|
316
|
+
await video.play();
|
|
314
317
|
|
|
315
318
|
// After 35 seconds seek back 10 seconds into the first Period.
|
|
316
319
|
await waiter.timeoutAfter(80).waitUntilPlayheadReaches(video, 35);
|
|
@@ -322,7 +325,7 @@ describe('StreamingEngine', () => {
|
|
|
322
325
|
// Let's go!
|
|
323
326
|
streamingEngine.switchVariant(variant);
|
|
324
327
|
await streamingEngine.start();
|
|
325
|
-
video.play();
|
|
328
|
+
await video.play();
|
|
326
329
|
await waiter.timeoutAfter(60).waitUntilPlayheadReaches(video, 20);
|
|
327
330
|
video.currentTime = 40;
|
|
328
331
|
await waiter.timeoutAfter(60).waitForEnd(video);
|
|
@@ -350,7 +353,7 @@ describe('StreamingEngine', () => {
|
|
|
350
353
|
streamingEngine.switchVariant(variant);
|
|
351
354
|
await streamingEngine.start();
|
|
352
355
|
|
|
353
|
-
video.play();
|
|
356
|
+
await video.play();
|
|
354
357
|
await waiter.timeoutAfter(60).waitUntilPlayheadReaches(video, 305);
|
|
355
358
|
|
|
356
359
|
const segmentType = shaka.net.NetworkingEngine.RequestType.SEGMENT;
|
|
@@ -370,7 +373,7 @@ describe('StreamingEngine', () => {
|
|
|
370
373
|
// Seek outside the availability window right away. The playhead
|
|
371
374
|
// should adjust the video's current time.
|
|
372
375
|
video.currentTime = segmentAvailability.end + 120;
|
|
373
|
-
video.play();
|
|
376
|
+
await video.play();
|
|
374
377
|
|
|
375
378
|
// Wait until the repositioning is complete so we don't
|
|
376
379
|
// immediately hit this case.
|
|
@@ -395,7 +398,7 @@ describe('StreamingEngine', () => {
|
|
|
395
398
|
video.currentTime = segmentAvailability.start - 120;
|
|
396
399
|
expect(video.currentTime).toBeGreaterThan(0);
|
|
397
400
|
|
|
398
|
-
video.play();
|
|
401
|
+
await video.play();
|
|
399
402
|
await waiter.timeoutAfter(60).waitUntilPlayheadReaches(video, 305);
|
|
400
403
|
|
|
401
404
|
// We are playing close to the beginning of the availability window.
|
|
@@ -423,7 +426,7 @@ describe('StreamingEngine', () => {
|
|
|
423
426
|
// Let's go!
|
|
424
427
|
streamingEngine.switchVariant(variant);
|
|
425
428
|
await streamingEngine.start();
|
|
426
|
-
video.play();
|
|
429
|
+
await video.play();
|
|
427
430
|
|
|
428
431
|
await waiter.timeoutAfter(5).waitUntilPlayheadReaches(video, 0.01);
|
|
429
432
|
expect(video.buffered.length).toBeGreaterThan(0);
|
|
@@ -438,7 +441,7 @@ describe('StreamingEngine', () => {
|
|
|
438
441
|
// Let's go!
|
|
439
442
|
streamingEngine.switchVariant(variant);
|
|
440
443
|
await streamingEngine.start();
|
|
441
|
-
video.play();
|
|
444
|
+
await video.play();
|
|
442
445
|
|
|
443
446
|
await waiter.timeoutAfter(5).waitUntilPlayheadReaches(video, 0.01);
|
|
444
447
|
expect(video.buffered.length).toBeGreaterThan(0);
|
|
@@ -457,7 +460,7 @@ describe('StreamingEngine', () => {
|
|
|
457
460
|
await waiter.timeoutAfter(5).waitForEvent(video, 'loadeddata');
|
|
458
461
|
|
|
459
462
|
video.currentTime = 8;
|
|
460
|
-
video.play();
|
|
463
|
+
await video.play();
|
|
461
464
|
|
|
462
465
|
await waiter.timeoutAfter(60).waitUntilPlayheadReaches(video, 23);
|
|
463
466
|
// Should be close enough to still have the gap buffered.
|
|
@@ -474,7 +477,7 @@ describe('StreamingEngine', () => {
|
|
|
474
477
|
await waiter.timeoutAfter(5).waitForEvent(video, 'loadeddata');
|
|
475
478
|
|
|
476
479
|
video.currentTime = 8;
|
|
477
|
-
video.play();
|
|
480
|
+
await video.play();
|
|
478
481
|
|
|
479
482
|
await waiter.timeoutAfter(60).waitUntilPlayheadReaches(video, 23);
|
|
480
483
|
// Should be close enough to still have the gap buffered.
|
|
@@ -33,6 +33,9 @@ filterDescribe('Offline', supportsStorage, () => {
|
|
|
33
33
|
player = new shaka.Player(video);
|
|
34
34
|
player.addEventListener('error', fail);
|
|
35
35
|
|
|
36
|
+
// Disable stall detection, which can interfere with playback tests.
|
|
37
|
+
player.configure('streaming.stallEnabled', false);
|
|
38
|
+
|
|
36
39
|
eventManager = new shaka.util.EventManager();
|
|
37
40
|
waiter = new shaka.test.Waiter(eventManager);
|
|
38
41
|
waiter.setPlayer(player);
|
|
@@ -67,7 +70,7 @@ filterDescribe('Offline', supportsStorage, () => {
|
|
|
67
70
|
|
|
68
71
|
await player.load(contentUri);
|
|
69
72
|
|
|
70
|
-
video.play();
|
|
73
|
+
await video.play();
|
|
71
74
|
await playTo(/* end= */ 3, /* timeout= */ 20);
|
|
72
75
|
await player.unload();
|
|
73
76
|
await storage.remove(contentUri);
|
|
@@ -103,7 +106,7 @@ filterDescribe('Offline', supportsStorage, () => {
|
|
|
103
106
|
|
|
104
107
|
await player.load(contentUri);
|
|
105
108
|
|
|
106
|
-
video.play();
|
|
109
|
+
await video.play();
|
|
107
110
|
await playTo(/* end= */ 3, /* timeout= */ 20);
|
|
108
111
|
await player.unload();
|
|
109
112
|
await storage.remove(contentUri);
|
|
@@ -146,7 +149,7 @@ filterDescribe('Offline', supportsStorage, () => {
|
|
|
146
149
|
|
|
147
150
|
await player.load(contentUri);
|
|
148
151
|
|
|
149
|
-
video.play();
|
|
152
|
+
await video.play();
|
|
150
153
|
await playTo(/* end= */ 3, /* timeout= */ 20);
|
|
151
154
|
await player.unload();
|
|
152
155
|
await storage.remove(contentUri);
|
package/test/player_external.js
CHANGED
|
@@ -36,6 +36,24 @@ describe('Player', () => {
|
|
|
36
36
|
beforeEach(() => {
|
|
37
37
|
player = new compiledShaka.Player(video);
|
|
38
38
|
|
|
39
|
+
// Make sure we are playing the lowest res available to avoid test flake
|
|
40
|
+
// based on network issues. Note that disabling ABR and setting a low
|
|
41
|
+
// abr.defaultBandwidthEstimate would not be sufficient, because it
|
|
42
|
+
// would only affect the choice of track on the first period. When we
|
|
43
|
+
// cross a period boundary, the default bandwidth estimate will no
|
|
44
|
+
// longer be in effect, and AbrManager may choose higher res tracks for
|
|
45
|
+
// the new period. Using abr.restrictions.maxHeight will let us force
|
|
46
|
+
// AbrManager to the lowest resolution, which is its fallback when these
|
|
47
|
+
// soft restrictions cannot be met.
|
|
48
|
+
player.configure('abr.restrictions.maxHeight', 1);
|
|
49
|
+
|
|
50
|
+
// Make sure that live streams are synced against a good clock.
|
|
51
|
+
player.configure('manifest.dash.clockSyncUri',
|
|
52
|
+
'https://shaka-player-demo.appspot.com/time.txt');
|
|
53
|
+
|
|
54
|
+
// Disable stall detection, which can interfere with playback tests.
|
|
55
|
+
player.configure('streaming.stallEnabled', false);
|
|
56
|
+
|
|
39
57
|
// Grab event manager from the uncompiled library:
|
|
40
58
|
eventManager = new shaka.util.EventManager();
|
|
41
59
|
waiter = new shaka.test.Waiter(eventManager);
|
|
@@ -92,21 +110,6 @@ describe('Player', () => {
|
|
|
92
110
|
}
|
|
93
111
|
}
|
|
94
112
|
|
|
95
|
-
// Make sure we are playing the lowest res available to avoid test flake
|
|
96
|
-
// based on network issues. Note that disabling ABR and setting a low
|
|
97
|
-
// abr.defaultBandwidthEstimate would not be sufficient, because it
|
|
98
|
-
// would only affect the choice of track on the first period. When we
|
|
99
|
-
// cross a period boundary, the default bandwidth estimate will no
|
|
100
|
-
// longer be in effect, and AbrManager may choose higher res tracks for
|
|
101
|
-
// the new period. Using abr.restrictions.maxHeight will let us force
|
|
102
|
-
// AbrManager to the lowest resolution, which is its fallback when these
|
|
103
|
-
// soft restrictions cannot be met.
|
|
104
|
-
player.configure('abr.restrictions.maxHeight', 1);
|
|
105
|
-
|
|
106
|
-
// Make sure that live streams are synced against a good clock.
|
|
107
|
-
player.configure('manifest.dash.clockSyncUri',
|
|
108
|
-
'https://shaka-player-demo.appspot.com/time.txt');
|
|
109
|
-
|
|
110
113
|
// Add asset-specific configuration.
|
|
111
114
|
player.configure(asset.getConfiguration());
|
|
112
115
|
|
|
@@ -125,7 +128,7 @@ describe('Player', () => {
|
|
|
125
128
|
const isLive = asset.features.includes(Feature.LIVE);
|
|
126
129
|
expect(player.isLive()).toBe(isLive);
|
|
127
130
|
}
|
|
128
|
-
video.play();
|
|
131
|
+
await video.play();
|
|
129
132
|
|
|
130
133
|
// Wait for the video to start playback. If it takes longer than 20
|
|
131
134
|
// seconds, fail the test.
|
|
@@ -34,6 +34,9 @@ describe('Player', () => {
|
|
|
34
34
|
await shaka.test.TestScheme.createManifests(compiledShaka, '_compiled');
|
|
35
35
|
player = new compiledShaka.Player(video);
|
|
36
36
|
|
|
37
|
+
// Disable stall detection, which can interfere with playback tests.
|
|
38
|
+
player.configure('streaming.stallEnabled', false);
|
|
39
|
+
|
|
37
40
|
// Grab event manager from the uncompiled library:
|
|
38
41
|
eventManager = new shaka.util.EventManager();
|
|
39
42
|
waiter = new shaka.test.Waiter(eventManager);
|
|
@@ -81,11 +84,15 @@ describe('Player', () => {
|
|
|
81
84
|
// Unlike the other tests in this file, this uses an uncompiled build of
|
|
82
85
|
// Shaka, so that we don't need to expose shaka.util.Timer.activeTimers.
|
|
83
86
|
player = new shaka.Player(video);
|
|
87
|
+
|
|
88
|
+
// Disable stall detection, which can interfere with playback tests.
|
|
89
|
+
player.configure('streaming.stallEnabled', false);
|
|
90
|
+
|
|
84
91
|
waiter.setPlayer(player);
|
|
85
92
|
|
|
86
93
|
// Play the video for a little while.
|
|
87
94
|
await player.load('test:sintel');
|
|
88
|
-
video.play();
|
|
95
|
+
await video.play();
|
|
89
96
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 1, 10);
|
|
90
97
|
|
|
91
98
|
// Destroy the player.
|
|
@@ -127,7 +134,7 @@ describe('Player', () => {
|
|
|
127
134
|
}
|
|
128
135
|
});
|
|
129
136
|
await player.load('test:sintel_compiled');
|
|
130
|
-
video.play();
|
|
137
|
+
await video.play();
|
|
131
138
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 25, 30);
|
|
132
139
|
expect(results).toEqual(expected);
|
|
133
140
|
});
|
|
@@ -139,7 +146,7 @@ describe('Player', () => {
|
|
|
139
146
|
// This is tested more in player_unit.js. This is here to test the public
|
|
140
147
|
// API and to check for renaming.
|
|
141
148
|
await player.load('test:sintel_compiled');
|
|
142
|
-
video.play();
|
|
149
|
+
await video.play();
|
|
143
150
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 1, 10);
|
|
144
151
|
|
|
145
152
|
const stats = player.getStats();
|
|
@@ -210,7 +217,7 @@ describe('Player', () => {
|
|
|
210
217
|
|
|
211
218
|
it('does not cause cues to be null', async () => {
|
|
212
219
|
await player.load('test:sintel_compiled');
|
|
213
|
-
video.play();
|
|
220
|
+
await video.play();
|
|
214
221
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 1, 10);
|
|
215
222
|
|
|
216
223
|
// This TextTrack was created as part of load() when we set up the
|
|
@@ -331,7 +338,7 @@ describe('Player', () => {
|
|
|
331
338
|
await player.load('test:sintel_realistic_compiled');
|
|
332
339
|
|
|
333
340
|
// Play until a time at which the external cues would be on screen.
|
|
334
|
-
video.play();
|
|
341
|
+
await video.play();
|
|
335
342
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 4, 20);
|
|
336
343
|
|
|
337
344
|
expect(player.isTextTrackVisible()).toBe(true);
|
|
@@ -363,7 +370,7 @@ describe('Player', () => {
|
|
|
363
370
|
await waiter.waitForEvent(player, 'texttrackvisibility');
|
|
364
371
|
|
|
365
372
|
// Play until a time at which the external cues would be on screen.
|
|
366
|
-
video.play();
|
|
373
|
+
await video.play();
|
|
367
374
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 4, 20);
|
|
368
375
|
|
|
369
376
|
expect(player.isTextTrackVisible()).toBe(true);
|
|
@@ -434,7 +441,7 @@ describe('Player', () => {
|
|
|
434
441
|
player.setTextTrackVisibility(true);
|
|
435
442
|
player.selectTextLanguage('fr');
|
|
436
443
|
video.currentTime = 5;
|
|
437
|
-
video.play();
|
|
444
|
+
await video.play();
|
|
438
445
|
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
439
446
|
|
|
440
447
|
expect(video.textTracks[0].activeCues.length).toBe(1);
|
|
@@ -472,7 +479,7 @@ describe('Player', () => {
|
|
|
472
479
|
|
|
473
480
|
it('at higher playback rates', async () => {
|
|
474
481
|
await player.load('test:sintel_compiled');
|
|
475
|
-
video.play();
|
|
482
|
+
await video.play();
|
|
476
483
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 1, 10);
|
|
477
484
|
|
|
478
485
|
// Enabling trick play should change our playback rate to the same rate.
|
|
@@ -488,14 +495,12 @@ describe('Player', () => {
|
|
|
488
495
|
});
|
|
489
496
|
|
|
490
497
|
it('in sequence mode', async () => {
|
|
491
|
-
|
|
492
|
-
player = new compiledShaka.Player(video);
|
|
493
|
-
await player.load('test:sintel_sequence_compiled', 0, testSchemeMimeType);
|
|
498
|
+
await player.load('test:sintel_sequence_compiled');
|
|
494
499
|
expect(player.getManifest().sequenceMode).toBe(true);
|
|
495
500
|
|
|
496
501
|
// Ensure the video plays.
|
|
497
|
-
video.play();
|
|
498
|
-
await waiter.
|
|
502
|
+
await video.play();
|
|
503
|
+
await waiter.timeoutAfter(20).waitUntilPlayheadReaches(video, 5);
|
|
499
504
|
|
|
500
505
|
// Seek the video, and see if it can continue playing from that point.
|
|
501
506
|
video.currentTime = 20;
|
|
@@ -514,9 +519,8 @@ describe('Player', () => {
|
|
|
514
519
|
// even if one is not specified in load().
|
|
515
520
|
it('immediately after construction with MIME type', async () => {
|
|
516
521
|
const testSchemeMimeType = 'application/x-test-manifest';
|
|
517
|
-
player = new compiledShaka.Player(video);
|
|
518
522
|
await player.load('test:sintel_compiled', 0, testSchemeMimeType);
|
|
519
|
-
video.play();
|
|
523
|
+
await video.play();
|
|
520
524
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 1, 10);
|
|
521
525
|
});
|
|
522
526
|
|
|
@@ -555,7 +559,7 @@ describe('Player', () => {
|
|
|
555
559
|
// Regression test for https://github.com/shaka-project/shaka-player/issues/1187
|
|
556
560
|
it('does not throw on destroy', async () => {
|
|
557
561
|
await player.load('test:sintel_compiled');
|
|
558
|
-
video.play();
|
|
562
|
+
await video.play();
|
|
559
563
|
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 1, 10);
|
|
560
564
|
await player.unload();
|
|
561
565
|
// Before we fixed #1187, the call to destroy() on textDisplayer was
|
|
@@ -801,7 +805,7 @@ describe('Player', () => {
|
|
|
801
805
|
player.configure('streaming.observeQualityChanges', true);
|
|
802
806
|
|
|
803
807
|
await player.load('test:sintel_compiled');
|
|
804
|
-
video.play();
|
|
808
|
+
await video.play();
|
|
805
809
|
|
|
806
810
|
// Wait for the video to start playback. If it takes longer than 10
|
|
807
811
|
// seconds, fail the test.
|
|
@@ -815,7 +819,7 @@ describe('Player', () => {
|
|
|
815
819
|
player.configure('streaming.observeQualityChanges', false);
|
|
816
820
|
|
|
817
821
|
await player.load('test:sintel_compiled');
|
|
818
|
-
video.play();
|
|
822
|
+
await video.play();
|
|
819
823
|
|
|
820
824
|
// Wait for the video to start playback. If it takes longer than 10
|
|
821
825
|
// seconds, fail the test.
|
|
@@ -844,7 +848,7 @@ describe('Player', () => {
|
|
|
844
848
|
|
|
845
849
|
// Play the stream.
|
|
846
850
|
await player.load('/base/test/test/assets/3675/dash_0.mpd');
|
|
847
|
-
video.play();
|
|
851
|
+
await video.play();
|
|
848
852
|
|
|
849
853
|
// Wait for the stream to be over.
|
|
850
854
|
eventManager.listen(player, 'error', Util.spyFunc(onErrorSpy));
|
|
@@ -932,22 +936,22 @@ describe('Player', () => {
|
|
|
932
936
|
|
|
933
937
|
await player.load('test:sintel_long_compiled');
|
|
934
938
|
video.pause();
|
|
935
|
-
await waitUntilBuffered(10);
|
|
939
|
+
await waiter.waitUntilBuffered(video, 10);
|
|
936
940
|
|
|
937
941
|
player.configure('streaming.bufferingGoal', 30);
|
|
938
|
-
await waitUntilBuffered(30);
|
|
942
|
+
await waiter.waitUntilBuffered(video, 30);
|
|
939
943
|
|
|
940
944
|
player.configure('streaming.bufferingGoal', 60);
|
|
941
|
-
await waitUntilBuffered(60);
|
|
942
|
-
await Util.delay(
|
|
945
|
+
await waiter.waitUntilBuffered(video, 60);
|
|
946
|
+
await Util.delay(1);
|
|
943
947
|
expect(getBufferedAhead()).toBeLessThan(70); // 60 + segment_size
|
|
944
948
|
|
|
945
949
|
// We don't remove buffered content ahead of the playhead, so seek to
|
|
946
950
|
// clear the buffer.
|
|
947
951
|
player.configure('streaming.bufferingGoal', 10);
|
|
948
952
|
video.currentTime = 120;
|
|
949
|
-
await waitUntilBuffered(10);
|
|
950
|
-
await Util.delay(
|
|
953
|
+
await waiter.waitUntilBuffered(video, 10);
|
|
954
|
+
await Util.delay(1);
|
|
951
955
|
expect(getBufferedAhead()).toBeLessThan(20); // 10 + segment_size
|
|
952
956
|
});
|
|
953
957
|
|
|
@@ -957,20 +961,22 @@ describe('Player', () => {
|
|
|
957
961
|
|
|
958
962
|
await player.load('test:sintel_long_compiled');
|
|
959
963
|
video.pause();
|
|
960
|
-
await waitUntilBuffered(30);
|
|
964
|
+
await waiter.waitUntilBuffered(video, 30);
|
|
961
965
|
video.currentTime = 20;
|
|
962
|
-
await waitUntilBuffered(30);
|
|
966
|
+
await waiter.waitUntilBuffered(video, 30);
|
|
963
967
|
|
|
964
968
|
expect(getBufferedBehind()).toBe(20); // Buffered to start still.
|
|
965
969
|
video.currentTime = 50;
|
|
966
|
-
await waitUntilBuffered(30);
|
|
970
|
+
await waiter.waitUntilBuffered(video, 30);
|
|
971
|
+
await Util.delay(1);
|
|
967
972
|
expect(getBufferedBehind()).toBeLessThan(40); // 30 + segment_size
|
|
968
973
|
|
|
969
974
|
player.configure('streaming.bufferBehind', 10);
|
|
970
975
|
// We only evict content when we append a segment, so increase the
|
|
971
976
|
// buffering goal so we append another segment.
|
|
972
977
|
player.configure('streaming.bufferingGoal', 40);
|
|
973
|
-
await waitUntilBuffered(40);
|
|
978
|
+
await waiter.waitUntilBuffered(video, 40);
|
|
979
|
+
await Util.delay(1);
|
|
974
980
|
expect(getBufferedBehind()).toBeLessThanOrEqual(10);
|
|
975
981
|
});
|
|
976
982
|
|
|
@@ -989,25 +995,6 @@ describe('Player', () => {
|
|
|
989
995
|
}
|
|
990
996
|
return video.currentTime - start;
|
|
991
997
|
}
|
|
992
|
-
|
|
993
|
-
async function waitUntilBuffered(amount) {
|
|
994
|
-
for (let i = 0; i < 50; i++) {
|
|
995
|
-
// We buffer from an internal segment, so this shouldn't take long to
|
|
996
|
-
// buffer.
|
|
997
|
-
await Util.delay(0.1); // eslint-disable-line no-await-in-loop
|
|
998
|
-
if (getBufferedAhead() >= amount) {
|
|
999
|
-
return;
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
const ranges =
|
|
1004
|
-
shaka.media.TimeRangesUtils.getBufferedInfo(video.buffered);
|
|
1005
|
-
const currentTime = video.currentTime;
|
|
1006
|
-
const target = currentTime + amount;
|
|
1007
|
-
|
|
1008
|
-
throw new Error('Timeout waiting to buffer! ' +
|
|
1009
|
-
JSON.stringify({ranges, currentTime, target}));
|
|
1010
|
-
}
|
|
1011
998
|
}); // describe('buffering')
|
|
1012
999
|
|
|
1013
1000
|
describe('configuration', () => {
|
|
@@ -27,6 +27,10 @@ describe('Player Src Equals', () => {
|
|
|
27
27
|
beforeEach(() => {
|
|
28
28
|
player = new shaka.Player();
|
|
29
29
|
player.addEventListener('error', fail);
|
|
30
|
+
|
|
31
|
+
// Disable stall detection, which can interfere with playback tests.
|
|
32
|
+
player.configure('streaming.stallEnabled', false);
|
|
33
|
+
|
|
30
34
|
eventManager = new shaka.util.EventManager();
|
|
31
35
|
waiter = new shaka.test.Waiter(eventManager);
|
|
32
36
|
});
|
|
@@ -101,7 +105,7 @@ describe('Player Src Equals', () => {
|
|
|
101
105
|
expect(video.duration).not.toBeCloseTo(0);
|
|
102
106
|
|
|
103
107
|
// Start playback and wait for the playhead to move.
|
|
104
|
-
video.play();
|
|
108
|
+
await video.play();
|
|
105
109
|
await waiter.waitForMovementOrFailOnTimeout(video, /* timeout= */10);
|
|
106
110
|
|
|
107
111
|
// Make sure the playhead is roughly where we expect it to be before
|
|
@@ -138,7 +142,7 @@ describe('Player Src Equals', () => {
|
|
|
138
142
|
await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
|
|
139
143
|
|
|
140
144
|
// For playback to begin so that we have some content buffered.
|
|
141
|
-
video.play();
|
|
145
|
+
await video.play();
|
|
142
146
|
await waiter.waitForMovementOrFailOnTimeout(video, /* timeout= */10);
|
|
143
147
|
|
|
144
148
|
const buffered = player.getBufferedInfo();
|
|
@@ -162,7 +166,7 @@ describe('Player Src Equals', () => {
|
|
|
162
166
|
await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
|
|
163
167
|
|
|
164
168
|
// Let playback run for a little.
|
|
165
|
-
video.play();
|
|
169
|
+
await video.play();
|
|
166
170
|
await waiter.waitForMovementOrFailOnTimeout(video, /* timeout= */10);
|
|
167
171
|
|
|
168
172
|
let videoRateChange = false;
|
|
@@ -279,7 +283,7 @@ describe('Player Src Equals', () => {
|
|
|
279
283
|
expect(video.currentTime).toBeCloseTo(0);
|
|
280
284
|
|
|
281
285
|
// Start playback and wait. We should see the playhead move.
|
|
282
|
-
video.play();
|
|
286
|
+
await video.play();
|
|
283
287
|
await waiter.waitForMovementOrFailOnTimeout(video, /* timeout= */10);
|
|
284
288
|
await shaka.test.Util.delay(1.5);
|
|
285
289
|
|
|
@@ -296,7 +300,7 @@ describe('Player Src Equals', () => {
|
|
|
296
300
|
|
|
297
301
|
// Wait some time for playback to start so that we will have a load latency
|
|
298
302
|
// value.
|
|
299
|
-
video.play();
|
|
303
|
+
await video.play();
|
|
300
304
|
await waiter.waitForMovementOrFailOnTimeout(video, /* timeout= */10);
|
|
301
305
|
|
|
302
306
|
// Get the stats and check that some stats have been filled in.
|
|
@@ -12,9 +12,13 @@
|
|
|
12
12
|
*/
|
|
13
13
|
shaka.test.FakeDemoMain = class {
|
|
14
14
|
constructor() {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
// Using the player's constructor argument to attach a video element seems
|
|
16
|
+
// to cause flaky timeouts on teardown. If a video element is needed in
|
|
17
|
+
// the future, please explicitly call attach(video) and await the result
|
|
18
|
+
// during the test setup.
|
|
19
|
+
/** @type {!shaka.Player} */
|
|
20
|
+
this.player = new shaka.Player();
|
|
21
|
+
|
|
18
22
|
this.config_ = this.player.getConfiguration();
|
|
19
23
|
this.selectedAsset = null;
|
|
20
24
|
|
|
@@ -395,7 +395,7 @@ shaka.test.NativeTextLayoutTests = class extends shaka.test.TextLayoutTests {
|
|
|
395
395
|
// The this.video must be played a little now, after the cues were appended,
|
|
396
396
|
// but before the screenshot.
|
|
397
397
|
this.video.playbackRate = 1;
|
|
398
|
-
this.video.play();
|
|
398
|
+
await this.video.play();
|
|
399
399
|
await this.waiter.failOnTimeout(false).timeoutAfter(5)
|
|
400
400
|
.waitForMovement(this.video);
|
|
401
401
|
this.video.pause();
|
|
@@ -404,7 +404,7 @@ shaka.test.NativeTextLayoutTests = class extends shaka.test.TextLayoutTests {
|
|
|
404
404
|
this.video.currentTime = time;
|
|
405
405
|
// Get into a playing state, but without movement.
|
|
406
406
|
this.video.playbackRate = 0;
|
|
407
|
-
this.video.play();
|
|
407
|
+
await this.video.play();
|
|
408
408
|
|
|
409
409
|
// Add a short delay to ensure that the system has caught up and that
|
|
410
410
|
// native text displayers have been updated by the browser.
|
|
@@ -115,11 +115,18 @@ shaka.test.UiUtils = class {
|
|
|
115
115
|
// Destroying the UI destroys the controls and player inside.
|
|
116
116
|
destroys.push(ui.destroy());
|
|
117
117
|
}
|
|
118
|
-
|
|
118
|
+
|
|
119
|
+
const allDestroyed = Promise.all(destroys);
|
|
120
|
+
// 10 seconds should be more than enough to tear down the UI.
|
|
121
|
+
// Adding this silent timeout fixes several tests that inconsistently hang
|
|
122
|
+
// during teardown and cause failures in afterEach() clauses.
|
|
123
|
+
await Promise.race([allDestroyed, shaka.test.Util.delay(10)]);
|
|
119
124
|
|
|
120
125
|
// Now remove all the containers from the DOM.
|
|
121
126
|
for (const container of containers) {
|
|
122
|
-
container.parentElement
|
|
127
|
+
if (container.parentElement) {
|
|
128
|
+
container.parentElement.removeChild(container);
|
|
129
|
+
}
|
|
123
130
|
}
|
|
124
131
|
}
|
|
125
132
|
|