shaka-player 4.3.8 → 4.3.9
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 +8 -0
- package/.github/workflows/selenium-lab-tests.yaml +3 -2
- package/.github/workflows/update-issues.yaml +1 -0
- package/CHANGELOG.md +19 -0
- package/dist/deps.js +1 -1
- package/dist/locales.js +30 -30
- package/dist/shaka-player.compiled.d.ts +2 -2
- package/dist/shaka-player.compiled.debug.d.ts +2 -2
- package/dist/shaka-player.compiled.debug.js +50 -48
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.js +385 -385
- package/dist/shaka-player.compiled.map +2 -2
- package/dist/shaka-player.ui.d.ts +2 -2
- package/dist/shaka-player.ui.debug.d.ts +2 -2
- package/dist/shaka-player.ui.debug.js +54 -52
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.js +400 -399
- package/dist/shaka-player.ui.map +3 -3
- package/docs/tutorials/selenium-grid-config.md +60 -8
- package/externs/shaka/manifest.js +5 -1
- package/externs/shaka/offline.js +5 -1
- package/karma.conf.js +50 -7
- package/lib/abr/simple_abr_manager.js +5 -5
- package/lib/dash/dash_parser.js +1 -0
- package/lib/hls/hls_parser.js +1 -0
- package/lib/media/media_source_engine.js +6 -5
- package/lib/media/streaming_engine.js +2 -2
- package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
- package/lib/offline/manifest_converter.js +1 -0
- package/lib/offline/storage.js +1 -0
- package/lib/player.js +9 -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/periods.js +2 -0
- 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/adaptation_set_unit.js +1 -0
- package/test/media/drm_engine_integration.js +2 -2
- package/test/media/media_source_engine_unit.js +1 -1
- package/test/media/segment_index_unit.js +3 -3
- package/test/media/streaming_engine_integration.js +14 -11
- package/test/offline/manifest_convert_unit.js +5 -0
- 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/manifest_generator.js +2 -0
- package/test/test/util/offline_utils.js +1 -0
- package/test/test/util/streaming_engine_util.js +3 -0
- 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
package/lib/util/stream_utils.js
CHANGED
|
@@ -437,48 +437,62 @@ shaka.util.StreamUtils = class {
|
|
|
437
437
|
manifest.variants = manifest.variants.filter((variant) => {
|
|
438
438
|
// See: https://github.com/shaka-project/shaka-player/issues/3860
|
|
439
439
|
const video = variant.video;
|
|
440
|
+
|
|
440
441
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
441
442
|
const Capabilities = shaka.media.Capabilities;
|
|
443
|
+
const ManifestParserUtils = shaka.util.ManifestParserUtils;
|
|
444
|
+
const MimeUtils = shaka.util.MimeUtils;
|
|
445
|
+
const StreamUtils = shaka.util.StreamUtils;
|
|
446
|
+
|
|
442
447
|
if (video) {
|
|
443
|
-
let videoCodecs =
|
|
444
|
-
|
|
448
|
+
let videoCodecs = StreamUtils.getCorrectVideoCodecs_(video.codecs);
|
|
449
|
+
|
|
445
450
|
// For multiplexed streams. Here we must check the audio of the
|
|
446
451
|
// stream to see if it is compatible.
|
|
447
452
|
if (video.codecs.includes(',')) {
|
|
448
453
|
const allCodecs = video.codecs.split(',');
|
|
449
|
-
|
|
454
|
+
|
|
455
|
+
videoCodecs = ManifestParserUtils.guessCodecs(
|
|
450
456
|
ContentType.VIDEO, allCodecs);
|
|
451
|
-
videoCodecs =
|
|
452
|
-
|
|
453
|
-
let audioCodecs =
|
|
457
|
+
videoCodecs = StreamUtils.getCorrectVideoCodecs_(videoCodecs);
|
|
458
|
+
|
|
459
|
+
let audioCodecs = ManifestParserUtils.guessCodecs(
|
|
454
460
|
ContentType.AUDIO, allCodecs);
|
|
455
|
-
audioCodecs =
|
|
456
|
-
|
|
457
|
-
const audioFullType =
|
|
461
|
+
audioCodecs = StreamUtils.getCorrectAudioCodecs_(audioCodecs);
|
|
462
|
+
|
|
463
|
+
const audioFullType = MimeUtils.getFullOrConvertedType(
|
|
458
464
|
video.mimeType, audioCodecs, ContentType.AUDIO);
|
|
465
|
+
|
|
459
466
|
if (!Capabilities.isTypeSupported(audioFullType)) {
|
|
460
467
|
return false;
|
|
461
468
|
}
|
|
469
|
+
|
|
462
470
|
// Update the codec string with the (possibly) converted codecs.
|
|
463
471
|
videoCodecs = [videoCodecs, audioCodecs].join(',');
|
|
464
472
|
}
|
|
465
|
-
|
|
473
|
+
|
|
474
|
+
const fullType = MimeUtils.getFullOrConvertedType(
|
|
466
475
|
video.mimeType, videoCodecs, ContentType.VIDEO);
|
|
476
|
+
|
|
467
477
|
if (!Capabilities.isTypeSupported(fullType)) {
|
|
468
478
|
return false;
|
|
469
479
|
}
|
|
480
|
+
|
|
470
481
|
// Update the codec string with the (possibly) converted codecs.
|
|
471
482
|
video.codecs = videoCodecs;
|
|
472
483
|
}
|
|
484
|
+
|
|
473
485
|
const audio = variant.audio;
|
|
486
|
+
|
|
474
487
|
if (audio) {
|
|
475
|
-
const codecs =
|
|
476
|
-
|
|
477
|
-
const fullType = shaka.util.MimeUtils.getFullOrConvertedType(
|
|
488
|
+
const codecs = StreamUtils.getCorrectAudioCodecs_(audio.codecs);
|
|
489
|
+
const fullType = MimeUtils.getFullOrConvertedType(
|
|
478
490
|
audio.mimeType, codecs, ContentType.AUDIO);
|
|
491
|
+
|
|
479
492
|
if (!Capabilities.isTypeSupported(fullType)) {
|
|
480
493
|
return false;
|
|
481
494
|
}
|
|
495
|
+
|
|
482
496
|
// Update the codec string with the (possibly) converted codecs.
|
|
483
497
|
audio.codecs = codecs;
|
|
484
498
|
}
|
|
@@ -490,7 +504,7 @@ shaka.util.StreamUtils = class {
|
|
|
490
504
|
(video.codecs.includes('avc1.') ||
|
|
491
505
|
video.codecs.includes('avc3.'))) {
|
|
492
506
|
shaka.log.debug('Dropping variant - not compatible with platform',
|
|
493
|
-
|
|
507
|
+
StreamUtils.getVariantSummaryString_(variant));
|
|
494
508
|
return false;
|
|
495
509
|
}
|
|
496
510
|
|
|
@@ -500,7 +514,7 @@ shaka.util.StreamUtils = class {
|
|
|
500
514
|
// Filter out all unsupported variants.
|
|
501
515
|
if (!supported) {
|
|
502
516
|
shaka.log.debug('Dropping variant - not compatible with platform',
|
|
503
|
-
|
|
517
|
+
StreamUtils.getVariantSummaryString_(variant));
|
|
504
518
|
}
|
|
505
519
|
return supported;
|
|
506
520
|
});
|
|
@@ -564,7 +578,11 @@ shaka.util.StreamUtils = class {
|
|
|
564
578
|
static getDecodingConfigs_(variant, usePersistentLicenses, srcEquals) {
|
|
565
579
|
const audio = variant.audio;
|
|
566
580
|
const video = variant.video;
|
|
581
|
+
|
|
567
582
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
583
|
+
const ManifestParserUtils = shaka.util.ManifestParserUtils;
|
|
584
|
+
const MimeUtils = shaka.util.MimeUtils;
|
|
585
|
+
const StreamUtils = shaka.util.StreamUtils;
|
|
568
586
|
|
|
569
587
|
/** @type {!MediaDecodingConfiguration} */
|
|
570
588
|
const mediaDecodingConfig = {
|
|
@@ -573,19 +591,23 @@ shaka.util.StreamUtils = class {
|
|
|
573
591
|
|
|
574
592
|
if (video) {
|
|
575
593
|
let videoCodecs = video.codecs;
|
|
594
|
+
|
|
576
595
|
// For multiplexed streams with audio+video codecs, the config should have
|
|
577
596
|
// AudioConfiguration and VideoConfiguration.
|
|
578
597
|
if (video.codecs.includes(',')) {
|
|
579
598
|
const allCodecs = video.codecs.split(',');
|
|
580
|
-
|
|
599
|
+
|
|
600
|
+
videoCodecs = ManifestParserUtils.guessCodecs(
|
|
581
601
|
ContentType.VIDEO, allCodecs);
|
|
582
|
-
videoCodecs =
|
|
583
|
-
|
|
584
|
-
|
|
602
|
+
videoCodecs = StreamUtils.getCorrectVideoCodecs_(videoCodecs);
|
|
603
|
+
|
|
604
|
+
let audioCodecs = ManifestParserUtils.guessCodecs(
|
|
585
605
|
ContentType.AUDIO, allCodecs);
|
|
606
|
+
audioCodecs = StreamUtils.getCorrectAudioCodecs_(audioCodecs);
|
|
586
607
|
|
|
587
|
-
const audioFullType =
|
|
608
|
+
const audioFullType = MimeUtils.getFullOrConvertedType(
|
|
588
609
|
video.mimeType, audioCodecs, ContentType.AUDIO);
|
|
610
|
+
|
|
589
611
|
mediaDecodingConfig.audio = {
|
|
590
612
|
contentType: audioFullType,
|
|
591
613
|
channels: 2,
|
|
@@ -594,9 +616,11 @@ shaka.util.StreamUtils = class {
|
|
|
594
616
|
spatialRendering: false,
|
|
595
617
|
};
|
|
596
618
|
}
|
|
597
|
-
|
|
598
|
-
|
|
619
|
+
|
|
620
|
+
videoCodecs = StreamUtils.getCorrectVideoCodecs_(videoCodecs);
|
|
621
|
+
const fullType = MimeUtils.getFullOrConvertedType(
|
|
599
622
|
video.mimeType, videoCodecs, ContentType.VIDEO);
|
|
623
|
+
|
|
600
624
|
// VideoConfiguration
|
|
601
625
|
mediaDecodingConfig.video = {
|
|
602
626
|
contentType: fullType,
|
|
@@ -629,9 +653,8 @@ shaka.util.StreamUtils = class {
|
|
|
629
653
|
}
|
|
630
654
|
}
|
|
631
655
|
if (audio) {
|
|
632
|
-
const codecs =
|
|
633
|
-
|
|
634
|
-
const fullType = shaka.util.MimeUtils.getFullOrConvertedType(
|
|
656
|
+
const codecs = StreamUtils.getCorrectAudioCodecs_(audio.codecs);
|
|
657
|
+
const fullType = MimeUtils.getFullOrConvertedType(
|
|
635
658
|
audio.mimeType, codecs, ContentType.AUDIO);
|
|
636
659
|
|
|
637
660
|
// AudioConfiguration
|
|
@@ -762,6 +785,20 @@ shaka.util.StreamUtils = class {
|
|
|
762
785
|
* @private
|
|
763
786
|
*/
|
|
764
787
|
static getCorrectAudioCodecs_(codecs) {
|
|
788
|
+
// According to RFC 6381 section 3.3, 'fLaC' is actually the correct
|
|
789
|
+
// codec string. We still need to map it to 'flac', as some browsers
|
|
790
|
+
// currently don't support 'fLaC', while 'flac' is supported by most
|
|
791
|
+
// major browsers.
|
|
792
|
+
// See https://bugs.chromium.org/p/chromium/issues/detail?id=1422728
|
|
793
|
+
if (codecs === 'fLaC') {
|
|
794
|
+
return 'flac';
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// The same is true for 'Opus'.
|
|
798
|
+
if (codecs === 'Opus') {
|
|
799
|
+
return 'opus';
|
|
800
|
+
}
|
|
801
|
+
|
|
765
802
|
// Some Tizen devices seem to misreport AC-3 support, but correctly
|
|
766
803
|
// report EC-3 support. So query EC-3 as a fallback for AC-3.
|
|
767
804
|
// See https://github.com/shaka-project/shaka-player/issues/2989 for
|
|
@@ -1240,6 +1277,9 @@ shaka.util.StreamUtils = class {
|
|
|
1240
1277
|
if (textTrack.kind == 'captions') {
|
|
1241
1278
|
track.mimeType = CLOSED_CAPTION_MIMETYPE;
|
|
1242
1279
|
}
|
|
1280
|
+
if (textTrack.kind == 'subtitles') {
|
|
1281
|
+
track.mimeType = 'text/vtt';
|
|
1282
|
+
}
|
|
1243
1283
|
if (textTrack.kind) {
|
|
1244
1284
|
track.roles = [textTrack.kind];
|
|
1245
1285
|
}
|
|
@@ -1287,13 +1327,15 @@ shaka.util.StreamUtils = class {
|
|
|
1287
1327
|
* @private
|
|
1288
1328
|
*/
|
|
1289
1329
|
static html5TrackToGenericShakaTrack_(html5Track) {
|
|
1330
|
+
const language = html5Track.language;
|
|
1331
|
+
|
|
1290
1332
|
/** @type {shaka.extern.Track} */
|
|
1291
1333
|
const track = {
|
|
1292
1334
|
id: shaka.util.StreamUtils.html5TrackId(html5Track),
|
|
1293
1335
|
active: false,
|
|
1294
1336
|
type: '',
|
|
1295
1337
|
bandwidth: 0,
|
|
1296
|
-
language: shaka.util.LanguageUtils.normalize(
|
|
1338
|
+
language: shaka.util.LanguageUtils.normalize(language || 'und'),
|
|
1297
1339
|
label: html5Track.label,
|
|
1298
1340
|
kind: html5Track.kind,
|
|
1299
1341
|
width: null,
|
|
@@ -1323,6 +1365,7 @@ shaka.util.StreamUtils = class {
|
|
|
1323
1365
|
originalAudioId: null,
|
|
1324
1366
|
originalTextId: null,
|
|
1325
1367
|
originalImageId: null,
|
|
1368
|
+
originalLanguage: language,
|
|
1326
1369
|
};
|
|
1327
1370
|
|
|
1328
1371
|
return track;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shaka-player",
|
|
3
3
|
"description": "DASH/EME video player library",
|
|
4
|
-
"version": "4.3.
|
|
4
|
+
"version": "4.3.9",
|
|
5
5
|
"homepage": "https://github.com/shaka-project/shaka-player",
|
|
6
6
|
"author": "Google",
|
|
7
7
|
"maintainers": [
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"karma-coverage": "^2.2.0",
|
|
43
43
|
"karma-jasmine": "^4.0.1",
|
|
44
44
|
"karma-jasmine-ajax": "^0.1.13",
|
|
45
|
-
"karma-local-wd-launcher": "^1.6.
|
|
45
|
+
"karma-local-wd-launcher": "^1.6.4",
|
|
46
46
|
"karma-opera-launcher": "^1.0.0",
|
|
47
47
|
"karma-sourcemap-loader": "^0.3.8",
|
|
48
48
|
"karma-spec-reporter": "^0.0.34",
|
|
@@ -171,7 +171,10 @@ describe('CastUtils', () => {
|
|
|
171
171
|
}
|
|
172
172
|
});
|
|
173
173
|
|
|
174
|
-
|
|
174
|
+
// Disable because these tests are flakey on ChromeLinux, and this whole
|
|
175
|
+
// module will be removed in
|
|
176
|
+
// https://github.com/shaka-project/shaka-player/issues/4214
|
|
177
|
+
xdescribe('TimeRanges', () => {
|
|
175
178
|
/** @type {!HTMLVideoElement} */
|
|
176
179
|
let video;
|
|
177
180
|
/** @type {!shaka.util.EventManager} */
|
|
@@ -628,6 +628,78 @@ describe('HlsParser', () => {
|
|
|
628
628
|
await testHlsParser(master, media, manifest);
|
|
629
629
|
});
|
|
630
630
|
|
|
631
|
+
it('accepts fLaC codec as audio/mp4', async () => {
|
|
632
|
+
const master = [
|
|
633
|
+
'#EXTM3U\n',
|
|
634
|
+
'#EXT-X-STREAM-INF:BANDWIDTH=1000000,CODECS="fLaC"\n',
|
|
635
|
+
'audio\n',
|
|
636
|
+
'#EXT-X-STREAM-INF:BANDWIDTH=1000000,CODECS="flac"\n',
|
|
637
|
+
'audio2\n',
|
|
638
|
+
].join('');
|
|
639
|
+
|
|
640
|
+
const media = [
|
|
641
|
+
'#EXTM3U\n',
|
|
642
|
+
'#EXT-X-PLAYLIST-TYPE:VOD\n',
|
|
643
|
+
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
644
|
+
'#EXTINF:5,\n',
|
|
645
|
+
'#EXT-X-BYTERANGE:121090@616\n',
|
|
646
|
+
'main.mp4',
|
|
647
|
+
].join('');
|
|
648
|
+
|
|
649
|
+
const manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
650
|
+
manifest.anyTimeline();
|
|
651
|
+
manifest.addPartialVariant((variant) => {
|
|
652
|
+
variant.addPartialStream(ContentType.AUDIO, (stream) => {
|
|
653
|
+
stream.mime('audio/mp4', 'fLaC');
|
|
654
|
+
});
|
|
655
|
+
});
|
|
656
|
+
manifest.addPartialVariant((variant) => {
|
|
657
|
+
variant.addPartialStream(ContentType.AUDIO, (stream) => {
|
|
658
|
+
stream.mime('audio/mp4', 'flac');
|
|
659
|
+
});
|
|
660
|
+
});
|
|
661
|
+
manifest.sequenceMode = true;
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
await testHlsParser(master, media, manifest);
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
it('accepts Opus codec as audio/mp4', async () => {
|
|
668
|
+
const master = [
|
|
669
|
+
'#EXTM3U\n',
|
|
670
|
+
'#EXT-X-STREAM-INF:BANDWIDTH=128000,CODECS="Opus"\n',
|
|
671
|
+
'audio\n',
|
|
672
|
+
'#EXT-X-STREAM-INF:BANDWIDTH=128000,CODECS="opus"\n',
|
|
673
|
+
'audio2\n',
|
|
674
|
+
].join('');
|
|
675
|
+
|
|
676
|
+
const media = [
|
|
677
|
+
'#EXTM3U\n',
|
|
678
|
+
'#EXT-X-PLAYLIST-TYPE:VOD\n',
|
|
679
|
+
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
680
|
+
'#EXTINF:5,\n',
|
|
681
|
+
'#EXT-X-BYTERANGE:121090@616\n',
|
|
682
|
+
'main.mp4',
|
|
683
|
+
].join('');
|
|
684
|
+
|
|
685
|
+
const manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
686
|
+
manifest.anyTimeline();
|
|
687
|
+
manifest.addPartialVariant((variant) => {
|
|
688
|
+
variant.addPartialStream(ContentType.AUDIO, (stream) => {
|
|
689
|
+
stream.mime('audio/mp4', 'Opus');
|
|
690
|
+
});
|
|
691
|
+
});
|
|
692
|
+
manifest.addPartialVariant((variant) => {
|
|
693
|
+
variant.addPartialStream(ContentType.AUDIO, (stream) => {
|
|
694
|
+
stream.mime('audio/mp4', 'opus');
|
|
695
|
+
});
|
|
696
|
+
});
|
|
697
|
+
manifest.sequenceMode = true;
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
await testHlsParser(master, media, manifest);
|
|
701
|
+
});
|
|
702
|
+
|
|
631
703
|
it('parses audio+video variant with closed captions', async () => {
|
|
632
704
|
const master = [
|
|
633
705
|
'#EXTM3U\n',
|
|
@@ -244,7 +244,7 @@ describe('DrmEngine', () => {
|
|
|
244
244
|
/* hasClosedCaptions= */ false);
|
|
245
245
|
|
|
246
246
|
expect(video.buffered.end(0)).toBeGreaterThan(0);
|
|
247
|
-
video.play();
|
|
247
|
+
await video.play();
|
|
248
248
|
|
|
249
249
|
const waiter = new shaka.test.Waiter(eventManager).timeoutAfter(15);
|
|
250
250
|
waiter.setMediaSourceEngine(mediaSourceEngine);
|
|
@@ -327,7 +327,7 @@ describe('DrmEngine', () => {
|
|
|
327
327
|
/* hasClosedCaptions= */ false);
|
|
328
328
|
|
|
329
329
|
expect(video.buffered.end(0)).toBeGreaterThan(0);
|
|
330
|
-
video.play();
|
|
330
|
+
await video.play();
|
|
331
331
|
|
|
332
332
|
const waiter = new shaka.test.Waiter(eventManager).timeoutAfter(15);
|
|
333
333
|
waiter.setMediaSourceEngine(mediaSourceEngine);
|
|
@@ -1262,7 +1262,7 @@ describe('MediaSourceEngine', () => {
|
|
|
1262
1262
|
});
|
|
1263
1263
|
|
|
1264
1264
|
it('destroys text engines', async () => {
|
|
1265
|
-
mediaSourceEngine.reinitText('text/vtt', false);
|
|
1265
|
+
mediaSourceEngine.reinitText('text/vtt', false, false);
|
|
1266
1266
|
|
|
1267
1267
|
await mediaSourceEngine.destroy();
|
|
1268
1268
|
expect(mockTextEngine).toBeTruthy();
|
|
@@ -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');
|
|
@@ -279,7 +282,7 @@ describe('StreamingEngine', () => {
|
|
|
279
282
|
// Let's go!
|
|
280
283
|
streamingEngine.switchVariant(variant);
|
|
281
284
|
await streamingEngine.start();
|
|
282
|
-
video.play();
|
|
285
|
+
await video.play();
|
|
283
286
|
// The overall test timeout is 120 seconds, and the content is 40
|
|
284
287
|
// seconds. It should be possible to complete this test in 100 seconds,
|
|
285
288
|
// and if not, we want the error thrown to be within the overall test's
|
|
@@ -299,7 +302,7 @@ describe('StreamingEngine', () => {
|
|
|
299
302
|
// Let's go!
|
|
300
303
|
streamingEngine.switchVariant(variant);
|
|
301
304
|
await streamingEngine.start();
|
|
302
|
-
video.play();
|
|
305
|
+
await video.play();
|
|
303
306
|
|
|
304
307
|
// Wait for playback to begin before increasing the playback rate. This
|
|
305
308
|
// improves test reliability on slow platforms like Chromecast.
|
|
@@ -313,7 +316,7 @@ describe('StreamingEngine', () => {
|
|
|
313
316
|
// Let's go!
|
|
314
317
|
streamingEngine.switchVariant(variant);
|
|
315
318
|
await streamingEngine.start();
|
|
316
|
-
video.play();
|
|
319
|
+
await video.play();
|
|
317
320
|
|
|
318
321
|
// After 35 seconds seek back 10 seconds into the first Period.
|
|
319
322
|
await waiter.timeoutAfter(80).waitUntilPlayheadReaches(video, 35);
|
|
@@ -325,7 +328,7 @@ describe('StreamingEngine', () => {
|
|
|
325
328
|
// Let's go!
|
|
326
329
|
streamingEngine.switchVariant(variant);
|
|
327
330
|
await streamingEngine.start();
|
|
328
|
-
video.play();
|
|
331
|
+
await video.play();
|
|
329
332
|
await waiter.timeoutAfter(60).waitUntilPlayheadReaches(video, 20);
|
|
330
333
|
video.currentTime = 40;
|
|
331
334
|
await waiter.timeoutAfter(60).waitForEnd(video);
|
|
@@ -353,7 +356,7 @@ describe('StreamingEngine', () => {
|
|
|
353
356
|
streamingEngine.switchVariant(variant);
|
|
354
357
|
await streamingEngine.start();
|
|
355
358
|
|
|
356
|
-
video.play();
|
|
359
|
+
await video.play();
|
|
357
360
|
await waiter.timeoutAfter(60).waitUntilPlayheadReaches(video, 305);
|
|
358
361
|
|
|
359
362
|
const segmentType = shaka.net.NetworkingEngine.RequestType.SEGMENT;
|
|
@@ -373,7 +376,7 @@ describe('StreamingEngine', () => {
|
|
|
373
376
|
// Seek outside the availability window right away. The playhead
|
|
374
377
|
// should adjust the video's current time.
|
|
375
378
|
video.currentTime = segmentAvailability.end + 120;
|
|
376
|
-
video.play();
|
|
379
|
+
await video.play();
|
|
377
380
|
|
|
378
381
|
// Wait until the repositioning is complete so we don't
|
|
379
382
|
// immediately hit this case.
|
|
@@ -398,7 +401,7 @@ describe('StreamingEngine', () => {
|
|
|
398
401
|
video.currentTime = segmentAvailability.start - 120;
|
|
399
402
|
expect(video.currentTime).toBeGreaterThan(0);
|
|
400
403
|
|
|
401
|
-
video.play();
|
|
404
|
+
await video.play();
|
|
402
405
|
await waiter.timeoutAfter(60).waitUntilPlayheadReaches(video, 305);
|
|
403
406
|
|
|
404
407
|
// We are playing close to the beginning of the availability window.
|
|
@@ -426,7 +429,7 @@ describe('StreamingEngine', () => {
|
|
|
426
429
|
// Let's go!
|
|
427
430
|
streamingEngine.switchVariant(variant);
|
|
428
431
|
await streamingEngine.start();
|
|
429
|
-
video.play();
|
|
432
|
+
await video.play();
|
|
430
433
|
|
|
431
434
|
await waiter.timeoutAfter(5).waitUntilPlayheadReaches(video, 0.01);
|
|
432
435
|
expect(video.buffered.length).toBeGreaterThan(0);
|
|
@@ -441,7 +444,7 @@ describe('StreamingEngine', () => {
|
|
|
441
444
|
// Let's go!
|
|
442
445
|
streamingEngine.switchVariant(variant);
|
|
443
446
|
await streamingEngine.start();
|
|
444
|
-
video.play();
|
|
447
|
+
await video.play();
|
|
445
448
|
|
|
446
449
|
await waiter.timeoutAfter(5).waitUntilPlayheadReaches(video, 0.01);
|
|
447
450
|
expect(video.buffered.length).toBeGreaterThan(0);
|
|
@@ -460,7 +463,7 @@ describe('StreamingEngine', () => {
|
|
|
460
463
|
await waiter.timeoutAfter(5).waitForEvent(video, 'loadeddata');
|
|
461
464
|
|
|
462
465
|
video.currentTime = 8;
|
|
463
|
-
video.play();
|
|
466
|
+
await video.play();
|
|
464
467
|
|
|
465
468
|
await waiter.timeoutAfter(60).waitUntilPlayheadReaches(video, 23);
|
|
466
469
|
// Should be close enough to still have the gap buffered.
|
|
@@ -477,7 +480,7 @@ describe('StreamingEngine', () => {
|
|
|
477
480
|
await waiter.timeoutAfter(5).waitForEvent(video, 'loadeddata');
|
|
478
481
|
|
|
479
482
|
video.currentTime = 8;
|
|
480
|
-
video.play();
|
|
483
|
+
await video.play();
|
|
481
484
|
|
|
482
485
|
await waiter.timeoutAfter(60).waitUntilPlayheadReaches(video, 23);
|
|
483
486
|
// Should be close enough to still have the gap buffered.
|
|
@@ -316,6 +316,7 @@ describe('ManifestConverter', () => {
|
|
|
316
316
|
audioSamplingRate: null,
|
|
317
317
|
spatialAudio: false,
|
|
318
318
|
closedCaptions: null,
|
|
319
|
+
external: false,
|
|
319
320
|
};
|
|
320
321
|
|
|
321
322
|
return streamDB;
|
|
@@ -389,6 +390,7 @@ describe('ManifestConverter', () => {
|
|
|
389
390
|
spatialAudio: false,
|
|
390
391
|
closedCaptions: null,
|
|
391
392
|
tilesLayout: undefined,
|
|
393
|
+
external: false,
|
|
392
394
|
};
|
|
393
395
|
}
|
|
394
396
|
|
|
@@ -438,6 +440,7 @@ describe('ManifestConverter', () => {
|
|
|
438
440
|
spatialAudio: false,
|
|
439
441
|
closedCaptions: null,
|
|
440
442
|
tilesLayout: undefined,
|
|
443
|
+
external: false,
|
|
441
444
|
};
|
|
442
445
|
}
|
|
443
446
|
|
|
@@ -486,6 +489,7 @@ describe('ManifestConverter', () => {
|
|
|
486
489
|
spatialAudio: false,
|
|
487
490
|
closedCaptions: null,
|
|
488
491
|
tilesLayout: undefined,
|
|
492
|
+
external: false,
|
|
489
493
|
};
|
|
490
494
|
}
|
|
491
495
|
|
|
@@ -531,6 +535,7 @@ describe('ManifestConverter', () => {
|
|
|
531
535
|
spatialAudio: streamDb.spatialAudio,
|
|
532
536
|
closedCaptions: streamDb.closedCaptions,
|
|
533
537
|
tilesLayout: streamDb.tilesLayout,
|
|
538
|
+
external: streamDb.external,
|
|
534
539
|
};
|
|
535
540
|
|
|
536
541
|
expect(stream).toEqual(expectedStream);
|
|
@@ -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.
|