shaka-player 3.3.3 → 3.3.6
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 +6 -3
- package/.github/workflows/selenium-lab-tests.yaml +0 -1
- package/CHANGELOG.md +38 -0
- package/README.md +4 -4
- package/build/README.md +2 -2
- package/build/test.py +7 -1
- package/build/types/core +0 -1
- package/demo/demo.less +0 -1
- package/dist/controls.css +3 -3
- package/dist/controls.css.map +1 -1
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +2 -3
- package/dist/locales.js +31 -31
- package/dist/shaka-player.compiled.d.ts +1 -0
- package/dist/shaka-player.compiled.debug.d.ts +1 -0
- package/dist/shaka-player.compiled.debug.externs.js +1 -0
- package/dist/shaka-player.compiled.debug.js +152 -150
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +1 -0
- package/dist/shaka-player.compiled.js +844 -842
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +1 -0
- package/dist/shaka-player.ui.debug.d.ts +1 -0
- package/dist/shaka-player.ui.debug.externs.js +1 -0
- package/dist/shaka-player.ui.debug.js +224 -222
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +1 -0
- package/dist/shaka-player.ui.js +952 -950
- 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 +37 -14
- 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/offline/storage.js +92 -91
- 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 +4 -2
- package/package.json +2 -2
- 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/ad_controls.less +2 -2
- package/ui/less/buttons.less +1 -1
- package/ui/less/containers.less +5 -5
- package/ui/less/general.less +1 -1
- package/ui/less/range_elements.less +3 -2
- package/ui/less/tooltip.less +3 -3
- package/ui/seek_bar.js +2 -1
- package/.github/pull_request_template.md +0 -10
- package/docs/tutorials/gsoc-ideas-list.md +0 -3
- package/lib/util/mutex.js +0 -52
package/lib/util/periods.js
CHANGED
|
@@ -573,8 +573,8 @@ shaka.util.PeriodCombiner = class {
|
|
|
573
573
|
// TODO(#1528): Consider changing this when we support codec switching.
|
|
574
574
|
const hasCodec = outputStreams.some((s) => {
|
|
575
575
|
return s.mimeType == stream.mimeType &&
|
|
576
|
-
shaka.util.MimeUtils.
|
|
577
|
-
shaka.util.MimeUtils.
|
|
576
|
+
shaka.util.MimeUtils.getNormalizedCodec(s.codecs) ==
|
|
577
|
+
shaka.util.MimeUtils.getNormalizedCodec(stream.codecs);
|
|
578
578
|
});
|
|
579
579
|
if (!hasCodec) {
|
|
580
580
|
continue;
|
|
@@ -1050,10 +1050,11 @@ shaka.util.PeriodCombiner = class {
|
|
|
1050
1050
|
* @private
|
|
1051
1051
|
*/
|
|
1052
1052
|
static areAVStreamsCompatible_(outputStream, candidate) {
|
|
1053
|
-
const
|
|
1053
|
+
const getCodec = (codecs) =>
|
|
1054
|
+
shaka.util.MimeUtils.getNormalizedCodec(codecs);
|
|
1054
1055
|
// Check MIME type and codecs, which should always be the same.
|
|
1055
1056
|
if (candidate.mimeType != outputStream.mimeType ||
|
|
1056
|
-
|
|
1057
|
+
getCodec(candidate.codecs) != getCodec(outputStream.codecs)) {
|
|
1057
1058
|
return false;
|
|
1058
1059
|
}
|
|
1059
1060
|
|
|
@@ -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: {
|
|
@@ -132,7 +123,9 @@ shaka.util.PlayerConfiguration = class {
|
|
|
132
123
|
// log message, because those are stripped in the compiled build.
|
|
133
124
|
failureCallback: (error) => {
|
|
134
125
|
shaka.log.error('Unhandled streaming error', error);
|
|
135
|
-
return
|
|
126
|
+
return shaka.util.ConfigUtils.referenceParametersAndReturn(
|
|
127
|
+
[error],
|
|
128
|
+
undefined);
|
|
136
129
|
},
|
|
137
130
|
// When low latency streaming is enabled, rebufferingGoal will default to
|
|
138
131
|
// 0.01 if not specified.
|
|
@@ -210,7 +203,9 @@ shaka.util.PlayerConfiguration = class {
|
|
|
210
203
|
// to the function as it would be a no-op. The operation can't just be a
|
|
211
204
|
// log message, because those are stripped in the compiled build.
|
|
212
205
|
progressCallback: (content, progress) => {
|
|
213
|
-
return
|
|
206
|
+
return shaka.util.ConfigUtils.referenceParametersAndReturn(
|
|
207
|
+
[content, progress],
|
|
208
|
+
undefined);
|
|
214
209
|
},
|
|
215
210
|
|
|
216
211
|
// 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;
|
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.3.
|
|
4
|
+
"version": "3.3.6",
|
|
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",
|
|
@@ -447,30 +447,6 @@ describe('DashParser Manifest', () => {
|
|
|
447
447
|
expect(stream.closedCaptions).toEqual(expectedClosedCaptions);
|
|
448
448
|
});
|
|
449
449
|
|
|
450
|
-
it('Detects E-AC3 JOC content by SupplementalProperty', async () => {
|
|
451
|
-
const idUri = 'tag:dolby.com,2018:dash:EC3_ExtensionType:2018';
|
|
452
|
-
const source = [
|
|
453
|
-
'<MPD>',
|
|
454
|
-
' <Period duration="PT30M">',
|
|
455
|
-
' <AdaptationSet mimeType="audio/mp4" lang="\u2603">',
|
|
456
|
-
' <Representation bandwidth="500">',
|
|
457
|
-
' <SupplementalProperty schemeIdUri="' + idUri + '" value="JOC"/>',
|
|
458
|
-
' <BaseURL>http://example.com</BaseURL>',
|
|
459
|
-
' <SegmentTemplate media="2.mp4" duration="1" />',
|
|
460
|
-
' </Representation>',
|
|
461
|
-
' </AdaptationSet>',
|
|
462
|
-
' </Period>',
|
|
463
|
-
'</MPD>',
|
|
464
|
-
].join('\n');
|
|
465
|
-
|
|
466
|
-
fakeNetEngine.setResponseText('dummy://foo', source);
|
|
467
|
-
|
|
468
|
-
/** @type {shaka.extern.Manifest} */
|
|
469
|
-
const manifest = await parser.start('dummy://foo', playerInterface);
|
|
470
|
-
const stream = manifest.variants[0].audio;
|
|
471
|
-
expect(stream.mimeType).toBe('audio/eac3-joc');
|
|
472
|
-
});
|
|
473
|
-
|
|
474
450
|
it('Detects spatial audio', async () => {
|
|
475
451
|
const idUri = 'tag:dolby.com,2018:dash:EC3_ExtensionType:2018';
|
|
476
452
|
const source = [
|
|
@@ -632,11 +632,13 @@ describe('HlsParser live', () => {
|
|
|
632
632
|
expect(ref.startTime).not.toBeLessThan(rolloverOffset);
|
|
633
633
|
});
|
|
634
634
|
|
|
635
|
+
// Test for https://github.com/shaka-project/shaka-player/issues/4223
|
|
635
636
|
it('parses streams with partial and preload hinted segments', async () => {
|
|
636
637
|
playerInterface.isLowLatencyMode = () => true;
|
|
637
638
|
const mediaWithPartialSegments = [
|
|
638
639
|
'#EXTM3U\n',
|
|
639
640
|
'#EXT-X-TARGETDURATION:5\n',
|
|
641
|
+
'#EXT-X-PART-INF:PART-TARGET=1.5\n',
|
|
640
642
|
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
641
643
|
'#EXT-X-MEDIA-SEQUENCE:0\n',
|
|
642
644
|
// ref includes partialRef, partialRef2
|
|
@@ -670,6 +672,11 @@ describe('HlsParser live', () => {
|
|
|
670
672
|
segmentDataStartTime + 4, /* baseUri= */ '', /* startByte= */ 200,
|
|
671
673
|
/* endByte= */ 429);
|
|
672
674
|
|
|
675
|
+
const ref = ManifestParser.makeReference(
|
|
676
|
+
'test:/main.mp4', segmentDataStartTime, segmentDataStartTime + 4,
|
|
677
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 429,
|
|
678
|
+
/* timestampOffset= */ 0, [partialRef, partialRef2]);
|
|
679
|
+
|
|
673
680
|
const partialRef3 = ManifestParser.makeReference(
|
|
674
681
|
'test:/partial.mp4', segmentDataStartTime + 4,
|
|
675
682
|
segmentDataStartTime + 6,
|
|
@@ -679,17 +686,12 @@ describe('HlsParser live', () => {
|
|
|
679
686
|
// so its startTime and endTime are the same.
|
|
680
687
|
const preloadRef = ManifestParser.makeReference(
|
|
681
688
|
'test:/partial.mp4', segmentDataStartTime + 6,
|
|
682
|
-
segmentDataStartTime +
|
|
689
|
+
segmentDataStartTime + 7.5,
|
|
683
690
|
/* baseUri= */ '', /* startByte= */ 210, /* endByte= */ null);
|
|
684
691
|
|
|
685
|
-
const ref = ManifestParser.makeReference(
|
|
686
|
-
'test:/main.mp4', segmentDataStartTime, segmentDataStartTime + 4,
|
|
687
|
-
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 429,
|
|
688
|
-
/* timestampOffset= */ 0, [partialRef, partialRef2]);
|
|
689
|
-
|
|
690
692
|
// ref2 is not fully published yet, so it doesn't have a segment uri.
|
|
691
693
|
const ref2 = ManifestParser.makeReference(
|
|
692
|
-
'', segmentDataStartTime + 4, segmentDataStartTime +
|
|
694
|
+
'', segmentDataStartTime + 4, segmentDataStartTime + 7.5,
|
|
693
695
|
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
|
|
694
696
|
/* timestampOffset= */ 0, [partialRef3, preloadRef]);
|
|
695
697
|
|
|
@@ -699,6 +701,83 @@ describe('HlsParser live', () => {
|
|
|
699
701
|
ManifestParser.verifySegmentIndex(video, [ref, ref2]);
|
|
700
702
|
});
|
|
701
703
|
|
|
704
|
+
// Test for https://github.com/shaka-project/shaka-player/issues/4223
|
|
705
|
+
it('ignores preload hinted segments without target duration', async () => {
|
|
706
|
+
playerInterface.isLowLatencyMode = () => true;
|
|
707
|
+
|
|
708
|
+
// Missing PART-TARGET, so preload hints are skipped.
|
|
709
|
+
const mediaWithPartialSegments = [
|
|
710
|
+
'#EXTM3U\n',
|
|
711
|
+
'#EXT-X-TARGETDURATION:5\n',
|
|
712
|
+
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
713
|
+
'#EXT-X-MEDIA-SEQUENCE:0\n',
|
|
714
|
+
'#EXTINF:4,\n',
|
|
715
|
+
// ref1
|
|
716
|
+
'main.mp4\n',
|
|
717
|
+
// ref2 includes partialRef, but not preloadRef
|
|
718
|
+
// partialRef
|
|
719
|
+
'#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=210@0\n',
|
|
720
|
+
// preloadRef
|
|
721
|
+
'#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4",BYTERANGE-START=210\n',
|
|
722
|
+
].join('');
|
|
723
|
+
|
|
724
|
+
fakeNetEngine
|
|
725
|
+
.setResponseText('test:/master', master)
|
|
726
|
+
.setResponseText('test:/video', mediaWithPartialSegments)
|
|
727
|
+
.setResponseValue('test:/init.mp4', initSegmentData)
|
|
728
|
+
.setResponseValue('test:/main.mp4', segmentData)
|
|
729
|
+
.setResponseValue('test:/partial.mp4', segmentData)
|
|
730
|
+
.setResponseValue('test:/partial2.mp4', segmentData);
|
|
731
|
+
|
|
732
|
+
const ref1 = ManifestParser.makeReference(
|
|
733
|
+
'test:/main.mp4', segmentDataStartTime, segmentDataStartTime + 4,
|
|
734
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
|
|
735
|
+
/* timestampOffset= */ 0, []);
|
|
736
|
+
|
|
737
|
+
const partialRef = ManifestParser.makeReference(
|
|
738
|
+
'test:/partial.mp4', segmentDataStartTime + 4,
|
|
739
|
+
segmentDataStartTime + 6,
|
|
740
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 209);
|
|
741
|
+
|
|
742
|
+
// ref2 is not fully published yet, so it doesn't have a segment uri.
|
|
743
|
+
const ref2 = ManifestParser.makeReference(
|
|
744
|
+
'', segmentDataStartTime + 4, segmentDataStartTime + 6,
|
|
745
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 209,
|
|
746
|
+
/* timestampOffset= */ 0, [partialRef]);
|
|
747
|
+
|
|
748
|
+
const manifest = await parser.start('test:/master', playerInterface);
|
|
749
|
+
const video = manifest.variants[0].video;
|
|
750
|
+
await video.createSegmentIndex();
|
|
751
|
+
ManifestParser.verifySegmentIndex(video, [ref1, ref2]);
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
// Test for https://github.com/shaka-project/shaka-player/issues/4185
|
|
755
|
+
it('does not fail on preload hints with LL mode off', async () => {
|
|
756
|
+
// LL mode must be off for this test!
|
|
757
|
+
playerInterface.isLowLatencyMode = () => false;
|
|
758
|
+
|
|
759
|
+
const mediaWithPartialSegments = [
|
|
760
|
+
'#EXTM3U\n',
|
|
761
|
+
'#EXT-X-TARGETDURATION:5\n',
|
|
762
|
+
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
763
|
+
'#EXT-X-PART-INF:PART-TARGET=1.5\n',
|
|
764
|
+
'#EXTINF:4,\n',
|
|
765
|
+
'main.mp4\n',
|
|
766
|
+
'#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=210@0\n',
|
|
767
|
+
'#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4",BYTERANGE-START=210\n',
|
|
768
|
+
].join('');
|
|
769
|
+
|
|
770
|
+
fakeNetEngine
|
|
771
|
+
.setResponseText('test:/master', master)
|
|
772
|
+
.setResponseText('test:/video', mediaWithPartialSegments)
|
|
773
|
+
.setResponseValue('test:/init.mp4', initSegmentData)
|
|
774
|
+
.setResponseValue('test:/main.mp4', segmentData)
|
|
775
|
+
.setResponseValue('test:/partial.mp4', segmentData);
|
|
776
|
+
|
|
777
|
+
// If this throws, the test fails. Otherwise, it passes.
|
|
778
|
+
await parser.start('test:/master', playerInterface);
|
|
779
|
+
});
|
|
780
|
+
|
|
702
781
|
describe('update', () => {
|
|
703
782
|
it('adds new segments when they appear', async () => {
|
|
704
783
|
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;
|
|
@@ -622,6 +622,7 @@ describe('StreamingEngine', () => {
|
|
|
622
622
|
width: 600,
|
|
623
623
|
height: 400,
|
|
624
624
|
type: shaka.util.ManifestParserUtils.ContentType.VIDEO,
|
|
625
|
+
drmInfos: [],
|
|
625
626
|
},
|
|
626
627
|
audio: {
|
|
627
628
|
id: 3,
|
|
@@ -631,6 +632,7 @@ describe('StreamingEngine', () => {
|
|
|
631
632
|
codecs: 'mp4a.40.2',
|
|
632
633
|
bandwidth: 192000,
|
|
633
634
|
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
|
|
635
|
+
drmInfos: [],
|
|
634
636
|
},
|
|
635
637
|
}],
|
|
636
638
|
};
|
|
@@ -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);
|
|
@@ -1053,16 +1053,16 @@ describe('Player', () => {
|
|
|
1053
1053
|
});
|
|
1054
1054
|
}); // describe('unloading')
|
|
1055
1055
|
|
|
1056
|
-
describe('
|
|
1057
|
-
it('
|
|
1056
|
+
describe('addChaptersTrack', () => {
|
|
1057
|
+
it('adds external chapters in vtt format', async () => {
|
|
1058
1058
|
await player.load('test:sintel_no_text_compiled');
|
|
1059
1059
|
const locationUri = new goog.Uri(location.href);
|
|
1060
1060
|
const partialUri1 = new goog.Uri('/base/test/test/assets/chapters.vtt');
|
|
1061
1061
|
const absoluteUri1 = locationUri.resolve(partialUri1);
|
|
1062
1062
|
await player.addChaptersTrack(absoluteUri1.toString(), 'en');
|
|
1063
1063
|
|
|
1064
|
-
|
|
1065
|
-
|
|
1064
|
+
// Data should be available as soon as addChaptersTrack resolves.
|
|
1065
|
+
// See https://github.com/shaka-project/shaka-player/issues/4186
|
|
1066
1066
|
const chapters = player.getChapters('en');
|
|
1067
1067
|
expect(chapters.length).toBe(3);
|
|
1068
1068
|
const chapter1 = chapters[0];
|
|
@@ -1082,8 +1082,6 @@ describe('Player', () => {
|
|
|
1082
1082
|
const absoluteUri2 = locationUri.resolve(partialUri2);
|
|
1083
1083
|
await player.addChaptersTrack(absoluteUri2.toString(), 'en');
|
|
1084
1084
|
|
|
1085
|
-
await shaka.test.Util.delay(1.5);
|
|
1086
|
-
|
|
1087
1085
|
const chaptersUpdated = player.getChapters('en');
|
|
1088
1086
|
expect(chaptersUpdated.length).toBe(6);
|
|
1089
1087
|
const chapterUpdated1 = chaptersUpdated[0];
|
|
@@ -1112,15 +1110,13 @@ describe('Player', () => {
|
|
|
1112
1110
|
expect(chapterUpdated6.endTime).toBe(61.349);
|
|
1113
1111
|
});
|
|
1114
1112
|
|
|
1115
|
-
it('
|
|
1113
|
+
it('adds external chapters in srt format', async () => {
|
|
1116
1114
|
await player.load('test:sintel_no_text_compiled');
|
|
1117
1115
|
const locationUri = new goog.Uri(location.href);
|
|
1118
1116
|
const partialUri = new goog.Uri('/base/test/test/assets/chapters.srt');
|
|
1119
1117
|
const absoluteUri = locationUri.resolve(partialUri);
|
|
1120
1118
|
await player.addChaptersTrack(absoluteUri.toString(), 'es');
|
|
1121
1119
|
|
|
1122
|
-
await shaka.test.Util.delay(1.5);
|
|
1123
|
-
|
|
1124
1120
|
const chapters = player.getChapters('es');
|
|
1125
1121
|
expect(chapters.length).toBe(3);
|
|
1126
1122
|
const chapter1 = chapters[0];
|
|
@@ -1136,5 +1132,5 @@ describe('Player', () => {
|
|
|
1136
1132
|
expect(chapter3.startTime).toBe(30);
|
|
1137
1133
|
expect(chapter3.endTime).toBe(61.349);
|
|
1138
1134
|
});
|
|
1139
|
-
}); // describe('
|
|
1135
|
+
}); // describe('addChaptersTrack')
|
|
1140
1136
|
});
|
|
@@ -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.
|