shaka-player 4.2.8 → 4.2.10
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 +4 -4
- package/.github/workflows/demo-version-index.yaml +6 -0
- package/.github/workflows/selenium-lab-tests.yaml +78 -17
- package/.github/workflows/update-screenshots.yaml +142 -0
- package/AUTHORS +2 -1
- package/CHANGELOG.md +50 -0
- package/CONTRIBUTORS +4 -1
- package/demo/common/asset.js +15 -0
- package/demo/common/assets.js +4 -2
- package/demo/common/message_ids.js +1 -0
- package/demo/custom.js +19 -0
- package/demo/locales/en.json +1 -0
- package/demo/locales/source.json +4 -0
- package/demo/main.js +14 -0
- package/dist/controls.css +1 -1
- package/dist/demo.compiled.debug.js +170 -290
- package/dist/demo.compiled.debug.map +4 -4
- package/dist/demo.compiled.js +170 -290
- package/dist/demo.compiled.map +4 -4
- package/dist/deps.js +2 -2
- package/dist/locales.js +30 -30
- package/dist/receiver.compiled.debug.js +52 -81
- package/dist/receiver.compiled.debug.map +4 -4
- package/dist/receiver.compiled.js +52 -81
- package/dist/receiver.compiled.map +4 -4
- package/dist/shaka-player.compiled.d.ts +19 -3
- package/dist/shaka-player.compiled.debug.d.ts +19 -3
- package/dist/shaka-player.compiled.debug.externs.js +17 -12
- package/dist/shaka-player.compiled.debug.js +181 -176
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +17 -12
- package/dist/shaka-player.compiled.js +825 -823
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.d.ts +19 -3
- package/dist/shaka-player.ui.debug.d.ts +19 -3
- package/dist/shaka-player.ui.debug.externs.js +5 -0
- package/dist/shaka-player.ui.debug.js +191 -186
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.externs.js +5 -0
- package/dist/shaka-player.ui.js +955 -951
- package/dist/shaka-player.ui.map +3 -3
- package/docs/tutorials/a11y.md +0 -4
- package/docs/tutorials/ad_monetization.md +0 -4
- package/docs/tutorials/basic-usage.md +0 -5
- package/docs/tutorials/config.md +0 -5
- package/docs/tutorials/debugging.md +0 -5
- package/docs/tutorials/drm-config.md +0 -5
- package/docs/tutorials/errors.md +94 -0
- package/docs/tutorials/fairplay.md +4 -4
- package/docs/tutorials/index.json +2 -0
- package/docs/tutorials/license-server-auth.md +0 -5
- package/docs/tutorials/license-wrapping.md +0 -5
- package/docs/tutorials/network-and-buffering-config.md +0 -5
- package/docs/tutorials/ui-customization.md +0 -5
- package/docs/tutorials/ui.md +0 -7
- package/docs/tutorials/welcome.md +0 -5
- package/docs/tutorials/widevine-service-certs.md +45 -0
- package/externs/ima.js +9 -0
- package/externs/network_information.js +7 -2
- package/externs/shaka/abr_manager.js +6 -0
- package/externs/shaka/net.js +1 -0
- package/externs/shaka/player.js +13 -7
- package/lib/abr/simple_abr_manager.js +27 -3
- package/lib/ads/client_side_ad_manager.js +11 -5
- package/lib/dash/dash_parser.js +49 -48
- package/lib/debug/log.js +9 -13
- package/lib/hls/hls_parser.js +2 -0
- package/lib/media/drm_engine.js +4 -2
- package/lib/media/media_source_engine.js +11 -4
- package/lib/media/segment_index.js +2 -0
- package/lib/media/streaming_engine.js +8 -3
- package/lib/media/transmuxer.js +13 -7
- package/lib/media/video_wrapper.js +3 -3
- package/lib/net/http_fetch_plugin.js +79 -57
- package/lib/net/networking_engine.js +1 -0
- package/lib/offline/indexeddb/storage_mechanism.js +1 -1
- package/lib/player.js +24 -3
- package/lib/polyfill/media_capabilities.js +15 -8
- package/lib/polyfill/mediasource.js +24 -2
- package/lib/text/mp4_vtt_parser.js +4 -0
- package/lib/text/text_engine.js +1 -0
- package/lib/text/ui_text_displayer.js +1 -0
- package/lib/text/vtt_text_parser.js +4 -5
- package/lib/util/manifest_parser_utils.js +1 -2
- package/lib/util/mime_utils.js +12 -1
- package/lib/util/periods.js +5 -5
- package/lib/util/stream_utils.js +28 -16
- package/maintained-branches.md +3 -4
- package/package.json +1 -1
- package/test/media/content_workarounds_unit.js +43 -0
- package/test/media/drm_engine_integration.js +4 -17
- package/test/media/streaming_engine_unit.js +6 -1
- package/test/net/networking_engine_unit.js +6 -1
- package/test/player_integration.js +39 -0
- package/test/player_unit.js +57 -0
- package/test/polyfill/media_capabilities_unit.js +20 -23
- package/test/test/assets/text-clip-alt.vtt +63 -0
- package/test/test/util/fake_drm_engine.js +3 -0
- package/test/test/util/simple_fakes.js +6 -0
- package/test/test/util/test_scheme.js +9 -14
- package/test/text/mp4_vtt_parser_unit.js +8 -0
- package/test/text/vtt_text_parser_unit.js +26 -2
- package/test/text/web_vtt_layout_integration.js +0 -3
- package/test/util/mime_utils_unit.js +10 -0
package/lib/util/stream_utils.js
CHANGED
|
@@ -710,26 +710,38 @@ shaka.util.StreamUtils = class {
|
|
|
710
710
|
}
|
|
711
711
|
|
|
712
712
|
if (audio) {
|
|
713
|
-
|
|
713
|
+
// See: https://github.com/shaka-project/shaka-player/issues/4659
|
|
714
|
+
if (info.audioRobustness != '') {
|
|
715
|
+
if (!keySystemConfig.audio) {
|
|
716
|
+
// KeySystemTrackConfiguration
|
|
717
|
+
keySystemConfig.audio = {
|
|
718
|
+
robustness: info.audioRobustness,
|
|
719
|
+
};
|
|
720
|
+
} else {
|
|
721
|
+
keySystemConfig.audio.robustness =
|
|
722
|
+
keySystemConfig.audio.robustness || info.audioRobustness;
|
|
723
|
+
}
|
|
724
|
+
} else if (!keySystemConfig.audio) {
|
|
714
725
|
// KeySystemTrackConfiguration
|
|
715
|
-
keySystemConfig.audio = {
|
|
716
|
-
robustness: info.audioRobustness,
|
|
717
|
-
};
|
|
718
|
-
} else {
|
|
719
|
-
keySystemConfig.audio.robustness =
|
|
720
|
-
keySystemConfig.audio.robustness || info.audioRobustness;
|
|
726
|
+
keySystemConfig.audio = {};
|
|
721
727
|
}
|
|
722
728
|
}
|
|
723
729
|
|
|
724
730
|
if (video) {
|
|
725
|
-
|
|
731
|
+
// See: https://github.com/shaka-project/shaka-player/issues/4659
|
|
732
|
+
if (info.videoRobustness != '') {
|
|
733
|
+
if (!keySystemConfig.video) {
|
|
734
|
+
// KeySystemTrackConfiguration
|
|
735
|
+
keySystemConfig.video = {
|
|
736
|
+
robustness: info.videoRobustness,
|
|
737
|
+
};
|
|
738
|
+
} else {
|
|
739
|
+
keySystemConfig.video.robustness =
|
|
740
|
+
keySystemConfig.video.robustness || info.videoRobustness;
|
|
741
|
+
}
|
|
742
|
+
} else if (!keySystemConfig.video) {
|
|
726
743
|
// KeySystemTrackConfiguration
|
|
727
|
-
keySystemConfig.video = {
|
|
728
|
-
robustness: info.videoRobustness,
|
|
729
|
-
};
|
|
730
|
-
} else {
|
|
731
|
-
keySystemConfig.video.robustness =
|
|
732
|
-
keySystemConfig.video.robustness || info.videoRobustness;
|
|
744
|
+
keySystemConfig.video = {};
|
|
733
745
|
}
|
|
734
746
|
}
|
|
735
747
|
}
|
|
@@ -816,7 +828,7 @@ shaka.util.StreamUtils = class {
|
|
|
816
828
|
const video = variant.video;
|
|
817
829
|
if (audio && currentVariant && currentVariant.audio) {
|
|
818
830
|
if (!StreamUtils.areStreamsCompatible_(audio, currentVariant.audio)) {
|
|
819
|
-
shaka.log.debug('
|
|
831
|
+
shaka.log.debug('Dropping variant - not compatible with active audio',
|
|
820
832
|
'active audio',
|
|
821
833
|
StreamUtils.getStreamSummaryString_(currentVariant.audio),
|
|
822
834
|
'variant.audio',
|
|
@@ -827,7 +839,7 @@ shaka.util.StreamUtils = class {
|
|
|
827
839
|
|
|
828
840
|
if (video && currentVariant && currentVariant.video) {
|
|
829
841
|
if (!StreamUtils.areStreamsCompatible_(video, currentVariant.video)) {
|
|
830
|
-
shaka.log.debug('
|
|
842
|
+
shaka.log.debug('Dropping variant - not compatible with active video',
|
|
831
843
|
'active video',
|
|
832
844
|
StreamUtils.getStreamSummaryString_(currentVariant.video),
|
|
833
845
|
'variant.video',
|
package/maintained-branches.md
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
We are currently maintaining the following branches of Shaka Player:
|
|
4
4
|
|
|
5
|
-
- v4.
|
|
6
|
-
- v4.
|
|
7
|
-
-
|
|
8
|
-
- v3.2 (in use by the Cast Application Framework)
|
|
5
|
+
- v4.3 (latest, also in use by the Cast Application Framework)
|
|
6
|
+
- v4.2 (previous)
|
|
7
|
+
- No active LTS branches at this time
|
|
9
8
|
|
|
10
9
|
Other branches are no longer receiving bug fixes, and we recommend you upgrade
|
|
11
10
|
to a maintained branch. For details on upgrading, please see our
|
package/package.json
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
describe('ContentWorkarounds', () => {
|
|
8
|
+
const encryptionBoxes = {
|
|
9
|
+
'encv': ['hev1', 'hvc1', 'avc1', 'avc3'],
|
|
10
|
+
'enca': ['ac-3', 'ec-3', 'mp4a'],
|
|
11
|
+
};
|
|
12
|
+
for (const encryptionBox of Object.keys(encryptionBoxes)) {
|
|
13
|
+
for (const box of encryptionBoxes[encryptionBox]) {
|
|
14
|
+
it(`adds ${encryptionBox} box for ${box}`, () => {
|
|
15
|
+
const boxType = [];
|
|
16
|
+
for (const char of box) {
|
|
17
|
+
boxType.push(char.charCodeAt(0));
|
|
18
|
+
}
|
|
19
|
+
const unencrypted = new Uint8Array([
|
|
20
|
+
0x00, 0x00, 0x00, 0x20, // size
|
|
21
|
+
0x73, 0x74, 0x73, 0x64, // stsd
|
|
22
|
+
0x01, // version
|
|
23
|
+
0x12, 0x34, 0x56, // flags
|
|
24
|
+
0x00, 0x00, 0x00, 0x01, // count
|
|
25
|
+
0x00, 0x00, 0x00, 0x10, // size
|
|
26
|
+
...boxType, // box type
|
|
27
|
+
0x01, // version
|
|
28
|
+
0x12, 0x34, 0x56, // flags
|
|
29
|
+
0x00, 0x11, 0x22, 0x33, // payload
|
|
30
|
+
]);
|
|
31
|
+
|
|
32
|
+
const faked =
|
|
33
|
+
shaka.media.ContentWorkarounds.fakeEncryption(unencrypted);
|
|
34
|
+
const spy = jasmine.createSpy('boxCallback');
|
|
35
|
+
new shaka.util.Mp4Parser()
|
|
36
|
+
.fullBox('stsd', shaka.util.Mp4Parser.sampleDescription)
|
|
37
|
+
.box(encryptionBox, /** @type {!Function} */ (spy))
|
|
38
|
+
.parse(faked);
|
|
39
|
+
expect(spy).toHaveBeenCalled();
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
@@ -74,19 +74,6 @@ describe('DrmEngine', () => {
|
|
|
74
74
|
onEventSpy = jasmine.createSpy('onEvent');
|
|
75
75
|
|
|
76
76
|
networkingEngine = new shaka.net.NetworkingEngine();
|
|
77
|
-
networkingEngine.registerRequestFilter((type, request) => {
|
|
78
|
-
if (type != shaka.net.NetworkingEngine.RequestType.LICENSE) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
request.headers['X-AxDRM-Message'] = [
|
|
83
|
-
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ2ZXJzaW9uIjoxLCJjb21fa2V5X2lk',
|
|
84
|
-
'IjoiNjllNTQwODgtZTllMC00NTMwLThjMWEtMWViNmRjZDBkMTRlIiwibWVzc2FnZSI6e',
|
|
85
|
-
'yJ0eXBlIjoiZW50aXRsZW1lbnRfbWVzc2FnZSIsImtleXMiOlt7ImlkIjoiNmU1YTFkMj',
|
|
86
|
-
'YtMjc1Ny00N2Q3LTgwNDYtZWFhNWQxZDM0YjVhIn1dfX0.yF7PflOPv9qHnu3ZWJNZ12j',
|
|
87
|
-
'gkqTabmwXbDWk_47tLNE',
|
|
88
|
-
].join('');
|
|
89
|
-
});
|
|
90
77
|
|
|
91
78
|
const playerInterface = {
|
|
92
79
|
netEngine: networkingEngine,
|
|
@@ -99,22 +86,22 @@ describe('DrmEngine', () => {
|
|
|
99
86
|
drmEngine = new shaka.media.DrmEngine(playerInterface);
|
|
100
87
|
const config = shaka.util.PlayerConfiguration.createDefault().drm;
|
|
101
88
|
config.servers['com.widevine.alpha'] =
|
|
102
|
-
'https://
|
|
89
|
+
'https://cwip-shaka-proxy.appspot.com/specific_key?blodJidXR9eARuql0dNLWg=GX8m9XLIZNIzizrl0RTqnA';
|
|
103
90
|
config.servers['com.microsoft.playready'] =
|
|
104
|
-
'https://
|
|
91
|
+
'https://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(kid:6e5a1d26-2757-47d7-8046-eaa5d1d34b5a,contentkey:GX8m9XLIZNIzizrl0RTqnA==,sl:150)';
|
|
105
92
|
drmEngine.configure(config);
|
|
106
93
|
|
|
107
94
|
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
108
95
|
manifest.addVariant(0, (variant) => {
|
|
109
96
|
variant.addVideo(1, (stream) => {
|
|
110
97
|
stream.encrypted = true;
|
|
111
|
-
stream.addDrmInfo('com.widevine.alpha');
|
|
112
98
|
stream.addDrmInfo('com.microsoft.playready');
|
|
99
|
+
stream.addDrmInfo('com.widevine.alpha');
|
|
113
100
|
});
|
|
114
101
|
variant.addAudio(2, (stream) => {
|
|
115
102
|
stream.encrypted = true;
|
|
116
|
-
stream.addDrmInfo('com.widevine.alpha');
|
|
117
103
|
stream.addDrmInfo('com.microsoft.playready');
|
|
104
|
+
stream.addDrmInfo('com.widevine.alpha');
|
|
118
105
|
});
|
|
119
106
|
});
|
|
120
107
|
});
|
|
@@ -3297,7 +3297,12 @@ describe('StreamingEngine', () => {
|
|
|
3297
3297
|
netEngine.request.and.callFake((requestType, request) => {
|
|
3298
3298
|
const buffer = new ArrayBuffer(0);
|
|
3299
3299
|
/** @type {shaka.extern.Response} */
|
|
3300
|
-
const response = {
|
|
3300
|
+
const response = {
|
|
3301
|
+
uri: request.uris[0],
|
|
3302
|
+
originalUri: request.uris[0],
|
|
3303
|
+
data: buffer,
|
|
3304
|
+
headers: {},
|
|
3305
|
+
};
|
|
3301
3306
|
return shaka.util.AbortableOperation.completed(response);
|
|
3302
3307
|
});
|
|
3303
3308
|
|
|
@@ -1226,6 +1226,11 @@ describe('NetworkingEngine', /** @suppress {accessControls} */ () => {
|
|
|
1226
1226
|
|
|
1227
1227
|
/** @return {shaka.extern.Response} */
|
|
1228
1228
|
function createResponse() {
|
|
1229
|
-
return {
|
|
1229
|
+
return {
|
|
1230
|
+
uri: '',
|
|
1231
|
+
originalUri: '',
|
|
1232
|
+
data: new ArrayBuffer(5),
|
|
1233
|
+
headers: {},
|
|
1234
|
+
};
|
|
1230
1235
|
}
|
|
1231
1236
|
}); // describe('NetworkingEngine')
|
|
@@ -401,6 +401,45 @@ describe('Player', () => {
|
|
|
401
401
|
player.setTextTrackVisibility(true);
|
|
402
402
|
expect(getTracksActive()).toEqual([false, true]);
|
|
403
403
|
});
|
|
404
|
+
|
|
405
|
+
// https://github.com/shaka-project/shaka-player/issues/4821
|
|
406
|
+
it('loads a single text stream', async () => {
|
|
407
|
+
player.configure({preferredTextLanguage: 'en'});
|
|
408
|
+
await player.load('test:sintel_no_text_compiled');
|
|
409
|
+
|
|
410
|
+
// Add preferred language text track.
|
|
411
|
+
const locationUri = new goog.Uri(location.href);
|
|
412
|
+
const partialUri = new goog.Uri('/base/test/test/assets/text-clip.vtt');
|
|
413
|
+
const absoluteUri = locationUri.resolve(partialUri);
|
|
414
|
+
await player.addTextTrackAsync(
|
|
415
|
+
absoluteUri.toString(), 'en', 'subtitles', 'text/vtt');
|
|
416
|
+
|
|
417
|
+
// Add alternate language text track.
|
|
418
|
+
// Two text tracks with same timings but different text
|
|
419
|
+
// are necessary for test.
|
|
420
|
+
const partialUri2 =
|
|
421
|
+
new goog.Uri('/base/test/test/assets/text-clip-alt.vtt');
|
|
422
|
+
const absoluteUri2 = locationUri.resolve(partialUri2);
|
|
423
|
+
await player.addTextTrackAsync(
|
|
424
|
+
absoluteUri2.toString(), 'fr', 'subtitles', 'text/vtt');
|
|
425
|
+
|
|
426
|
+
const textTracks = player.getTextTracks();
|
|
427
|
+
expect(textTracks.length).toBe(2);
|
|
428
|
+
expect(textTracks[0].language).toBe('en');
|
|
429
|
+
expect(textTracks[1].language).toBe('fr');
|
|
430
|
+
|
|
431
|
+
// Enable text visibilty and immediately change language.
|
|
432
|
+
// Only one set of cues should be active.
|
|
433
|
+
// Cues should be of the selected language track.
|
|
434
|
+
player.setTextTrackVisibility(true);
|
|
435
|
+
player.selectTextLanguage('fr');
|
|
436
|
+
video.currentTime = 5;
|
|
437
|
+
video.play();
|
|
438
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
439
|
+
|
|
440
|
+
expect(video.textTracks[0].activeCues.length).toBe(1);
|
|
441
|
+
expect(player.getTextTracks()[1].active).toBe(true);
|
|
442
|
+
});
|
|
404
443
|
}); // describe('setTextTrackVisibility')
|
|
405
444
|
|
|
406
445
|
describe('plays', () => {
|
package/test/player_unit.js
CHANGED
|
@@ -205,6 +205,7 @@ describe('Player', () => {
|
|
|
205
205
|
await player.destroy();
|
|
206
206
|
|
|
207
207
|
expect(abrManager.stop).toHaveBeenCalled();
|
|
208
|
+
expect(abrManager.release).toHaveBeenCalled();
|
|
208
209
|
expect(networkingEngine.destroy).toHaveBeenCalled();
|
|
209
210
|
expect(drmEngine.destroy).toHaveBeenCalled();
|
|
210
211
|
expect(playhead.release).toHaveBeenCalled();
|
|
@@ -243,6 +244,7 @@ describe('Player', () => {
|
|
|
243
244
|
parser.start.and.returnValue(p);
|
|
244
245
|
parser.stop.and.callFake(() => {
|
|
245
246
|
expect(abrManager.stop).not.toHaveBeenCalled();
|
|
247
|
+
expect(abrManager.release).not.toHaveBeenCalled();
|
|
246
248
|
expect(networkingEngine.destroy).not.toHaveBeenCalled();
|
|
247
249
|
});
|
|
248
250
|
shaka.media.ManifestParser.registerParserByMime(
|
|
@@ -252,6 +254,7 @@ describe('Player', () => {
|
|
|
252
254
|
await shaka.test.Util.shortDelay();
|
|
253
255
|
await player.destroy();
|
|
254
256
|
expect(abrManager.stop).toHaveBeenCalled();
|
|
257
|
+
expect(abrManager.release).toHaveBeenCalled();
|
|
255
258
|
expect(networkingEngine.destroy).toHaveBeenCalled();
|
|
256
259
|
expect(parser.stop).toHaveBeenCalled();
|
|
257
260
|
await expectAsync(load).toBeRejected();
|
|
@@ -551,6 +554,60 @@ describe('Player', () => {
|
|
|
551
554
|
expect(streamingEngine.unloadTextStream).not.toHaveBeenCalled();
|
|
552
555
|
});
|
|
553
556
|
});
|
|
557
|
+
|
|
558
|
+
describe('when config.streaming.preferNativeHls is set to true', () => {
|
|
559
|
+
beforeEach(() => {
|
|
560
|
+
shaka.media.ManifestParser.registerParserByMime(
|
|
561
|
+
'application/x-mpegurl',
|
|
562
|
+
() => new shaka.test.FakeManifestParser(manifest));
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
afterEach(() => {
|
|
566
|
+
shaka.media.ManifestParser.unregisterParserByMime(
|
|
567
|
+
'application/x-mpegurl');
|
|
568
|
+
video.canPlayType.calls.reset();
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
it('only applies to HLS streams', async () => {
|
|
572
|
+
video.canPlayType.and.returnValue('maybe');
|
|
573
|
+
spyOn(shaka.util.Platform, 'anyMediaElement').and.returnValue(video);
|
|
574
|
+
spyOn(shaka.util.Platform, 'supportsMediaSource').and.returnValue(true);
|
|
575
|
+
spyOn(shaka.util.Platform, 'isApple').and.returnValue(false);
|
|
576
|
+
// Make sure player.load() resolves for src=
|
|
577
|
+
spyOn(shaka.util.MediaReadyState, 'waitForReadyState').and.callFake(
|
|
578
|
+
(mediaElement, readyState, eventManager, callback) => {
|
|
579
|
+
callback();
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
player.configure({
|
|
583
|
+
streaming: {
|
|
584
|
+
preferNativeHls: true,
|
|
585
|
+
useNativeHlsOnSafari: false,
|
|
586
|
+
},
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
await player.load(fakeManifestUri, undefined, 'application/x-mpegurl');
|
|
590
|
+
|
|
591
|
+
expect(player.getLoadMode()).toBe(shaka.Player.LoadMode.SRC_EQUALS);
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
it('does not apply to non-HLS streams', async () => {
|
|
595
|
+
video.canPlayType.and.returnValue('maybe');
|
|
596
|
+
spyOn(shaka.util.Platform, 'supportsMediaSource').and.returnValue(true);
|
|
597
|
+
spyOn(shaka.util.Platform, 'isApple').and.returnValue(false);
|
|
598
|
+
|
|
599
|
+
player.configure({
|
|
600
|
+
streaming: {
|
|
601
|
+
preferNativeHls: true,
|
|
602
|
+
useNativeHlsOnSafari: false,
|
|
603
|
+
},
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
await player.load(fakeManifestUri, 0, fakeMimeType);
|
|
607
|
+
|
|
608
|
+
expect(player.getLoadMode()).toBe(shaka.Player.LoadMode.MEDIA_SOURCE);
|
|
609
|
+
});
|
|
610
|
+
});
|
|
554
611
|
}); // describe('load/unload')
|
|
555
612
|
|
|
556
613
|
describe('getConfiguration', () => {
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
describe('MediaCapabilities', () => {
|
|
8
|
-
const Util = shaka.test.Util;
|
|
9
8
|
const originalCast = window['cast'];
|
|
10
9
|
const originalVendor = navigator.vendor;
|
|
11
10
|
const originalUserAgent = navigator.userAgent;
|
|
@@ -68,7 +67,6 @@ describe('MediaCapabilities', () => {
|
|
|
68
67
|
width: 512,
|
|
69
68
|
},
|
|
70
69
|
};
|
|
71
|
-
shaka.polyfill.MediaCapabilities.memoizedMediaKeySystemAccessRequests_ = {};
|
|
72
70
|
|
|
73
71
|
mockCanDisplayType = jasmine.createSpy('canDisplayType');
|
|
74
72
|
mockCanDisplayType.and.returnValue(false);
|
|
@@ -168,30 +166,29 @@ describe('MediaCapabilities', () => {
|
|
|
168
166
|
expect(result.keySystemAccess).toEqual(mockResult);
|
|
169
167
|
});
|
|
170
168
|
|
|
171
|
-
it('
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
169
|
+
it('falls back to isTypeSupported() when cast namespace is not available',
|
|
170
|
+
async () => {
|
|
171
|
+
// Temporarily remove window.cast to trigger error. It's restored
|
|
172
|
+
// after every test.
|
|
173
|
+
delete window['cast'];
|
|
175
174
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
shaka.util.Error.Code.CAST_API_UNAVAILABLE));
|
|
183
|
-
const isTypeSupportedSpy =
|
|
184
|
-
spyOn(window['MediaSource'], 'isTypeSupported').and.returnValue(true);
|
|
175
|
+
const isChromecastSpy =
|
|
176
|
+
spyOn(shaka['util']['Platform'],
|
|
177
|
+
'isChromecast').and.returnValue(true);
|
|
178
|
+
const isTypeSupportedSpy =
|
|
179
|
+
spyOn(window['MediaSource'], 'isTypeSupported')
|
|
180
|
+
.and.returnValue(true);
|
|
185
181
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
navigator.mediaCapabilities.decodingInfo(mockDecodingConfig))
|
|
189
|
-
.toBeRejectedWith(expected);
|
|
182
|
+
shaka.polyfill.MediaCapabilities.install();
|
|
183
|
+
await navigator.mediaCapabilities.decodingInfo(mockDecodingConfig);
|
|
190
184
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
185
|
+
expect(mockCanDisplayType).not.toHaveBeenCalled();
|
|
186
|
+
// 1 (during install()) + 1 (for video config check).
|
|
187
|
+
expect(isChromecastSpy).toHaveBeenCalledTimes(2);
|
|
188
|
+
// 1 (fallback in canCastDisplayType()) +
|
|
189
|
+
// 1 (mockDecodingConfig.audio).
|
|
190
|
+
expect(isTypeSupportedSpy).toHaveBeenCalledTimes(2);
|
|
191
|
+
});
|
|
195
192
|
|
|
196
193
|
it('falls back to isTypeSupported() when canDisplayType() missing',
|
|
197
194
|
async () => {
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
WEBVTT
|
|
2
|
+
|
|
3
|
+
00:04.000 --> 00:07.300
|
|
4
|
+
Journal de bord du capitaine.
|
|
5
|
+
Date stellaire 41636.9.
|
|
6
|
+
|
|
7
|
+
00:07.500 --> 00:11.800
|
|
8
|
+
Comme nous le craignions, l'épave
|
|
9
|
+
du cargo Odin de la Fédération,
|
|
10
|
+
|
|
11
|
+
00:12.100 --> 00:16.400
|
|
12
|
+
percuté par un astéroïde,
|
|
13
|
+
ne révèle aucun signe de vie.
|
|
14
|
+
|
|
15
|
+
00:16.700 --> 00:19.000
|
|
16
|
+
Mais trois nacelles
|
|
17
|
+
de sauvetage manquaient,
|
|
18
|
+
|
|
19
|
+
00:19.300 --> 00:21.900
|
|
20
|
+
laissant supposer
|
|
21
|
+
qu'il y aurait des survivants.
|
|
22
|
+
|
|
23
|
+
00:22.700 --> 00:27.700
|
|
24
|
+
- Mise sur orbite Angel One, paré.
|
|
25
|
+
- Quel genre d'endroit, Data ?
|
|
26
|
+
|
|
27
|
+
00:28.200 --> 00:31.600
|
|
28
|
+
Planète de Classe-M.
|
|
29
|
+
Faune et flore à base de carbone.
|
|
30
|
+
|
|
31
|
+
00:31.900 --> 00:34.300
|
|
32
|
+
Population éparse
|
|
33
|
+
et forme de vie intelligente.
|
|
34
|
+
|
|
35
|
+
00:34.600 --> 00:38.400
|
|
36
|
+
Développement technique équivalent
|
|
37
|
+
au milieu du 20ème siècle terrien.
|
|
38
|
+
|
|
39
|
+
00:38.800 --> 00:41.000
|
|
40
|
+
C'est presque un retour aux sources.
|
|
41
|
+
|
|
42
|
+
00:41.300 --> 00:43.600
|
|
43
|
+
Si jamais des survivants
|
|
44
|
+
ont pu aller si loin,
|
|
45
|
+
|
|
46
|
+
00:43.800 --> 00:49.000
|
|
47
|
+
c'était la planète la plus proche.
|
|
48
|
+
La distance qui nous a pris 2 jours
|
|
49
|
+
|
|
50
|
+
00:49.500 --> 00:52.400
|
|
51
|
+
aurait pris 5 mois aux nacelles
|
|
52
|
+
de sauvetage du Odin.
|
|
53
|
+
|
|
54
|
+
00:52.600 --> 00:54.700
|
|
55
|
+
Cinq mois, six jours, onze heures,
|
|
56
|
+
deux min...
|
|
57
|
+
|
|
58
|
+
00:54.900 --> 00:58.400
|
|
59
|
+
- Merci, Data.
|
|
60
|
+
- ..et 57 secondes.
|
|
61
|
+
|
|
62
|
+
00:58.600 --> 01:01.300
|
|
63
|
+
Signal audio provenant d'Angel One.
|
|
@@ -81,6 +81,9 @@ shaka.test.FakeDrmEngine = class {
|
|
|
81
81
|
/** @type {!jasmine.Spy} */
|
|
82
82
|
this.supportsVariant = jasmine.createSpy('supportsVariant');
|
|
83
83
|
this.supportsVariant.and.returnValue(true);
|
|
84
|
+
|
|
85
|
+
/** @type {!jasmine.Spy} */
|
|
86
|
+
this.setSrcEquals = jasmine.createSpy('setSrcEquals');
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
/**
|
|
@@ -35,6 +35,9 @@ shaka.test.FakeAbrManager = class {
|
|
|
35
35
|
/** @type {!jasmine.Spy} */
|
|
36
36
|
this.stop = jasmine.createSpy('stop');
|
|
37
37
|
|
|
38
|
+
/** @type {!jasmine.Spy} */
|
|
39
|
+
this.release = jasmine.createSpy('release');
|
|
40
|
+
|
|
38
41
|
/** @type {!jasmine.Spy} */
|
|
39
42
|
this.enable = jasmine.createSpy('enable');
|
|
40
43
|
|
|
@@ -225,6 +228,9 @@ shaka.test.FakeVideo = class {
|
|
|
225
228
|
|
|
226
229
|
/** @type {!jasmine.Spy} */
|
|
227
230
|
this.dispatchEvent = jasmine.createSpy('dispatchEvent');
|
|
231
|
+
|
|
232
|
+
/** @type {!jasmine.Spy} */
|
|
233
|
+
this.canPlayType = jasmine.createSpy('canPlayType');
|
|
228
234
|
}
|
|
229
235
|
};
|
|
230
236
|
|
|
@@ -447,6 +447,7 @@ const widevineDrmServers = {
|
|
|
447
447
|
|
|
448
448
|
/** @type {AVMetadataType} */
|
|
449
449
|
const axinomMultiDrmVideoSegment = {
|
|
450
|
+
// Taken from Axinom's v6 test vector.
|
|
450
451
|
initSegmentUri: '/base/test/test/assets/multidrm-video-init.mp4',
|
|
451
452
|
mdhdOffset: 0x1d1,
|
|
452
453
|
segmentUri: '/base/test/test/assets/multidrm-video-segment.mp4',
|
|
@@ -461,6 +462,7 @@ const axinomMultiDrmVideoSegment = {
|
|
|
461
462
|
|
|
462
463
|
/** @type {AVMetadataType} */
|
|
463
464
|
const axinomMultiDrmAudioSegment = {
|
|
465
|
+
// Taken from Axinom's v6 test vector.
|
|
464
466
|
initSegmentUri: '/base/test/test/assets/multidrm-audio-init.mp4',
|
|
465
467
|
mdhdOffset: 0x192,
|
|
466
468
|
segmentUri: '/base/test/test/assets/multidrm-audio-segment.mp4',
|
|
@@ -475,20 +477,15 @@ const axinomMultiDrmAudioSegment = {
|
|
|
475
477
|
|
|
476
478
|
/** @type {!Object.<string, string>} */
|
|
477
479
|
const axinomDrmServers = {
|
|
480
|
+
// NOTE: These are not Axinom's actual servers. These are test servers for
|
|
481
|
+
// Widevine and PlayReady that let us specify the known key IDs and keys for
|
|
482
|
+
// Axinom's v6 test vectors. Axinom's own servers started returning 403
|
|
483
|
+
// errors for these older test vectors, and we were forced to switch to
|
|
484
|
+
// something stable and independent.
|
|
478
485
|
'com.widevine.alpha':
|
|
479
|
-
'https://
|
|
486
|
+
'https://cwip-shaka-proxy.appspot.com/specific_key?blodJidXR9eARuql0dNLWg=GX8m9XLIZNIzizrl0RTqnA',
|
|
480
487
|
'com.microsoft.playready':
|
|
481
|
-
'https://
|
|
482
|
-
};
|
|
483
|
-
|
|
484
|
-
/** @type {!Object.<string, string>} */
|
|
485
|
-
const axinomDrmHeaders = {
|
|
486
|
-
'X-AxDRM-Message':
|
|
487
|
-
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ2ZXJzaW9uIjoxLCJjb21fa2V5' +
|
|
488
|
-
'X2lkIjoiNjllNTQwODgtZTllMC00NTMwLThjMWEtMWViNmRjZDBkMTRlIiwibWVzc' +
|
|
489
|
-
'2FnZSI6eyJ0eXBlIjoiZW50aXRsZW1lbnRfbWVzc2FnZSIsImtleXMiOlt7ImlkIj' +
|
|
490
|
-
'oiNmU1YTFkMjYtMjc1Ny00N2Q3LTgwNDYtZWFhNWQxZDM0YjVhIn1dfX0.yF7PflO' +
|
|
491
|
-
'Pv9qHnu3ZWJNZ12jgkqTabmwXbDWk_47tLNE',
|
|
488
|
+
'https://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(kid:6e5a1d26-2757-47d7-8046-eaa5d1d34b5a,contentkey:GX8m9XLIZNIzizrl0RTqnA==,sl:150)',
|
|
492
489
|
};
|
|
493
490
|
|
|
494
491
|
/** @type {TextMetadataType} */
|
|
@@ -601,7 +598,6 @@ shaka.test.TestScheme.DATA = {
|
|
|
601
598
|
audio: axinomMultiDrmAudioSegment,
|
|
602
599
|
text: vttSegment,
|
|
603
600
|
licenseServers: axinomDrmServers,
|
|
604
|
-
licenseRequestHeaders: axinomDrmHeaders,
|
|
605
601
|
duration: 30,
|
|
606
602
|
sequenceMode: false,
|
|
607
603
|
},
|
|
@@ -614,7 +610,6 @@ shaka.test.TestScheme.DATA = {
|
|
|
614
610
|
initData: undefined,
|
|
615
611
|
}),
|
|
616
612
|
licenseServers: axinomDrmServers,
|
|
617
|
-
licenseRequestHeaders: axinomDrmHeaders,
|
|
618
613
|
duration: 30,
|
|
619
614
|
sequenceMode: false,
|
|
620
615
|
},
|
|
@@ -171,6 +171,14 @@ describe('Mp4VttParser', () => {
|
|
|
171
171
|
verifyHelper(cues, result);
|
|
172
172
|
});
|
|
173
173
|
|
|
174
|
+
it('handles empty media segments', () => {
|
|
175
|
+
const parser = new shaka.text.Mp4VttParser();
|
|
176
|
+
parser.parseInit(vttInitSegment);
|
|
177
|
+
const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0};
|
|
178
|
+
const result = parser.parseMedia(new Uint8Array(0), time);
|
|
179
|
+
verifyHelper([], result);
|
|
180
|
+
});
|
|
181
|
+
|
|
174
182
|
it('rejects init segment with no vtt', () => {
|
|
175
183
|
const error = shaka.test.Util.jasmineError(new shaka.util.Error(
|
|
176
184
|
shaka.util.Error.Severity.CRITICAL,
|
|
@@ -852,11 +852,35 @@ describe('VttTextParser', () => {
|
|
|
852
852
|
it('support escaped html payload', () => {
|
|
853
853
|
verifyHelper(
|
|
854
854
|
[
|
|
855
|
-
{
|
|
855
|
+
{
|
|
856
|
+
startTime: 20.1,
|
|
857
|
+
endTime: 40.505,
|
|
858
|
+
payload: '"Test & 1"\u{a0}',
|
|
859
|
+
},
|
|
860
|
+
{
|
|
861
|
+
startTime: 41,
|
|
862
|
+
endTime: 42,
|
|
863
|
+
payload: '',
|
|
864
|
+
nestedCues: [
|
|
865
|
+
{
|
|
866
|
+
startTime: 41,
|
|
867
|
+
endTime: 42,
|
|
868
|
+
payload: 'Test',
|
|
869
|
+
fontStyle: Cue.fontStyle.ITALIC,
|
|
870
|
+
},
|
|
871
|
+
{
|
|
872
|
+
startTime: 41,
|
|
873
|
+
endTime: 42,
|
|
874
|
+
payload: '&',
|
|
875
|
+
},
|
|
876
|
+
],
|
|
877
|
+
},
|
|
856
878
|
],
|
|
857
879
|
'WEBVTT\n\n' +
|
|
858
880
|
'00:00:20.100 --> 00:00:40.505\n' +
|
|
859
|
-
'"Test & 1" 
|
|
881
|
+
'"Test & 1" \n\n' +
|
|
882
|
+
'00:00:41.000 --> 00:00:42.000\n' +
|
|
883
|
+
'<i>Test</i>&',
|
|
860
884
|
{periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
|
|
861
885
|
});
|
|
862
886
|
|
|
@@ -265,7 +265,6 @@ filterDescribe('WebVTT layout', shaka.test.TextLayoutTests.supported, () => {
|
|
|
265
265
|
await helper.checkScreenshot('line-85-position-50-size-63');
|
|
266
266
|
});
|
|
267
267
|
|
|
268
|
-
// FIXME: UI version is slightly wrong: gaps between lines when bold
|
|
269
268
|
it('bold long', async () => {
|
|
270
269
|
parseAndDisplay([
|
|
271
270
|
'WEBVTT\n',
|
|
@@ -278,7 +277,6 @@ filterDescribe('WebVTT layout', shaka.test.TextLayoutTests.supported, () => {
|
|
|
278
277
|
await helper.checkScreenshot('bold-long');
|
|
279
278
|
});
|
|
280
279
|
|
|
281
|
-
// FIXME: UI version is slightly wrong: gaps between lines when italic
|
|
282
280
|
it('italic long', async () => {
|
|
283
281
|
parseAndDisplay([
|
|
284
282
|
'WEBVTT\n',
|
|
@@ -291,7 +289,6 @@ filterDescribe('WebVTT layout', shaka.test.TextLayoutTests.supported, () => {
|
|
|
291
289
|
await helper.checkScreenshot('italic-long');
|
|
292
290
|
});
|
|
293
291
|
|
|
294
|
-
// FIXME: UI version is slightly wrong: gaps between lines when italic
|
|
295
292
|
it('underline long', async () => {
|
|
296
293
|
parseAndDisplay([
|
|
297
294
|
'WEBVTT\n',
|
|
@@ -51,4 +51,14 @@ describe('MimeUtils', () => {
|
|
|
51
51
|
expect(getNormalizedCodec('dvh1.05')).toBe('dovi');
|
|
52
52
|
expect(getNormalizedCodec('dvhe.05')).toBe('dovi');
|
|
53
53
|
});
|
|
54
|
+
|
|
55
|
+
it('isHlsType', () => {
|
|
56
|
+
const isHlsType = (mimeType) => shaka.util.MimeUtils.isHlsType(mimeType);
|
|
57
|
+
|
|
58
|
+
expect(isHlsType('application/x-mpegurl')).toBe(true);
|
|
59
|
+
expect(isHlsType('application/vnd.apple.mpegurl')).toBe(true);
|
|
60
|
+
expect(isHlsType('application/dash+xml')).toBe(false);
|
|
61
|
+
expect(isHlsType('application/vnd.ms-sstr+xml')).toBe(false);
|
|
62
|
+
expect(isHlsType('foo')).toBe(false);
|
|
63
|
+
});
|
|
54
64
|
});
|