shaka-player 4.3.5 → 4.3.7
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/demo-version-index.yaml +3 -3
- package/.github/workflows/selenium-lab-tests.yaml +23 -1
- package/AUTHORS +2 -1
- package/CHANGELOG.md +53 -0
- package/CONTRIBUTORS +4 -1
- package/README.md +3 -0
- package/demo/demo.less +1 -0
- package/dist/controls.css +2 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +167 -296
- package/dist/demo.compiled.debug.map +4 -4
- package/dist/demo.compiled.js +167 -296
- package/dist/demo.compiled.map +4 -4
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +1 -1
- package/dist/locales.js +32 -32
- package/dist/receiver.compiled.debug.js +34 -63
- package/dist/receiver.compiled.debug.map +4 -4
- package/dist/receiver.compiled.js +34 -63
- package/dist/receiver.compiled.map +4 -4
- package/dist/shaka-player.compiled.d.ts +20 -3
- package/dist/shaka-player.compiled.debug.d.ts +20 -3
- package/dist/shaka-player.compiled.debug.externs.js +29 -14
- package/dist/shaka-player.compiled.debug.js +303 -292
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +29 -14
- package/dist/shaka-player.compiled.js +886 -879
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.d.ts +20 -3
- package/dist/shaka-player.ui.debug.d.ts +20 -3
- package/dist/shaka-player.ui.debug.externs.js +17 -2
- package/dist/shaka-player.ui.debug.js +321 -309
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.externs.js +17 -2
- package/dist/shaka-player.ui.js +1027 -1021
- 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/fairplay.md +2 -2
- 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 +1 -6
- 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 +6 -3
- package/lib/cea/mp4_cea_parser.js +5 -2
- package/lib/dash/dash_parser.js +49 -48
- package/lib/debug/log.js +9 -13
- package/lib/hls/hls_parser.js +60 -7
- package/lib/hls/manifest_text_parser.js +10 -1
- package/lib/media/drm_engine.js +9 -6
- package/lib/media/media_source_engine.js +33 -13
- package/lib/media/presentation_timeline.js +9 -2
- package/lib/media/segment_index.js +2 -0
- package/lib/media/segment_reference.js +25 -2
- package/lib/media/streaming_engine.js +40 -11
- package/lib/net/http_fetch_plugin.js +79 -57
- package/lib/net/networking_engine.js +1 -0
- package/lib/player.js +26 -3
- package/lib/polyfill/media_capabilities.js +13 -0
- package/lib/text/mp4_vtt_parser.js +4 -0
- package/lib/text/text_engine.js +1 -0
- package/lib/util/manifest_parser_utils.js +1 -2
- package/lib/util/mime_utils.js +11 -0
- package/lib/util/periods.js +5 -5
- package/lib/util/stream_utils.js +2 -2
- package/maintained-branches.md +2 -3
- package/package.json +8 -3
- package/test/cea/mp4_cea_parser_unit.js +19 -0
- package/test/dash/dash_parser_live_unit.js +3 -2
- package/test/hls/hls_live_unit.js +3 -1
- package/test/hls/hls_parser_unit.js +156 -0
- package/test/media/content_workarounds_unit.js +43 -0
- package/test/media/drm_engine_integration.js +4 -17
- package/test/media/media_source_engine_unit.js +30 -0
- 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 +1 -0
- package/test/test/assets/h265-cea-init.mp4 +0 -0
- package/test/test/assets/h265-cea-segment.mp4 +0 -0
- package/test/test/assets/text-clip-alt.vtt +63 -0
- package/test/test/util/fake_drm_engine.js +3 -0
- package/test/test/util/fake_media_source_engine.js +4 -0
- package/test/test/util/layout_tests.js +4 -3
- 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/util/mime_utils_unit.js +10 -0
- package/ui/less/containers.less +4 -0
|
@@ -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
|
});
|
|
@@ -171,9 +171,12 @@ describe('MediaSourceEngine', () => {
|
|
|
171
171
|
describe('constructor', () => {
|
|
172
172
|
const originalCreateObjectURL =
|
|
173
173
|
shaka.media.MediaSourceEngine.createObjectURL;
|
|
174
|
+
const originalRevokeObjectURL = window.URL.revokeObjectURL;
|
|
174
175
|
const originalMediaSource = window.MediaSource;
|
|
175
176
|
/** @type {jasmine.Spy} */
|
|
176
177
|
let createObjectURLSpy;
|
|
178
|
+
/** @type {jasmine.Spy} */
|
|
179
|
+
let revokeObjectURLSpy;
|
|
177
180
|
|
|
178
181
|
beforeEach(async () => {
|
|
179
182
|
// Mock out MediaSource so we can test the production version of
|
|
@@ -188,6 +191,9 @@ describe('MediaSourceEngine', () => {
|
|
|
188
191
|
shaka.media.MediaSourceEngine.createObjectURL =
|
|
189
192
|
Util.spyFunc(createObjectURLSpy);
|
|
190
193
|
|
|
194
|
+
revokeObjectURLSpy = jasmine.createSpy('revokeObjectURL');
|
|
195
|
+
window.URL.revokeObjectURL = Util.spyFunc(revokeObjectURLSpy);
|
|
196
|
+
|
|
191
197
|
const mediaSourceSpy = jasmine.createSpy('MediaSource');
|
|
192
198
|
// Because this is a fake constructor, it must be callable with "new".
|
|
193
199
|
// This will cause jasmine to invoke the callback with "new" as well, so
|
|
@@ -205,6 +211,7 @@ describe('MediaSourceEngine', () => {
|
|
|
205
211
|
afterAll(() => {
|
|
206
212
|
shaka.media.MediaSourceEngine.createObjectURL = originalCreateObjectURL;
|
|
207
213
|
window.MediaSource = originalMediaSource;
|
|
214
|
+
window.URL.revokeObjectURL = originalRevokeObjectURL;
|
|
208
215
|
});
|
|
209
216
|
|
|
210
217
|
it('creates a MediaSource object and sets video.src', () => {
|
|
@@ -216,6 +223,29 @@ describe('MediaSourceEngine', () => {
|
|
|
216
223
|
expect(createObjectURLSpy).toHaveBeenCalled();
|
|
217
224
|
expect(mockVideo.src).toBe('blob:foo');
|
|
218
225
|
});
|
|
226
|
+
|
|
227
|
+
it('revokes object URL after MediaSource opens', () => {
|
|
228
|
+
let onSourceOpenListener;
|
|
229
|
+
|
|
230
|
+
mockMediaSource.addEventListener.and.callFake((event, callback, _) => {
|
|
231
|
+
if (event == 'sourceopen') {
|
|
232
|
+
onSourceOpenListener = callback;
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
mediaSourceEngine = new shaka.media.MediaSourceEngine(
|
|
237
|
+
video,
|
|
238
|
+
new shaka.test.FakeTextDisplayer());
|
|
239
|
+
|
|
240
|
+
expect(mockMediaSource.addEventListener).toHaveBeenCalledTimes(1);
|
|
241
|
+
expect(mockMediaSource.addEventListener.calls.mostRecent().args[0])
|
|
242
|
+
.toBe('sourceopen');
|
|
243
|
+
expect(typeof onSourceOpenListener).toBe(typeof Function);
|
|
244
|
+
|
|
245
|
+
onSourceOpenListener();
|
|
246
|
+
|
|
247
|
+
expect(revokeObjectURLSpy).toHaveBeenCalledWith('blob:foo');
|
|
248
|
+
});
|
|
219
249
|
});
|
|
220
250
|
|
|
221
251
|
describe('init', () => {
|
|
@@ -3412,7 +3412,12 @@ describe('StreamingEngine', () => {
|
|
|
3412
3412
|
netEngine.request.and.callFake((requestType, request) => {
|
|
3413
3413
|
const buffer = new ArrayBuffer(0);
|
|
3414
3414
|
/** @type {shaka.extern.Response} */
|
|
3415
|
-
const response = {
|
|
3415
|
+
const response = {
|
|
3416
|
+
uri: request.uris[0],
|
|
3417
|
+
originalUri: request.uris[0],
|
|
3418
|
+
data: buffer,
|
|
3419
|
+
headers: {},
|
|
3420
|
+
};
|
|
3416
3421
|
return shaka.util.AbortableOperation.completed(response);
|
|
3417
3422
|
});
|
|
3418
3423
|
|
|
@@ -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')
|
|
@@ -319,6 +319,45 @@ describe('Player', () => {
|
|
|
319
319
|
player.setTextTrackVisibility(true);
|
|
320
320
|
expect(getTracksActive()).toEqual([false, true]);
|
|
321
321
|
});
|
|
322
|
+
|
|
323
|
+
// https://github.com/shaka-project/shaka-player/issues/4821
|
|
324
|
+
it('loads a single text stream', async () => {
|
|
325
|
+
player.configure({preferredTextLanguage: 'en'});
|
|
326
|
+
await player.load('test:sintel_no_text_compiled');
|
|
327
|
+
|
|
328
|
+
// Add preferred language text track.
|
|
329
|
+
const locationUri = new goog.Uri(location.href);
|
|
330
|
+
const partialUri = new goog.Uri('/base/test/test/assets/text-clip.vtt');
|
|
331
|
+
const absoluteUri = locationUri.resolve(partialUri);
|
|
332
|
+
await player.addTextTrackAsync(
|
|
333
|
+
absoluteUri.toString(), 'en', 'subtitles', 'text/vtt');
|
|
334
|
+
|
|
335
|
+
// Add alternate language text track.
|
|
336
|
+
// Two text tracks with same timings but different text
|
|
337
|
+
// are necessary for test.
|
|
338
|
+
const partialUri2 =
|
|
339
|
+
new goog.Uri('/base/test/test/assets/text-clip-alt.vtt');
|
|
340
|
+
const absoluteUri2 = locationUri.resolve(partialUri2);
|
|
341
|
+
await player.addTextTrackAsync(
|
|
342
|
+
absoluteUri2.toString(), 'fr', 'subtitles', 'text/vtt');
|
|
343
|
+
|
|
344
|
+
const textTracks = player.getTextTracks();
|
|
345
|
+
expect(textTracks.length).toBe(2);
|
|
346
|
+
expect(textTracks[0].language).toBe('en');
|
|
347
|
+
expect(textTracks[1].language).toBe('fr');
|
|
348
|
+
|
|
349
|
+
// Enable text visibilty and immediately change language.
|
|
350
|
+
// Only one set of cues should be active.
|
|
351
|
+
// Cues should be of the selected language track.
|
|
352
|
+
player.setTextTrackVisibility(true);
|
|
353
|
+
player.selectTextLanguage('fr');
|
|
354
|
+
video.currentTime = 5;
|
|
355
|
+
video.play();
|
|
356
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
357
|
+
|
|
358
|
+
expect(video.textTracks[0].activeCues.length).toBe(1);
|
|
359
|
+
expect(player.getTextTracks()[1].active).toBe(true);
|
|
360
|
+
});
|
|
322
361
|
}); // describe('setTextTrackVisibility')
|
|
323
362
|
|
|
324
363
|
describe('autoShowText', () => {
|
package/test/player_unit.js
CHANGED
|
@@ -208,6 +208,7 @@ describe('Player', () => {
|
|
|
208
208
|
await player.destroy();
|
|
209
209
|
|
|
210
210
|
expect(abrManager.stop).toHaveBeenCalled();
|
|
211
|
+
expect(abrManager.release).toHaveBeenCalled();
|
|
211
212
|
expect(networkingEngine.destroy).toHaveBeenCalled();
|
|
212
213
|
expect(drmEngine.destroy).toHaveBeenCalled();
|
|
213
214
|
expect(playhead.release).toHaveBeenCalled();
|
|
@@ -246,6 +247,7 @@ describe('Player', () => {
|
|
|
246
247
|
parser.start.and.returnValue(p);
|
|
247
248
|
parser.stop.and.callFake(() => {
|
|
248
249
|
expect(abrManager.stop).not.toHaveBeenCalled();
|
|
250
|
+
expect(abrManager.release).not.toHaveBeenCalled();
|
|
249
251
|
expect(networkingEngine.destroy).not.toHaveBeenCalled();
|
|
250
252
|
});
|
|
251
253
|
shaka.media.ManifestParser.registerParserByMime(
|
|
@@ -255,6 +257,7 @@ describe('Player', () => {
|
|
|
255
257
|
await shaka.test.Util.shortDelay();
|
|
256
258
|
await player.destroy();
|
|
257
259
|
expect(abrManager.stop).toHaveBeenCalled();
|
|
260
|
+
expect(abrManager.release).toHaveBeenCalled();
|
|
258
261
|
expect(networkingEngine.destroy).toHaveBeenCalled();
|
|
259
262
|
expect(parser.stop).toHaveBeenCalled();
|
|
260
263
|
await expectAsync(load).toBeRejected();
|
|
@@ -554,6 +557,60 @@ describe('Player', () => {
|
|
|
554
557
|
expect(streamingEngine.unloadTextStream).not.toHaveBeenCalled();
|
|
555
558
|
});
|
|
556
559
|
});
|
|
560
|
+
|
|
561
|
+
describe('when config.streaming.preferNativeHls is set to true', () => {
|
|
562
|
+
beforeEach(() => {
|
|
563
|
+
shaka.media.ManifestParser.registerParserByMime(
|
|
564
|
+
'application/x-mpegurl',
|
|
565
|
+
() => new shaka.test.FakeManifestParser(manifest));
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
afterEach(() => {
|
|
569
|
+
shaka.media.ManifestParser.unregisterParserByMime(
|
|
570
|
+
'application/x-mpegurl');
|
|
571
|
+
video.canPlayType.calls.reset();
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
it('only applies to HLS streams', async () => {
|
|
575
|
+
video.canPlayType.and.returnValue('maybe');
|
|
576
|
+
spyOn(shaka.util.Platform, 'anyMediaElement').and.returnValue(video);
|
|
577
|
+
spyOn(shaka.util.Platform, 'supportsMediaSource').and.returnValue(true);
|
|
578
|
+
spyOn(shaka.util.Platform, 'isApple').and.returnValue(false);
|
|
579
|
+
// Make sure player.load() resolves for src=
|
|
580
|
+
spyOn(shaka.util.MediaReadyState, 'waitForReadyState').and.callFake(
|
|
581
|
+
(mediaElement, readyState, eventManager, callback) => {
|
|
582
|
+
callback();
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
player.configure({
|
|
586
|
+
streaming: {
|
|
587
|
+
preferNativeHls: true,
|
|
588
|
+
useNativeHlsOnSafari: false,
|
|
589
|
+
},
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
await player.load(fakeManifestUri, undefined, 'application/x-mpegurl');
|
|
593
|
+
|
|
594
|
+
expect(player.getLoadMode()).toBe(shaka.Player.LoadMode.SRC_EQUALS);
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
it('does not apply to non-HLS streams', async () => {
|
|
598
|
+
video.canPlayType.and.returnValue('maybe');
|
|
599
|
+
spyOn(shaka.util.Platform, 'supportsMediaSource').and.returnValue(true);
|
|
600
|
+
spyOn(shaka.util.Platform, 'isApple').and.returnValue(false);
|
|
601
|
+
|
|
602
|
+
player.configure({
|
|
603
|
+
streaming: {
|
|
604
|
+
preferNativeHls: true,
|
|
605
|
+
useNativeHlsOnSafari: false,
|
|
606
|
+
},
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
await player.load(fakeManifestUri, 0, fakeMimeType);
|
|
610
|
+
|
|
611
|
+
expect(player.getLoadMode()).toBe(shaka.Player.LoadMode.MEDIA_SOURCE);
|
|
612
|
+
});
|
|
613
|
+
});
|
|
557
614
|
}); // describe('load/unload')
|
|
558
615
|
|
|
559
616
|
describe('getConfiguration', () => {
|
|
@@ -69,6 +69,7 @@ describe('MediaCapabilities', () => {
|
|
|
69
69
|
},
|
|
70
70
|
};
|
|
71
71
|
shaka.polyfill.MediaCapabilities.memoizedMediaKeySystemAccessRequests_ = {};
|
|
72
|
+
supportMap.clear();
|
|
72
73
|
|
|
73
74
|
mockCanDisplayType = jasmine.createSpy('canDisplayType');
|
|
74
75
|
mockCanDisplayType.and.returnValue(false);
|
|
Binary file
|
|
Binary file
|
|
@@ -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
|
/**
|
|
@@ -136,6 +136,10 @@ shaka.test.FakeMediaSourceEngine = class {
|
|
|
136
136
|
/** @type {!jasmine.Spy} */
|
|
137
137
|
this.updateLcevcDil =
|
|
138
138
|
jasmine.createSpy('updateLcevcDil').and.stub();
|
|
139
|
+
|
|
140
|
+
/** @type {!jasmine.Spy} */
|
|
141
|
+
this.resync=
|
|
142
|
+
jasmine.createSpy('resync').and.stub();
|
|
139
143
|
}
|
|
140
144
|
|
|
141
145
|
/** @override */
|
|
@@ -43,9 +43,10 @@ shaka.test.LayoutTests = class {
|
|
|
43
43
|
});
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
// Wait one extra
|
|
47
|
-
// updated. Without this, we saw some rare test flake in Firefox on
|
|
48
|
-
|
|
46
|
+
// Wait one extra second to make sure the font rendering on the page has
|
|
47
|
+
// been updated. Without this, we saw some rare test flake in Firefox on
|
|
48
|
+
// Mac.
|
|
49
|
+
await shaka.test.Util.delay(1);
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
/**
|
|
@@ -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
|
|
|
@@ -455,6 +455,7 @@ const widevineDrmServers = {
|
|
|
455
455
|
|
|
456
456
|
/** @type {AVMetadataType} */
|
|
457
457
|
const axinomMultiDrmVideoSegment = {
|
|
458
|
+
// Taken from Axinom's v6 test vector.
|
|
458
459
|
initSegmentUri: '/base/test/test/assets/multidrm-video-init.mp4',
|
|
459
460
|
mdhdOffset: 0x1d1,
|
|
460
461
|
segmentUri: '/base/test/test/assets/multidrm-video-segment.mp4',
|
|
@@ -469,6 +470,7 @@ const axinomMultiDrmVideoSegment = {
|
|
|
469
470
|
|
|
470
471
|
/** @type {AVMetadataType} */
|
|
471
472
|
const axinomMultiDrmAudioSegment = {
|
|
473
|
+
// Taken from Axinom's v6 test vector.
|
|
472
474
|
initSegmentUri: '/base/test/test/assets/multidrm-audio-init.mp4',
|
|
473
475
|
mdhdOffset: 0x192,
|
|
474
476
|
segmentUri: '/base/test/test/assets/multidrm-audio-segment.mp4',
|
|
@@ -483,20 +485,15 @@ const axinomMultiDrmAudioSegment = {
|
|
|
483
485
|
|
|
484
486
|
/** @type {!Object.<string, string>} */
|
|
485
487
|
const axinomDrmServers = {
|
|
488
|
+
// NOTE: These are not Axinom's actual servers. These are test servers for
|
|
489
|
+
// Widevine and PlayReady that let us specify the known key IDs and keys for
|
|
490
|
+
// Axinom's v6 test vectors. Axinom's own servers started returning 403
|
|
491
|
+
// errors for these older test vectors, and we were forced to switch to
|
|
492
|
+
// something stable and independent.
|
|
486
493
|
'com.widevine.alpha':
|
|
487
|
-
'https://
|
|
494
|
+
'https://cwip-shaka-proxy.appspot.com/specific_key?blodJidXR9eARuql0dNLWg=GX8m9XLIZNIzizrl0RTqnA',
|
|
488
495
|
'com.microsoft.playready':
|
|
489
|
-
'https://
|
|
490
|
-
};
|
|
491
|
-
|
|
492
|
-
/** @type {!Object.<string, string>} */
|
|
493
|
-
const axinomDrmHeaders = {
|
|
494
|
-
'X-AxDRM-Message':
|
|
495
|
-
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ2ZXJzaW9uIjoxLCJjb21fa2V5' +
|
|
496
|
-
'X2lkIjoiNjllNTQwODgtZTllMC00NTMwLThjMWEtMWViNmRjZDBkMTRlIiwibWVzc' +
|
|
497
|
-
'2FnZSI6eyJ0eXBlIjoiZW50aXRsZW1lbnRfbWVzc2FnZSIsImtleXMiOlt7ImlkIj' +
|
|
498
|
-
'oiNmU1YTFkMjYtMjc1Ny00N2Q3LTgwNDYtZWFhNWQxZDM0YjVhIn1dfX0.yF7PflO' +
|
|
499
|
-
'Pv9qHnu3ZWJNZ12jgkqTabmwXbDWk_47tLNE',
|
|
496
|
+
'https://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(kid:6e5a1d26-2757-47d7-8046-eaa5d1d34b5a,contentkey:GX8m9XLIZNIzizrl0RTqnA==,sl:150)',
|
|
500
497
|
};
|
|
501
498
|
|
|
502
499
|
/** @type {TextMetadataType} */
|
|
@@ -614,7 +611,6 @@ shaka.test.TestScheme.DATA = {
|
|
|
614
611
|
audio: axinomMultiDrmAudioSegment,
|
|
615
612
|
text: vttSegment,
|
|
616
613
|
licenseServers: axinomDrmServers,
|
|
617
|
-
licenseRequestHeaders: axinomDrmHeaders,
|
|
618
614
|
duration: 30,
|
|
619
615
|
},
|
|
620
616
|
|
|
@@ -626,7 +622,6 @@ shaka.test.TestScheme.DATA = {
|
|
|
626
622
|
initData: undefined,
|
|
627
623
|
}),
|
|
628
624
|
licenseServers: axinomDrmServers,
|
|
629
|
-
licenseRequestHeaders: axinomDrmHeaders,
|
|
630
625
|
duration: 30,
|
|
631
626
|
},
|
|
632
627
|
|
|
@@ -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,
|
|
@@ -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
|
});
|
package/ui/less/containers.less
CHANGED
|
@@ -103,6 +103,10 @@
|
|
|
103
103
|
* below (Y axis) .shaka-play-button-container. */
|
|
104
104
|
.shaka-canvas-container {
|
|
105
105
|
.overlay-child();
|
|
106
|
+
|
|
107
|
+
/* Make sure pointer events can reach the video element in the case of native
|
|
108
|
+
* controls. */
|
|
109
|
+
pointer-events: none;
|
|
106
110
|
}
|
|
107
111
|
|
|
108
112
|
/* Container for controls positioned at the bottom of the video container:
|