shaka-player 3.2.6 → 3.2.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/workflows/build-and-test.yaml +0 -1
- package/.github/workflows/release-please.yaml +4 -3
- package/.github/workflows/selenium-lab-tests.yaml +0 -1
- package/AUTHORS +1 -1
- package/CHANGELOG.md +39 -0
- package/CONTRIBUTORS +2 -1
- package/README.md +4 -4
- package/build/README.md +2 -2
- package/build/generateTsDefs.py +0 -2
- package/build/test.py +8 -2
- package/demo/common/assets.js +1 -1
- package/demo/demo.less +0 -1
- package/demo/main.js +3 -3
- package/dist/controls.css +2 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +3 -3
- package/dist/demo.compiled.debug.map +2 -2
- package/dist/demo.compiled.js +3 -3
- package/dist/demo.compiled.map +2 -2
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +1 -1
- package/dist/locales.js +28 -28
- package/dist/receiver.compiled.debug.js +1 -1
- package/dist/receiver.compiled.debug.map +1 -1
- package/dist/receiver.compiled.js +1 -1
- package/dist/receiver.compiled.map +1 -1
- package/dist/shaka-player.compiled.d.ts +1 -2
- package/dist/shaka-player.compiled.debug.d.ts +1 -2
- package/dist/shaka-player.compiled.debug.externs.js +1 -0
- package/dist/shaka-player.compiled.debug.js +213 -207
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +1 -0
- package/dist/shaka-player.compiled.js +775 -769
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +1 -2
- package/dist/shaka-player.ui.debug.d.ts +1 -2
- package/dist/shaka-player.ui.debug.externs.js +1 -0
- package/dist/shaka-player.ui.debug.js +241 -236
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +1 -0
- package/dist/shaka-player.ui.js +898 -891
- package/dist/shaka-player.ui.map +4 -4
- package/karma.conf.js +4 -0
- package/lib/abr/simple_abr_manager.js +2 -1
- package/lib/dash/dash_parser.js +2 -3
- package/lib/hls/hls_parser.js +45 -18
- package/lib/media/drm_engine.js +3 -0
- package/lib/media/media_source_engine.js +7 -1
- package/lib/offline/indexeddb/storage_mechanism.js +4 -2
- package/lib/player.js +165 -107
- package/lib/util/config_utils.js +25 -0
- package/lib/util/error.js +7 -0
- package/lib/util/manifest_parser_utils.js +1 -1
- package/lib/util/mime_utils.js +62 -6
- package/lib/util/periods.js +5 -4
- package/lib/util/player_configuration.js +9 -14
- package/lib/util/stream_utils.js +5 -2
- package/package.json +6 -3
- package/test/cast/cast_utils_unit.js +1 -0
- package/test/dash/dash_parser_manifest_unit.js +0 -24
- package/test/hls/hls_live_unit.js +86 -7
- package/test/hls/manifest_text_parser_unit.js +19 -0
- package/test/media/media_source_engine_integration.js +1 -0
- package/test/media/media_source_engine_unit.js +4 -4
- package/test/media/streaming_engine_integration.js +2 -0
- package/test/offline/indexeddb_storage_unit.js +1 -1
- package/test/offline/storage_compatibility_unit.js +1 -1
- package/test/player_external.js +7 -1
- package/test/player_integration.js +6 -10
- package/test/player_src_equals_integration.js +81 -83
- package/test/player_unit.js +98 -1
- package/test/test/boot.js +9 -0
- package/test/test/externs/filters.js +4 -0
- package/test/test/util/simple_fakes.js +31 -2
- package/test/util/mime_utils_unit.js +54 -0
- package/test/util/periods_unit.js +79 -0
- package/ui/less/containers.less +1 -1
- package/ui/less/general.less +1 -1
- package/ui/less/range_elements.less +1 -0
- package/.github/pull_request_template.md +0 -38
- package/docs/tutorials/gsoc-ideas-list.md +0 -3
package/lib/util/periods.js
CHANGED
|
@@ -574,8 +574,8 @@ shaka.util.PeriodCombiner = class {
|
|
|
574
574
|
// TODO(#1528): Consider changing this when we support codec switching.
|
|
575
575
|
const hasCodec = outputStreams.some((s) => {
|
|
576
576
|
return s.mimeType == stream.mimeType &&
|
|
577
|
-
shaka.util.MimeUtils.
|
|
578
|
-
shaka.util.MimeUtils.
|
|
577
|
+
shaka.util.MimeUtils.getNormalizedCodec(s.codecs) ==
|
|
578
|
+
shaka.util.MimeUtils.getNormalizedCodec(stream.codecs);
|
|
579
579
|
});
|
|
580
580
|
if (!hasCodec) {
|
|
581
581
|
continue;
|
|
@@ -1016,10 +1016,11 @@ shaka.util.PeriodCombiner = class {
|
|
|
1016
1016
|
* @private
|
|
1017
1017
|
*/
|
|
1018
1018
|
static areAVStreamsCompatible_(outputStream, candidate) {
|
|
1019
|
-
const
|
|
1019
|
+
const getCodec = (codecs) =>
|
|
1020
|
+
shaka.util.MimeUtils.getNormalizedCodec(codecs);
|
|
1020
1021
|
// Check MIME type and codecs, which should always be the same.
|
|
1021
1022
|
if (candidate.mimeType != outputStream.mimeType ||
|
|
1022
|
-
|
|
1023
|
+
getCodec(candidate.codecs) != getCodec(outputStream.codecs)) {
|
|
1023
1024
|
return false;
|
|
1024
1025
|
}
|
|
1025
1026
|
|
|
@@ -17,14 +17,6 @@ goog.require('shaka.util.ManifestParserUtils');
|
|
|
17
17
|
goog.require('shaka.util.Platform');
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
// TODO(vaage): Many times in our configs, we need to create an empty
|
|
21
|
-
// implementation of a method, but to avoid closure from removing unused
|
|
22
|
-
// parameters (and breaking our merge config code) we need to use each
|
|
23
|
-
// parameter. Is there a better solution to this problem than what we are
|
|
24
|
-
// doing now?
|
|
25
|
-
//
|
|
26
|
-
// NOTE: Chrome App Content Security Policy prohibits usage of new Function()
|
|
27
|
-
|
|
28
20
|
/**
|
|
29
21
|
* @final
|
|
30
22
|
* @export
|
|
@@ -109,11 +101,10 @@ shaka.util.PlayerConfiguration = class {
|
|
|
109
101
|
'urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb':
|
|
110
102
|
'com.adobe.primetime',
|
|
111
103
|
},
|
|
112
|
-
// Need some operation in the callback or else closure may remove calls
|
|
113
|
-
// to the function as it would be a no-op. The operation can't just be
|
|
114
|
-
// a log message, because those are stripped in the compiled build.
|
|
115
104
|
manifestPreprocessor: (element) => {
|
|
116
|
-
return
|
|
105
|
+
return shaka.util.ConfigUtils.referenceParametersAndReturn(
|
|
106
|
+
[element],
|
|
107
|
+
element);
|
|
117
108
|
},
|
|
118
109
|
},
|
|
119
110
|
hls: {
|
|
@@ -130,7 +121,9 @@ shaka.util.PlayerConfiguration = class {
|
|
|
130
121
|
// log message, because those are stripped in the compiled build.
|
|
131
122
|
failureCallback: (error) => {
|
|
132
123
|
shaka.log.error('Unhandled streaming error', error);
|
|
133
|
-
return
|
|
124
|
+
return shaka.util.ConfigUtils.referenceParametersAndReturn(
|
|
125
|
+
[error],
|
|
126
|
+
undefined);
|
|
134
127
|
},
|
|
135
128
|
// When low latency streaming is enabled, rebufferingGoal will default to
|
|
136
129
|
// 0.01 if not specified.
|
|
@@ -206,7 +199,9 @@ shaka.util.PlayerConfiguration = class {
|
|
|
206
199
|
// to the function as it would be a no-op. The operation can't just be a
|
|
207
200
|
// log message, because those are stripped in the compiled build.
|
|
208
201
|
progressCallback: (content, progress) => {
|
|
209
|
-
return
|
|
202
|
+
return shaka.util.ConfigUtils.referenceParametersAndReturn(
|
|
203
|
+
[content, progress],
|
|
204
|
+
undefined);
|
|
210
205
|
},
|
|
211
206
|
|
|
212
207
|
// By default we use persistent licenses as forces errors to surface if
|
package/lib/util/stream_utils.js
CHANGED
|
@@ -283,12 +283,14 @@ shaka.util.StreamUtils = class {
|
|
|
283
283
|
// both be considered the same codec: avc1.42c01e, avc1.4d401f
|
|
284
284
|
let baseVideoCodec = '';
|
|
285
285
|
if (variant.video) {
|
|
286
|
-
baseVideoCodec =
|
|
286
|
+
baseVideoCodec =
|
|
287
|
+
shaka.util.MimeUtils.getNormalizedCodec(variant.video.codecs);
|
|
287
288
|
}
|
|
288
289
|
|
|
289
290
|
let baseAudioCodec = '';
|
|
290
291
|
if (variant.audio) {
|
|
291
|
-
baseAudioCodec =
|
|
292
|
+
baseAudioCodec =
|
|
293
|
+
shaka.util.MimeUtils.getNormalizedCodec(variant.audio.codecs);
|
|
292
294
|
}
|
|
293
295
|
|
|
294
296
|
return baseVideoCodec + '-' + baseAudioCodec;
|
|
@@ -979,6 +981,7 @@ shaka.util.StreamUtils = class {
|
|
|
979
981
|
track.channelsCount = audio.channelsCount;
|
|
980
982
|
track.audioSamplingRate = audio.audioSamplingRate;
|
|
981
983
|
track.audioBandwidth = audio.bandwidth || null;
|
|
984
|
+
track.spatialAudio = audio.spatialAudio;
|
|
982
985
|
track.label = audio.label;
|
|
983
986
|
track.audioRoles = audio.roles;
|
|
984
987
|
}
|
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": "3.2.
|
|
4
|
+
"version": "3.2.9",
|
|
5
5
|
"homepage": "https://github.com/shaka-project/shaka-player",
|
|
6
6
|
"author": "Google",
|
|
7
7
|
"maintainers": [
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"less": "https://gitpkg.now.sh/joeyparrish/less.js/packages/less?28c63a43",
|
|
51
51
|
"less-plugin-clean-css": "github:austingardner/less-plugin-clean-css#4e9e77bf",
|
|
52
52
|
"material-design-lite": "^1.3.0",
|
|
53
|
-
"mux.js": "^
|
|
53
|
+
"mux.js": "^6.1.0",
|
|
54
54
|
"open-sans-fonts": "^1.6.2",
|
|
55
55
|
"postcss-less": "^6.0.0",
|
|
56
56
|
"pwacompat": "^2.0.17",
|
|
@@ -96,6 +96,9 @@
|
|
|
96
96
|
"prepublishOnly": "python build/checkversion.py && python build/all.py --force"
|
|
97
97
|
},
|
|
98
98
|
"dependencies": {
|
|
99
|
-
"eme-encryption-scheme-polyfill": "^2.0.
|
|
99
|
+
"eme-encryption-scheme-polyfill": "^2.0.5"
|
|
100
|
+
},
|
|
101
|
+
"engines": {
|
|
102
|
+
"node": ">=14"
|
|
100
103
|
}
|
|
101
104
|
}
|
|
@@ -445,30 +445,6 @@ describe('DashParser Manifest', () => {
|
|
|
445
445
|
expect(stream.closedCaptions).toEqual(expectedClosedCaptions);
|
|
446
446
|
});
|
|
447
447
|
|
|
448
|
-
it('Detects E-AC3 JOC content by SupplementalProperty', async () => {
|
|
449
|
-
const idUri = 'tag:dolby.com,2018:dash:EC3_ExtensionType:2018';
|
|
450
|
-
const source = [
|
|
451
|
-
'<MPD>',
|
|
452
|
-
' <Period duration="PT30M">',
|
|
453
|
-
' <AdaptationSet mimeType="audio/mp4" lang="\u2603">',
|
|
454
|
-
' <Representation bandwidth="500">',
|
|
455
|
-
' <SupplementalProperty schemeIdUri="' + idUri + '" value="JOC"/>',
|
|
456
|
-
' <BaseURL>http://example.com</BaseURL>',
|
|
457
|
-
' <SegmentTemplate media="2.mp4" duration="1" />',
|
|
458
|
-
' </Representation>',
|
|
459
|
-
' </AdaptationSet>',
|
|
460
|
-
' </Period>',
|
|
461
|
-
'</MPD>',
|
|
462
|
-
].join('\n');
|
|
463
|
-
|
|
464
|
-
fakeNetEngine.setResponseText('dummy://foo', source);
|
|
465
|
-
|
|
466
|
-
/** @type {shaka.extern.Manifest} */
|
|
467
|
-
const manifest = await parser.start('dummy://foo', playerInterface);
|
|
468
|
-
const stream = manifest.variants[0].audio;
|
|
469
|
-
expect(stream.mimeType).toBe('audio/eac3-joc');
|
|
470
|
-
});
|
|
471
|
-
|
|
472
448
|
it('Detects spatial audio', async () => {
|
|
473
449
|
const idUri = 'tag:dolby.com,2018:dash:EC3_ExtensionType:2018';
|
|
474
450
|
const source = [
|
|
@@ -630,11 +630,13 @@ describe('HlsParser live', () => {
|
|
|
630
630
|
expect(ref.startTime).not.toBeLessThan(rolloverOffset);
|
|
631
631
|
});
|
|
632
632
|
|
|
633
|
+
// Test for https://github.com/shaka-project/shaka-player/issues/4223
|
|
633
634
|
it('parses streams with partial and preload hinted segments', async () => {
|
|
634
635
|
playerInterface.isLowLatencyMode = () => true;
|
|
635
636
|
const mediaWithPartialSegments = [
|
|
636
637
|
'#EXTM3U\n',
|
|
637
638
|
'#EXT-X-TARGETDURATION:5\n',
|
|
639
|
+
'#EXT-X-PART-INF:PART-TARGET=1.5\n',
|
|
638
640
|
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
639
641
|
'#EXT-X-MEDIA-SEQUENCE:0\n',
|
|
640
642
|
// ref includes partialRef, partialRef2
|
|
@@ -668,6 +670,11 @@ describe('HlsParser live', () => {
|
|
|
668
670
|
segmentDataStartTime + 4, /* baseUri= */ '', /* startByte= */ 200,
|
|
669
671
|
/* endByte= */ 429);
|
|
670
672
|
|
|
673
|
+
const ref = ManifestParser.makeReference(
|
|
674
|
+
'test:/main.mp4', segmentDataStartTime, segmentDataStartTime + 4,
|
|
675
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 429,
|
|
676
|
+
/* timestampOffset= */ 0, [partialRef, partialRef2]);
|
|
677
|
+
|
|
671
678
|
const partialRef3 = ManifestParser.makeReference(
|
|
672
679
|
'test:/partial.mp4', segmentDataStartTime + 4,
|
|
673
680
|
segmentDataStartTime + 6,
|
|
@@ -677,17 +684,12 @@ describe('HlsParser live', () => {
|
|
|
677
684
|
// so its startTime and endTime are the same.
|
|
678
685
|
const preloadRef = ManifestParser.makeReference(
|
|
679
686
|
'test:/partial.mp4', segmentDataStartTime + 6,
|
|
680
|
-
segmentDataStartTime +
|
|
687
|
+
segmentDataStartTime + 7.5,
|
|
681
688
|
/* baseUri= */ '', /* startByte= */ 210, /* endByte= */ null);
|
|
682
689
|
|
|
683
|
-
const ref = ManifestParser.makeReference(
|
|
684
|
-
'test:/main.mp4', segmentDataStartTime, segmentDataStartTime + 4,
|
|
685
|
-
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 429,
|
|
686
|
-
/* timestampOffset= */ 0, [partialRef, partialRef2]);
|
|
687
|
-
|
|
688
690
|
// ref2 is not fully published yet, so it doesn't have a segment uri.
|
|
689
691
|
const ref2 = ManifestParser.makeReference(
|
|
690
|
-
'', segmentDataStartTime + 4, segmentDataStartTime +
|
|
692
|
+
'', segmentDataStartTime + 4, segmentDataStartTime + 7.5,
|
|
691
693
|
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
|
|
692
694
|
/* timestampOffset= */ 0, [partialRef3, preloadRef]);
|
|
693
695
|
|
|
@@ -697,6 +699,83 @@ describe('HlsParser live', () => {
|
|
|
697
699
|
ManifestParser.verifySegmentIndex(video, [ref, ref2]);
|
|
698
700
|
});
|
|
699
701
|
|
|
702
|
+
// Test for https://github.com/shaka-project/shaka-player/issues/4223
|
|
703
|
+
it('ignores preload hinted segments without target duration', async () => {
|
|
704
|
+
playerInterface.isLowLatencyMode = () => true;
|
|
705
|
+
|
|
706
|
+
// Missing PART-TARGET, so preload hints are skipped.
|
|
707
|
+
const mediaWithPartialSegments = [
|
|
708
|
+
'#EXTM3U\n',
|
|
709
|
+
'#EXT-X-TARGETDURATION:5\n',
|
|
710
|
+
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
711
|
+
'#EXT-X-MEDIA-SEQUENCE:0\n',
|
|
712
|
+
'#EXTINF:4,\n',
|
|
713
|
+
// ref1
|
|
714
|
+
'main.mp4\n',
|
|
715
|
+
// ref2 includes partialRef, but not preloadRef
|
|
716
|
+
// partialRef
|
|
717
|
+
'#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=210@0\n',
|
|
718
|
+
// preloadRef
|
|
719
|
+
'#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4",BYTERANGE-START=210\n',
|
|
720
|
+
].join('');
|
|
721
|
+
|
|
722
|
+
fakeNetEngine
|
|
723
|
+
.setResponseText('test:/master', master)
|
|
724
|
+
.setResponseText('test:/video', mediaWithPartialSegments)
|
|
725
|
+
.setResponseValue('test:/init.mp4', initSegmentData)
|
|
726
|
+
.setResponseValue('test:/main.mp4', segmentData)
|
|
727
|
+
.setResponseValue('test:/partial.mp4', segmentData)
|
|
728
|
+
.setResponseValue('test:/partial2.mp4', segmentData);
|
|
729
|
+
|
|
730
|
+
const ref1 = ManifestParser.makeReference(
|
|
731
|
+
'test:/main.mp4', segmentDataStartTime, segmentDataStartTime + 4,
|
|
732
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
|
|
733
|
+
/* timestampOffset= */ 0, []);
|
|
734
|
+
|
|
735
|
+
const partialRef = ManifestParser.makeReference(
|
|
736
|
+
'test:/partial.mp4', segmentDataStartTime + 4,
|
|
737
|
+
segmentDataStartTime + 6,
|
|
738
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 209);
|
|
739
|
+
|
|
740
|
+
// ref2 is not fully published yet, so it doesn't have a segment uri.
|
|
741
|
+
const ref2 = ManifestParser.makeReference(
|
|
742
|
+
'', segmentDataStartTime + 4, segmentDataStartTime + 6,
|
|
743
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 209,
|
|
744
|
+
/* timestampOffset= */ 0, [partialRef]);
|
|
745
|
+
|
|
746
|
+
const manifest = await parser.start('test:/master', playerInterface);
|
|
747
|
+
const video = manifest.variants[0].video;
|
|
748
|
+
await video.createSegmentIndex();
|
|
749
|
+
ManifestParser.verifySegmentIndex(video, [ref1, ref2]);
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
// Test for https://github.com/shaka-project/shaka-player/issues/4185
|
|
753
|
+
it('does not fail on preload hints with LL mode off', async () => {
|
|
754
|
+
// LL mode must be off for this test!
|
|
755
|
+
playerInterface.isLowLatencyMode = () => false;
|
|
756
|
+
|
|
757
|
+
const mediaWithPartialSegments = [
|
|
758
|
+
'#EXTM3U\n',
|
|
759
|
+
'#EXT-X-TARGETDURATION:5\n',
|
|
760
|
+
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
761
|
+
'#EXT-X-PART-INF:PART-TARGET=1.5\n',
|
|
762
|
+
'#EXTINF:4,\n',
|
|
763
|
+
'main.mp4\n',
|
|
764
|
+
'#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=210@0\n',
|
|
765
|
+
'#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4",BYTERANGE-START=210\n',
|
|
766
|
+
].join('');
|
|
767
|
+
|
|
768
|
+
fakeNetEngine
|
|
769
|
+
.setResponseText('test:/master', master)
|
|
770
|
+
.setResponseText('test:/video', mediaWithPartialSegments)
|
|
771
|
+
.setResponseValue('test:/init.mp4', initSegmentData)
|
|
772
|
+
.setResponseValue('test:/main.mp4', segmentData)
|
|
773
|
+
.setResponseValue('test:/partial.mp4', segmentData);
|
|
774
|
+
|
|
775
|
+
// If this throws, the test fails. Otherwise, it passes.
|
|
776
|
+
await parser.start('test:/master', playerInterface);
|
|
777
|
+
});
|
|
778
|
+
|
|
700
779
|
describe('update', () => {
|
|
701
780
|
it('adds new segments when they appear', async () => {
|
|
702
781
|
const ref1 = ManifestParser.makeReference('test:/main.mp4', 2, 4);
|
|
@@ -238,6 +238,25 @@ describe('ManifestTextParser', () => {
|
|
|
238
238
|
'#EXTM3U\n' +
|
|
239
239
|
'#EXT-X-MEDIA:CODECS="avc1.64002a,mp4a.40.2",AUDIO="a1,a2"',
|
|
240
240
|
|
|
241
|
+
// manifest URI:
|
|
242
|
+
'https://test/manifest.m3u8');
|
|
243
|
+
|
|
244
|
+
verifyPlaylist(
|
|
245
|
+
{
|
|
246
|
+
type: shaka.hls.PlaylistType.MASTER,
|
|
247
|
+
tags: [
|
|
248
|
+
new shaka.hls.Tag(/* id= */ 3, 'EXT-X-MEDIA',
|
|
249
|
+
[
|
|
250
|
+
new shaka.hls.Attribute('CODECS',
|
|
251
|
+
'av01.0.08M.08,mp4a.40.2'),
|
|
252
|
+
]),
|
|
253
|
+
],
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
// playlist text:
|
|
257
|
+
'#EXTM3U\n' +
|
|
258
|
+
'#EXT-X-MEDIA:CODECS="av01.0.08M.08,mp4a.40.2"',
|
|
259
|
+
|
|
241
260
|
// manifest URI:
|
|
242
261
|
'https://test/manifest.m3u8');
|
|
243
262
|
});
|
|
@@ -49,10 +49,10 @@ describe('MediaSourceEngine', () => {
|
|
|
49
49
|
const buffer2 = /** @type {!ArrayBuffer} */ (/** @type {?} */ (2));
|
|
50
50
|
const buffer3 = /** @type {!ArrayBuffer} */ (/** @type {?} */ (3));
|
|
51
51
|
|
|
52
|
-
const fakeVideoStream = {mimeType: 'video/foo'};
|
|
53
|
-
const fakeAudioStream = {mimeType: 'audio/foo'};
|
|
54
|
-
const fakeTextStream = {mimeType: 'text/foo'};
|
|
55
|
-
const fakeTransportStream = {mimeType: 'tsMimetype'};
|
|
52
|
+
const fakeVideoStream = {mimeType: 'video/foo', drmInfos: []};
|
|
53
|
+
const fakeAudioStream = {mimeType: 'audio/foo', drmInfos: []};
|
|
54
|
+
const fakeTextStream = {mimeType: 'text/foo', drmInfos: []};
|
|
55
|
+
const fakeTransportStream = {mimeType: 'tsMimetype', drmInfos: []};
|
|
56
56
|
|
|
57
57
|
let audioSourceBuffer;
|
|
58
58
|
let videoSourceBuffer;
|
|
@@ -621,6 +621,7 @@ describe('StreamingEngine', () => {
|
|
|
621
621
|
width: 600,
|
|
622
622
|
height: 400,
|
|
623
623
|
type: shaka.util.ManifestParserUtils.ContentType.VIDEO,
|
|
624
|
+
drmInfos: [],
|
|
624
625
|
},
|
|
625
626
|
audio: {
|
|
626
627
|
id: 3,
|
|
@@ -630,6 +631,7 @@ describe('StreamingEngine', () => {
|
|
|
630
631
|
codecs: 'mp4a.40.2',
|
|
631
632
|
bandwidth: 192000,
|
|
632
633
|
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
|
|
634
|
+
drmInfos: [],
|
|
633
635
|
},
|
|
634
636
|
}],
|
|
635
637
|
};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
filterDescribe('IndexeddbStorageCell',
|
|
7
|
+
filterDescribe('IndexeddbStorageCell', offlineSupported, () => {
|
|
8
8
|
const IndexedDBUtils = shaka.test.IndexedDBUtils;
|
|
9
9
|
const OfflineUtils = shaka.test.OfflineUtils;
|
|
10
10
|
const Util = shaka.test.Util;
|
|
@@ -91,7 +91,7 @@ const compatibilityTestsMetadata = [
|
|
|
91
91
|
},
|
|
92
92
|
];
|
|
93
93
|
|
|
94
|
-
filterDescribe('Storage Compatibility',
|
|
94
|
+
filterDescribe('Storage Compatibility', offlineSupported, () => {
|
|
95
95
|
for (const metadata of compatibilityTestsMetadata) {
|
|
96
96
|
describe(metadata.name, () => {
|
|
97
97
|
makeTests(metadata);
|
package/test/player_external.js
CHANGED
|
@@ -120,7 +120,13 @@ describe('Player', () => {
|
|
|
120
120
|
const networkingEngine = player.getNetworkingEngine();
|
|
121
121
|
asset.applyFilters(networkingEngine);
|
|
122
122
|
|
|
123
|
-
|
|
123
|
+
// Rather than awaiting the load() method, catch any load() errors and
|
|
124
|
+
// wait on the 'canplay' event. This has the advantage that we will
|
|
125
|
+
// get better logging of the media state on a timeout, since that
|
|
126
|
+
// capabilitiy is built into the waiter for media element events.
|
|
127
|
+
player.load(asset.manifestUri).catch(fail);
|
|
128
|
+
await waiter.timeoutAfter(60).waitForEvent(video, 'canplay');
|
|
129
|
+
|
|
124
130
|
if (asset.features) {
|
|
125
131
|
const isLive = asset.features.includes(Feature.LIVE);
|
|
126
132
|
expect(player.isLive()).toBe(isLive);
|
|
@@ -953,16 +953,16 @@ describe('Player', () => {
|
|
|
953
953
|
});
|
|
954
954
|
}); // describe('unloading')
|
|
955
955
|
|
|
956
|
-
describe('
|
|
957
|
-
it('
|
|
956
|
+
describe('addChaptersTrack', () => {
|
|
957
|
+
it('adds external chapters in vtt format', async () => {
|
|
958
958
|
await player.load('test:sintel_no_text_compiled');
|
|
959
959
|
const locationUri = new goog.Uri(location.href);
|
|
960
960
|
const partialUri1 = new goog.Uri('/base/test/test/assets/chapters.vtt');
|
|
961
961
|
const absoluteUri1 = locationUri.resolve(partialUri1);
|
|
962
962
|
await player.addChaptersTrack(absoluteUri1.toString(), 'en');
|
|
963
963
|
|
|
964
|
-
|
|
965
|
-
|
|
964
|
+
// Data should be available as soon as addChaptersTrack resolves.
|
|
965
|
+
// See https://github.com/shaka-project/shaka-player/issues/4186
|
|
966
966
|
const chapters = player.getChapters('en');
|
|
967
967
|
expect(chapters.length).toBe(3);
|
|
968
968
|
const chapter1 = chapters[0];
|
|
@@ -982,8 +982,6 @@ describe('Player', () => {
|
|
|
982
982
|
const absoluteUri2 = locationUri.resolve(partialUri2);
|
|
983
983
|
await player.addChaptersTrack(absoluteUri2.toString(), 'en');
|
|
984
984
|
|
|
985
|
-
await shaka.test.Util.delay(1.5);
|
|
986
|
-
|
|
987
985
|
const chaptersUpdated = player.getChapters('en');
|
|
988
986
|
expect(chaptersUpdated.length).toBe(6);
|
|
989
987
|
const chapterUpdated1 = chaptersUpdated[0];
|
|
@@ -1012,15 +1010,13 @@ describe('Player', () => {
|
|
|
1012
1010
|
expect(chapterUpdated6.endTime).toBe(61.349);
|
|
1013
1011
|
});
|
|
1014
1012
|
|
|
1015
|
-
it('
|
|
1013
|
+
it('adds external chapters in srt format', async () => {
|
|
1016
1014
|
await player.load('test:sintel_no_text_compiled');
|
|
1017
1015
|
const locationUri = new goog.Uri(location.href);
|
|
1018
1016
|
const partialUri = new goog.Uri('/base/test/test/assets/chapters.srt');
|
|
1019
1017
|
const absoluteUri = locationUri.resolve(partialUri);
|
|
1020
1018
|
await player.addChaptersTrack(absoluteUri.toString(), 'es');
|
|
1021
1019
|
|
|
1022
|
-
await shaka.test.Util.delay(1.5);
|
|
1023
|
-
|
|
1024
1020
|
const chapters = player.getChapters('es');
|
|
1025
1021
|
expect(chapters.length).toBe(3);
|
|
1026
1022
|
const chapter1 = chapters[0];
|
|
@@ -1036,5 +1032,5 @@ describe('Player', () => {
|
|
|
1036
1032
|
expect(chapter3.startTime).toBe(30);
|
|
1037
1033
|
expect(chapter3.endTime).toBe(61.349);
|
|
1038
1034
|
});
|
|
1039
|
-
}); // describe('
|
|
1035
|
+
}); // describe('addChaptersTrack')
|
|
1040
1036
|
});
|
|
@@ -319,90 +319,88 @@ describe('Player Src Equals', () => {
|
|
|
319
319
|
expect(newTrack).toBeTruthy();
|
|
320
320
|
});
|
|
321
321
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
});
|
|
380
|
-
|
|
381
|
-
it('add external chapters in srt format', async () => {
|
|
382
|
-
await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
|
|
383
|
-
|
|
384
|
-
const locationUri = new goog.Uri(location.href);
|
|
385
|
-
const partialUri = new goog.Uri('/base/test/test/assets/chapters.srt');
|
|
386
|
-
const absoluteUri = locationUri.resolve(partialUri);
|
|
387
|
-
await player.addChaptersTrack(absoluteUri.toString(), 'es');
|
|
388
|
-
|
|
389
|
-
await shaka.test.Util.delay(1.5);
|
|
322
|
+
describe('addChaptersTrack', () => {
|
|
323
|
+
it('adds external chapters in vtt format', async () => {
|
|
324
|
+
await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
|
|
325
|
+
|
|
326
|
+
const locationUri = new goog.Uri(location.href);
|
|
327
|
+
const partialUri1 = new goog.Uri('/base/test/test/assets/chapters.vtt');
|
|
328
|
+
const absoluteUri1 = locationUri.resolve(partialUri1);
|
|
329
|
+
await player.addChaptersTrack(absoluteUri1.toString(), 'en');
|
|
330
|
+
|
|
331
|
+
// Data should be available as soon as addChaptersTrack resolves.
|
|
332
|
+
// See https://github.com/shaka-project/shaka-player/issues/4186
|
|
333
|
+
const chapters = player.getChapters('en');
|
|
334
|
+
expect(chapters.length).toBe(3);
|
|
335
|
+
const chapter1 = chapters[0];
|
|
336
|
+
expect(chapter1.title).toBe('Chapter 1');
|
|
337
|
+
expect(chapter1.startTime).toBe(0);
|
|
338
|
+
expect(chapter1.endTime).toBe(5);
|
|
339
|
+
const chapter2 = chapters[1];
|
|
340
|
+
expect(chapter2.title).toBe('Chapter 2');
|
|
341
|
+
expect(chapter2.startTime).toBe(5);
|
|
342
|
+
expect(chapter2.endTime).toBe(10);
|
|
343
|
+
const chapter3 = chapters[2];
|
|
344
|
+
expect(chapter3.title).toBe('Chapter 3');
|
|
345
|
+
expect(chapter3.startTime).toBe(10);
|
|
346
|
+
expect(chapter3.endTime).toBe(20);
|
|
347
|
+
|
|
348
|
+
const partialUri2 = new goog.Uri('/base/test/test/assets/chapters2.vtt');
|
|
349
|
+
const absoluteUri2 = locationUri.resolve(partialUri2);
|
|
350
|
+
await player.addChaptersTrack(absoluteUri2.toString(), 'en');
|
|
351
|
+
|
|
352
|
+
const chaptersUpdated = player.getChapters('en');
|
|
353
|
+
expect(chaptersUpdated.length).toBe(6);
|
|
354
|
+
const chapterUpdated1 = chaptersUpdated[0];
|
|
355
|
+
expect(chapterUpdated1.title).toBe('Chapter 1');
|
|
356
|
+
expect(chapterUpdated1.startTime).toBe(0);
|
|
357
|
+
expect(chapterUpdated1.endTime).toBe(5);
|
|
358
|
+
const chapterUpdated2 = chaptersUpdated[1];
|
|
359
|
+
expect(chapterUpdated2.title).toBe('Chapter 2');
|
|
360
|
+
expect(chapterUpdated2.startTime).toBe(5);
|
|
361
|
+
expect(chapterUpdated2.endTime).toBe(10);
|
|
362
|
+
const chapterUpdated3 = chaptersUpdated[2];
|
|
363
|
+
expect(chapterUpdated3.title).toBe('Chapter 3');
|
|
364
|
+
expect(chapterUpdated3.startTime).toBe(10);
|
|
365
|
+
expect(chapterUpdated3.endTime).toBe(20);
|
|
366
|
+
const chapterUpdated4 = chaptersUpdated[3];
|
|
367
|
+
expect(chapterUpdated4.title).toBe('Chapter 4');
|
|
368
|
+
expect(chapterUpdated4.startTime).toBe(20);
|
|
369
|
+
expect(chapterUpdated4.endTime).toBe(30);
|
|
370
|
+
const chapterUpdated5 = chaptersUpdated[4];
|
|
371
|
+
expect(chapterUpdated5.title).toBe('Chapter 5');
|
|
372
|
+
expect(chapterUpdated5.startTime).toBe(30);
|
|
373
|
+
expect(chapterUpdated5.endTime).toBe(40);
|
|
374
|
+
const chapterUpdated6 = chaptersUpdated[5];
|
|
375
|
+
expect(chapterUpdated6.title).toBe('Chapter 6');
|
|
376
|
+
expect(chapterUpdated6.startTime).toBe(40);
|
|
377
|
+
expect(chapterUpdated6.endTime).toBe(61.349);
|
|
378
|
+
});
|
|
390
379
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
380
|
+
it('add external chapters in srt format', async () => {
|
|
381
|
+
await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
|
|
382
|
+
|
|
383
|
+
const locationUri = new goog.Uri(location.href);
|
|
384
|
+
const partialUri = new goog.Uri('/base/test/test/assets/chapters.srt');
|
|
385
|
+
const absoluteUri = locationUri.resolve(partialUri);
|
|
386
|
+
await player.addChaptersTrack(absoluteUri.toString(), 'es');
|
|
387
|
+
|
|
388
|
+
const chapters = player.getChapters('es');
|
|
389
|
+
expect(chapters.length).toBe(3);
|
|
390
|
+
const chapter1 = chapters[0];
|
|
391
|
+
expect(chapter1.title).toBe('Chapter 1');
|
|
392
|
+
expect(chapter1.startTime).toBe(0);
|
|
393
|
+
expect(chapter1.endTime).toBe(5);
|
|
394
|
+
const chapter2 = chapters[1];
|
|
395
|
+
expect(chapter2.title).toBe('Chapter 2');
|
|
396
|
+
expect(chapter2.startTime).toBe(5);
|
|
397
|
+
expect(chapter2.endTime).toBe(30);
|
|
398
|
+
const chapter3 = chapters[2];
|
|
399
|
+
expect(chapter3.title).toBe('Chapter 3');
|
|
400
|
+
expect(chapter3.startTime).toBe(30);
|
|
401
|
+
expect(chapter3.endTime).toBe(61.349);
|
|
402
|
+
});
|
|
403
|
+
}); // describe('addChaptersTrack')
|
|
406
404
|
|
|
407
405
|
// Since we are not in-charge of streaming, calling |retryStreaming| should
|
|
408
406
|
// have no effect.
|