shaka-player 4.1.1 → 4.2.0
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 +67 -15
- package/.github/workflows/compute-incremental-coverage.py +251 -0
- package/.github/workflows/report-incremental-coverage.yaml +39 -0
- package/.github/workflows/selenium-lab-tests.yaml +44 -1
- package/AUTHORS +1 -0
- package/CHANGELOG.md +36 -8
- package/CONTRIBUTORS +3 -0
- package/README.md +20 -6
- package/demo/common/assets.js +25 -0
- package/demo/common/message_ids.js +2 -0
- package/demo/config.js +5 -1
- package/demo/index.html +1 -3
- package/demo/locales/en.json +2 -0
- package/demo/locales/source.json +8 -0
- package/dist/controls.css +1 -1
- package/dist/demo.compiled.debug.js +25 -23
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +25 -23
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +6 -5
- package/dist/locales.js +30 -30
- package/dist/receiver.compiled.debug.js +24 -22
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +24 -22
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +69 -5
- package/dist/shaka-player.compiled.debug.d.ts +69 -5
- package/dist/shaka-player.compiled.debug.externs.js +111 -42
- package/dist/shaka-player.compiled.debug.js +352 -301
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +111 -42
- package/dist/shaka-player.compiled.js +823 -802
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +69 -5
- package/dist/shaka-player.ui.debug.d.ts +69 -5
- package/dist/shaka-player.ui.debug.externs.js +111 -42
- package/dist/shaka-player.ui.debug.js +360 -310
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +111 -42
- package/dist/shaka-player.ui.js +980 -957
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/fairplay.md +149 -0
- package/docs/tutorials/ui.md +6 -6
- package/docs/tutorials/upgrade.md +1 -0
- package/docs/tutorials/welcome.md +6 -3
- package/externs/shaka/abr_manager.js +8 -0
- package/externs/shaka/manifest.js +43 -0
- package/externs/shaka/player.js +13 -2
- package/karma.conf.js +3 -11
- package/lib/abr/simple_abr_manager.js +72 -4
- package/lib/ads/client_side_ad_manager.js +1 -1
- package/lib/dash/dash_parser.js +5 -0
- package/lib/hls/hls_parser.js +123 -27
- package/lib/media/drm_engine.js +1 -3
- package/lib/media/media_source_engine.js +57 -24
- package/lib/media/presentation_timeline.js +24 -1
- package/lib/media/segment_index.js +8 -0
- package/lib/media/segment_reference.js +7 -1
- package/lib/media/streaming_engine.js +42 -6
- package/lib/media/time_ranges_utils.js +46 -0
- package/lib/net/networking_engine.js +1 -0
- package/lib/player.js +8 -6
- package/lib/polyfill/media_capabilities.js +9 -0
- package/lib/polyfill/patchedmediakeys_apple.js +729 -0
- package/lib/polyfill/videoplaybackquality.js +3 -1
- package/lib/text/cue.js +0 -5
- package/lib/text/simple_text_displayer.js +21 -9
- package/lib/text/ui_text_displayer.js +83 -19
- package/lib/text/vtt_text_parser.js +61 -4
- package/lib/util/buffer_utils.js +3 -0
- package/lib/util/error.js +21 -1
- package/lib/util/fairplay_utils.js +100 -2
- package/lib/util/object_utils.js +1 -0
- package/lib/util/platform.js +30 -1
- package/lib/util/player_configuration.js +3 -10
- package/lib/util/stream_utils.js +23 -3
- package/lib/util/string_utils.js +102 -13
- package/maintained-branches.md +15 -0
- package/package.json +3 -5
- package/shaka-player.uncompiled.js +1 -0
- package/test/hls/hls_parser_unit.js +49 -33
- package/test/media/drm_engine_integration.js +24 -8
- package/test/media/media_source_engine_integration.js +24 -10
- package/test/media/media_source_engine_unit.js +53 -38
- package/test/media/streaming_engine_unit.js +107 -32
- package/test/test/util/fake_media_source_engine.js +10 -9
- package/test/test/util/simple_fakes.js +4 -0
- package/test/test/util/streaming_engine_util.js +10 -2
- package/test/text/simple_text_displayer_unit.js +27 -0
- package/test/text/ui_text_displayer_unit.js +65 -0
- package/test/text/vtt_text_parser_unit.js +26 -0
- package/test/util/string_utils_unit.js +46 -8
- package/ui/text_selection.js +2 -2
- package/app-engine/README.md +0 -9
- package/app-engine/demo-version-index/README.md +0 -14
- package/app-engine/demo-version-index/app.yaml +0 -28
- package/app-engine/demo-version-index/generate.py +0 -164
- package/app-engine/demo-version-index/main.py +0 -11
- package/app-engine/demo-version-index/requirements.txt +0 -5
- package/app-engine/demo-version-index/templates/index.html +0 -114
- package/app-engine/shaka-player-demo/README.md +0 -18
- package/app-engine/shaka-player-demo/app.yaml +0 -61
- package/app-engine/shaka-player-demo/main.py +0 -95
- package/app-engine/shaka-player-demo/posters/10yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/10yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/1yo.jpg +0 -0
- package/app-engine/shaka-player-demo/posters/2yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/2yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/3yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/3yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/4yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/4yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/5yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/5yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/6yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/6yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/7yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/7yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/8yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/8yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/9yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/9yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/audioOnly.gif +0 -0
- package/app-engine/shaka-player-demo/posters/audioRickRoll.gif +0 -0
- package/app-engine/shaka-player-demo/posters/colorbars.gif +0 -0
- package/app-engine/shaka-player-demo/posters/fireworks.jpg +0 -0
- package/app-engine/shaka-player-demo/posters/party-hat.png +0 -0
- package/app-engine/shaka-player-demo/posters/sources.txt +0 -46
- package/app-engine/shaka-player-demo/posters/standard.png +0 -0
- package/app-engine/shaka-player-demo/posters/trek.jpg +0 -0
- package/app-engine/shaka-player-demo/posters/valentines.png +0 -0
- package/app-engine/shaka-player-demo/posters/zombie.jpg +0 -0
- package/app-engine/shaka-player-demo/posters.py +0 -110
- package/app-engine/shaka-player-demo/requirements.txt +0 -5
- package/app-engine/shaka-player-demo/time.txt +0 -1
- package/build/README.md +0 -127
- package/build/__init__.py +0 -0
- package/build/all.py +0 -150
- package/build/apps.py +0 -186
- package/build/build.py +0 -392
- package/build/check.py +0 -354
- package/build/checkversion.py +0 -84
- package/build/compiler.py +0 -513
- package/build/conformance.textproto +0 -335
- package/build/docker/Dockerfile +0 -20
- package/build/docker/docker-compose.yml +0 -10
- package/build/docs.py +0 -54
- package/build/eslint-plugin-shaka-rules/arg-comment-spacing.js +0 -72
- package/build/eslint-plugin-shaka-rules/index.js +0 -24
- package/build/eslint-plugin-shaka-rules/package.json +0 -7
- package/build/eslint-plugin-shaka-rules/private.js +0 -109
- package/build/gendeps.py +0 -71
- package/build/generateExterns.js +0 -867
- package/build/generateLocalizations.py +0 -262
- package/build/generateTsDefs.py +0 -137
- package/build/install-linux-prereqs.sh +0 -136
- package/build/license-header +0 -5
- package/build/misspellings.txt +0 -39
- package/build/pixelsChanged.js +0 -35
- package/build/shaka-lab.yaml +0 -161
- package/build/shakaBuildHelpers.py +0 -356
- package/build/stats.py +0 -816
- package/build/subprocessWindowsPatch.py +0 -103
- package/build/test.py +0 -541
- package/build/types/ads +0 -8
- package/build/types/cast +0 -6
- package/build/types/cea +0 -13
- package/build/types/complete +0 -9
- package/build/types/core +0 -108
- package/build/types/dash +0 -8
- package/build/types/hls +0 -9
- package/build/types/manifests +0 -5
- package/build/types/networking +0 -6
- package/build/types/offline +0 -22
- package/build/types/polyfill +0 -18
- package/build/types/text +0 -11
- package/build/types/ui +0 -39
- package/build/updateScreenshots.py +0 -85
- package/build/wrapper.template.js +0 -52
|
@@ -346,7 +346,7 @@ describe('MediaSourceEngine', () => {
|
|
|
346
346
|
|
|
347
347
|
it('appends the given data', async () => {
|
|
348
348
|
const p = mediaSourceEngine.appendBuffer(
|
|
349
|
-
ContentType.AUDIO, buffer, null,
|
|
349
|
+
ContentType.AUDIO, buffer, null,
|
|
350
350
|
/* hasClosedCaptions= */ false);
|
|
351
351
|
expect(audioSourceBuffer.appendBuffer).toHaveBeenCalledWith(buffer);
|
|
352
352
|
audioSourceBuffer.updateend();
|
|
@@ -363,7 +363,7 @@ describe('MediaSourceEngine', () => {
|
|
|
363
363
|
jasmine.objectContaining({message: 'fail!'})));
|
|
364
364
|
await expectAsync(
|
|
365
365
|
mediaSourceEngine.appendBuffer(
|
|
366
|
-
ContentType.AUDIO, buffer, null,
|
|
366
|
+
ContentType.AUDIO, buffer, null,
|
|
367
367
|
/* hasClosedCaptions= */ false))
|
|
368
368
|
.toBeRejectedWith(expected);
|
|
369
369
|
expect(audioSourceBuffer.appendBuffer).toHaveBeenCalledWith(buffer);
|
|
@@ -382,7 +382,7 @@ describe('MediaSourceEngine', () => {
|
|
|
382
382
|
ContentType.AUDIO));
|
|
383
383
|
await expectAsync(
|
|
384
384
|
mediaSourceEngine.appendBuffer(
|
|
385
|
-
ContentType.AUDIO, buffer, null,
|
|
385
|
+
ContentType.AUDIO, buffer, null,
|
|
386
386
|
/* hasClosedCaptions= */ false))
|
|
387
387
|
.toBeRejectedWith(expected);
|
|
388
388
|
expect(audioSourceBuffer.appendBuffer).toHaveBeenCalledWith(buffer);
|
|
@@ -403,10 +403,10 @@ describe('MediaSourceEngine', () => {
|
|
|
403
403
|
ContentType.AUDIO));
|
|
404
404
|
|
|
405
405
|
const p1 = mediaSourceEngine.appendBuffer(
|
|
406
|
-
ContentType.AUDIO, buffer, null,
|
|
406
|
+
ContentType.AUDIO, buffer, null,
|
|
407
407
|
/* hasClosedCaptions= */ false);
|
|
408
408
|
const p2 = mediaSourceEngine.appendBuffer(
|
|
409
|
-
ContentType.AUDIO, buffer, null,
|
|
409
|
+
ContentType.AUDIO, buffer, null,
|
|
410
410
|
/* hasClosedCaptions= */ false);
|
|
411
411
|
audioSourceBuffer.updateend();
|
|
412
412
|
await expectAsync(p1).toBeResolved();
|
|
@@ -416,7 +416,7 @@ describe('MediaSourceEngine', () => {
|
|
|
416
416
|
it('rejects the promise if this operation fails async', async () => {
|
|
417
417
|
mockVideo.error = {code: 5};
|
|
418
418
|
const p = mediaSourceEngine.appendBuffer(
|
|
419
|
-
ContentType.AUDIO, buffer, null,
|
|
419
|
+
ContentType.AUDIO, buffer, null,
|
|
420
420
|
/* hasClosedCaptions= */ false);
|
|
421
421
|
audioSourceBuffer.error();
|
|
422
422
|
audioSourceBuffer.updateend();
|
|
@@ -433,11 +433,11 @@ describe('MediaSourceEngine', () => {
|
|
|
433
433
|
it('queues operations on a single SourceBuffer', async () => {
|
|
434
434
|
/** @type {!shaka.test.StatusPromise} */
|
|
435
435
|
const p1 = new shaka.test.StatusPromise(mediaSourceEngine.appendBuffer(
|
|
436
|
-
ContentType.AUDIO, buffer, null,
|
|
436
|
+
ContentType.AUDIO, buffer, null,
|
|
437
437
|
/* hasClosedCaptions= */ false));
|
|
438
438
|
/** @type {!shaka.test.StatusPromise} */
|
|
439
439
|
const p2 = new shaka.test.StatusPromise(mediaSourceEngine.appendBuffer(
|
|
440
|
-
ContentType.AUDIO, buffer2, null,
|
|
440
|
+
ContentType.AUDIO, buffer2, null,
|
|
441
441
|
/* hasClosedCaptions= */ false));
|
|
442
442
|
|
|
443
443
|
expect(audioSourceBuffer.appendBuffer).toHaveBeenCalledWith(buffer);
|
|
@@ -456,15 +456,15 @@ describe('MediaSourceEngine', () => {
|
|
|
456
456
|
it('queues operations independently for different types', async () => {
|
|
457
457
|
/** @type {!shaka.test.StatusPromise} */
|
|
458
458
|
const p1 = new shaka.test.StatusPromise(mediaSourceEngine.appendBuffer(
|
|
459
|
-
ContentType.AUDIO, buffer, null,
|
|
459
|
+
ContentType.AUDIO, buffer, null,
|
|
460
460
|
/* hasClosedCaptions= */ false));
|
|
461
461
|
/** @type {!shaka.test.StatusPromise} */
|
|
462
462
|
const p2 = new shaka.test.StatusPromise(mediaSourceEngine.appendBuffer(
|
|
463
|
-
ContentType.AUDIO, buffer2, null,
|
|
463
|
+
ContentType.AUDIO, buffer2, null,
|
|
464
464
|
/* hasClosedCaptions= */ false));
|
|
465
465
|
/** @type {!shaka.test.StatusPromise} */
|
|
466
466
|
const p3 = new shaka.test.StatusPromise(mediaSourceEngine.appendBuffer(
|
|
467
|
-
ContentType.VIDEO, buffer3, null,
|
|
467
|
+
ContentType.VIDEO, buffer3, null,
|
|
468
468
|
/* hasClosedCaptions= */ false));
|
|
469
469
|
|
|
470
470
|
expect(audioSourceBuffer.appendBuffer).toHaveBeenCalledWith(buffer);
|
|
@@ -499,13 +499,13 @@ describe('MediaSourceEngine', () => {
|
|
|
499
499
|
});
|
|
500
500
|
|
|
501
501
|
const p1 = mediaSourceEngine.appendBuffer(
|
|
502
|
-
ContentType.AUDIO, buffer, null,
|
|
502
|
+
ContentType.AUDIO, buffer, null,
|
|
503
503
|
/* hasClosedCaptions= */ false);
|
|
504
504
|
const p2 = mediaSourceEngine.appendBuffer(
|
|
505
|
-
ContentType.AUDIO, buffer2, null,
|
|
505
|
+
ContentType.AUDIO, buffer2, null,
|
|
506
506
|
/* hasClosedCaptions= */ false);
|
|
507
507
|
const p3 = mediaSourceEngine.appendBuffer(
|
|
508
|
-
ContentType.AUDIO, buffer3, null,
|
|
508
|
+
ContentType.AUDIO, buffer3, null,
|
|
509
509
|
/* hasClosedCaptions= */ false);
|
|
510
510
|
|
|
511
511
|
await expectAsync(p1).toBeResolved();
|
|
@@ -519,8 +519,9 @@ describe('MediaSourceEngine', () => {
|
|
|
519
519
|
it('forwards to TextEngine', async () => {
|
|
520
520
|
const data = new ArrayBuffer(0);
|
|
521
521
|
expect(mockTextEngine.appendBuffer).not.toHaveBeenCalled();
|
|
522
|
+
const reference = dummyReference(0, 10);
|
|
522
523
|
await mediaSourceEngine.appendBuffer(
|
|
523
|
-
ContentType.TEXT, data,
|
|
524
|
+
ContentType.TEXT, data, reference, /* hasClosedCaptions= */ false);
|
|
524
525
|
expect(mockTextEngine.appendBuffer).toHaveBeenCalledWith(
|
|
525
526
|
data, 0, 10);
|
|
526
527
|
});
|
|
@@ -538,7 +539,7 @@ describe('MediaSourceEngine', () => {
|
|
|
538
539
|
const init = async () => {
|
|
539
540
|
await mediaSourceEngine.init(initObject, false);
|
|
540
541
|
await mediaSourceEngine.appendBuffer(
|
|
541
|
-
ContentType.VIDEO, buffer, null,
|
|
542
|
+
ContentType.VIDEO, buffer, null,
|
|
542
543
|
/* hasClosedCaptions= */ false);
|
|
543
544
|
expect(mockTextEngine.storeAndAppendClosedCaptions).toHaveBeenCalled();
|
|
544
545
|
expect(videoSourceBuffer.appendBuffer).toHaveBeenCalled();
|
|
@@ -568,7 +569,7 @@ describe('MediaSourceEngine', () => {
|
|
|
568
569
|
const init = async () => {
|
|
569
570
|
await mediaSourceEngine.init(initObject, false);
|
|
570
571
|
await mediaSourceEngine.appendBuffer(
|
|
571
|
-
ContentType.VIDEO, buffer, null,
|
|
572
|
+
ContentType.VIDEO, buffer, null,
|
|
572
573
|
/* hasClosedCaptions= */ false);
|
|
573
574
|
expect(mockTextEngine.storeAndAppendClosedCaptions)
|
|
574
575
|
.not.toHaveBeenCalled();
|
|
@@ -599,7 +600,8 @@ describe('MediaSourceEngine', () => {
|
|
|
599
600
|
|
|
600
601
|
// Initialize the closed caption parser.
|
|
601
602
|
const appendInit = mediaSourceEngine.appendBuffer(
|
|
602
|
-
ContentType.VIDEO, buffer, null,
|
|
603
|
+
ContentType.VIDEO, buffer, null,
|
|
604
|
+
/* hasClosedCaptions= */ true);
|
|
603
605
|
// In MediaSourceEngine, appendBuffer() is async and Promise-based, but
|
|
604
606
|
// at the browser level, it's event-based.
|
|
605
607
|
// MediaSourceEngine waits for the 'updateend' event from the
|
|
@@ -612,8 +614,9 @@ describe('MediaSourceEngine', () => {
|
|
|
612
614
|
expect(mockTextEngine.storeAndAppendClosedCaptions).not
|
|
613
615
|
.toHaveBeenCalled();
|
|
614
616
|
// Parse and append the closed captions embedded in video stream.
|
|
617
|
+
const reference = dummyReference(0, 1000);
|
|
615
618
|
const appendVideo = mediaSourceEngine.appendBuffer(
|
|
616
|
-
ContentType.VIDEO, buffer,
|
|
619
|
+
ContentType.VIDEO, buffer, reference, true);
|
|
617
620
|
videoSourceBuffer.updateend();
|
|
618
621
|
await appendVideo;
|
|
619
622
|
|
|
@@ -837,11 +840,11 @@ describe('MediaSourceEngine', () => {
|
|
|
837
840
|
it('waits for all previous operations to complete', async () => {
|
|
838
841
|
/** @type {!shaka.test.StatusPromise} */
|
|
839
842
|
const p1 = new shaka.test.StatusPromise(mediaSourceEngine.appendBuffer(
|
|
840
|
-
ContentType.AUDIO, buffer, null,
|
|
843
|
+
ContentType.AUDIO, buffer, null,
|
|
841
844
|
/* hasClosedCaptions= */ false));
|
|
842
845
|
/** @type {!shaka.test.StatusPromise} */
|
|
843
846
|
const p2 = new shaka.test.StatusPromise(mediaSourceEngine.appendBuffer(
|
|
844
|
-
ContentType.VIDEO, buffer, null,
|
|
847
|
+
ContentType.VIDEO, buffer, null,
|
|
845
848
|
/* hasClosedCaptions= */ false));
|
|
846
849
|
/** @type {!shaka.test.StatusPromise} */
|
|
847
850
|
const p3 = new shaka.test.StatusPromise(mediaSourceEngine.endOfStream());
|
|
@@ -864,11 +867,11 @@ describe('MediaSourceEngine', () => {
|
|
|
864
867
|
it('makes subsequent operations wait', async () => {
|
|
865
868
|
/** @type {!Promise} */
|
|
866
869
|
const p1 = mediaSourceEngine.endOfStream();
|
|
867
|
-
mediaSourceEngine.appendBuffer(ContentType.AUDIO, buffer, null,
|
|
870
|
+
mediaSourceEngine.appendBuffer(ContentType.AUDIO, buffer, null,
|
|
868
871
|
/* hasClosedCaptions= */ false);
|
|
869
|
-
mediaSourceEngine.appendBuffer(ContentType.VIDEO, buffer, null,
|
|
872
|
+
mediaSourceEngine.appendBuffer(ContentType.VIDEO, buffer, null,
|
|
870
873
|
/* hasClosedCaptions= */ false);
|
|
871
|
-
mediaSourceEngine.appendBuffer(ContentType.VIDEO, buffer2, null,
|
|
874
|
+
mediaSourceEngine.appendBuffer(ContentType.VIDEO, buffer2, null,
|
|
872
875
|
/* hasClosedCaptions= */ false);
|
|
873
876
|
|
|
874
877
|
// endOfStream hasn't been called yet because blocking multiple queues
|
|
@@ -896,7 +899,7 @@ describe('MediaSourceEngine', () => {
|
|
|
896
899
|
mockMediaSource.endOfStream.and.throwError(new Error());
|
|
897
900
|
/** @type {!Promise} */
|
|
898
901
|
const p1 = mediaSourceEngine.endOfStream();
|
|
899
|
-
mediaSourceEngine.appendBuffer(ContentType.AUDIO, buffer, null,
|
|
902
|
+
mediaSourceEngine.appendBuffer(ContentType.AUDIO, buffer, null,
|
|
900
903
|
/* hasClosedCaptions= */ false);
|
|
901
904
|
|
|
902
905
|
expect(audioSourceBuffer.appendBuffer).not.toHaveBeenCalled();
|
|
@@ -928,11 +931,11 @@ describe('MediaSourceEngine', () => {
|
|
|
928
931
|
it('waits for all previous operations to complete', async () => {
|
|
929
932
|
/** @type {!shaka.test.StatusPromise} */
|
|
930
933
|
const p1 = new shaka.test.StatusPromise(mediaSourceEngine.appendBuffer(
|
|
931
|
-
ContentType.AUDIO, buffer, null,
|
|
934
|
+
ContentType.AUDIO, buffer, null,
|
|
932
935
|
/* hasClosedCaptions= */ false));
|
|
933
936
|
/** @type {!shaka.test.StatusPromise} */
|
|
934
937
|
const p2 = new shaka.test.StatusPromise(mediaSourceEngine.appendBuffer(
|
|
935
|
-
ContentType.VIDEO, buffer, null,
|
|
938
|
+
ContentType.VIDEO, buffer, null,
|
|
936
939
|
/* hasClosedCaptions= */ false));
|
|
937
940
|
/** @type {!shaka.test.StatusPromise} */
|
|
938
941
|
const p3 =
|
|
@@ -956,11 +959,11 @@ describe('MediaSourceEngine', () => {
|
|
|
956
959
|
it('makes subsequent operations wait', async () => {
|
|
957
960
|
/** @type {!Promise} */
|
|
958
961
|
const p1 = mediaSourceEngine.setDuration(100);
|
|
959
|
-
mediaSourceEngine.appendBuffer(ContentType.AUDIO, buffer, null,
|
|
962
|
+
mediaSourceEngine.appendBuffer(ContentType.AUDIO, buffer, null,
|
|
960
963
|
/* hasClosedCaptions= */ false);
|
|
961
|
-
mediaSourceEngine.appendBuffer(ContentType.VIDEO, buffer, null,
|
|
964
|
+
mediaSourceEngine.appendBuffer(ContentType.VIDEO, buffer, null,
|
|
962
965
|
/* hasClosedCaptions= */ false);
|
|
963
|
-
mediaSourceEngine.appendBuffer(ContentType.VIDEO, buffer2, null,
|
|
966
|
+
mediaSourceEngine.appendBuffer(ContentType.VIDEO, buffer2, null,
|
|
964
967
|
/* hasClosedCaptions= */ false);
|
|
965
968
|
|
|
966
969
|
// The setter hasn't been called yet because blocking multiple queues
|
|
@@ -989,7 +992,7 @@ describe('MediaSourceEngine', () => {
|
|
|
989
992
|
mockMediaSource.durationSetter.and.throwError(new Error());
|
|
990
993
|
/** @type {!Promise} */
|
|
991
994
|
const p1 = mediaSourceEngine.setDuration(100);
|
|
992
|
-
mediaSourceEngine.appendBuffer(ContentType.AUDIO, buffer, null,
|
|
995
|
+
mediaSourceEngine.appendBuffer(ContentType.AUDIO, buffer, null,
|
|
993
996
|
/* hasClosedCaptions= */ false);
|
|
994
997
|
|
|
995
998
|
expect(audioSourceBuffer.appendBuffer).not.toHaveBeenCalled();
|
|
@@ -1013,9 +1016,9 @@ describe('MediaSourceEngine', () => {
|
|
|
1013
1016
|
});
|
|
1014
1017
|
|
|
1015
1018
|
it('waits for all operations to complete', async () => {
|
|
1016
|
-
mediaSourceEngine.appendBuffer(ContentType.AUDIO, buffer, null,
|
|
1019
|
+
mediaSourceEngine.appendBuffer(ContentType.AUDIO, buffer, null,
|
|
1017
1020
|
/* hasClosedCaptions= */ false);
|
|
1018
|
-
mediaSourceEngine.appendBuffer(ContentType.VIDEO, buffer, null,
|
|
1021
|
+
mediaSourceEngine.appendBuffer(ContentType.VIDEO, buffer, null,
|
|
1019
1022
|
/* hasClosedCaptions= */ false);
|
|
1020
1023
|
|
|
1021
1024
|
/** @type {!shaka.test.StatusPromise} */
|
|
@@ -1033,7 +1036,7 @@ describe('MediaSourceEngine', () => {
|
|
|
1033
1036
|
|
|
1034
1037
|
it('resolves even when a pending operation fails', async () => {
|
|
1035
1038
|
const p = mediaSourceEngine.appendBuffer(
|
|
1036
|
-
ContentType.AUDIO, buffer, null,
|
|
1039
|
+
ContentType.AUDIO, buffer, null,
|
|
1037
1040
|
/* hasClosedCaptions= */ false);
|
|
1038
1041
|
const d = mediaSourceEngine.destroy();
|
|
1039
1042
|
|
|
@@ -1058,10 +1061,10 @@ describe('MediaSourceEngine', () => {
|
|
|
1058
1061
|
|
|
1059
1062
|
it('cancels operations that have not yet started', async () => {
|
|
1060
1063
|
mediaSourceEngine.appendBuffer(
|
|
1061
|
-
ContentType.AUDIO, buffer, null,
|
|
1064
|
+
ContentType.AUDIO, buffer, null,
|
|
1062
1065
|
/* hasClosedCaptions= */ false);
|
|
1063
1066
|
const rejected = mediaSourceEngine.appendBuffer(
|
|
1064
|
-
ContentType.AUDIO, buffer2, null,
|
|
1067
|
+
ContentType.AUDIO, buffer2, null,
|
|
1065
1068
|
/* hasClosedCaptions= */ false);
|
|
1066
1069
|
// Create the expectation first so we don't get unhandled rejection errors
|
|
1067
1070
|
const expected = expectAsync(rejected).toBeRejected();
|
|
@@ -1085,7 +1088,7 @@ describe('MediaSourceEngine', () => {
|
|
|
1085
1088
|
|
|
1086
1089
|
it('cancels blocking operations that have not yet started', async () => {
|
|
1087
1090
|
const p1 = mediaSourceEngine.appendBuffer(
|
|
1088
|
-
ContentType.AUDIO, buffer, null,
|
|
1091
|
+
ContentType.AUDIO, buffer, null,
|
|
1089
1092
|
/* hasClosedCaptions= */ false);
|
|
1090
1093
|
const p2 = mediaSourceEngine.endOfStream();
|
|
1091
1094
|
const d = mediaSourceEngine.destroy();
|
|
@@ -1100,7 +1103,7 @@ describe('MediaSourceEngine', () => {
|
|
|
1100
1103
|
const d = mediaSourceEngine.destroy();
|
|
1101
1104
|
await expectAsync(
|
|
1102
1105
|
mediaSourceEngine.appendBuffer(
|
|
1103
|
-
ContentType.AUDIO, buffer, null,
|
|
1106
|
+
ContentType.AUDIO, buffer, null,
|
|
1104
1107
|
/* hasClosedCaptions= */ false))
|
|
1105
1108
|
.toBeRejected();
|
|
1106
1109
|
await d;
|
|
@@ -1198,4 +1201,16 @@ describe('MediaSourceEngine', () => {
|
|
|
1198
1201
|
}
|
|
1199
1202
|
});
|
|
1200
1203
|
}
|
|
1204
|
+
|
|
1205
|
+
function dummyReference(startTime, endTime) {
|
|
1206
|
+
return new shaka.media.SegmentReference(
|
|
1207
|
+
startTime, endTime,
|
|
1208
|
+
/* uris= */ () => ['foo://bar'],
|
|
1209
|
+
/* startByte= */ 0,
|
|
1210
|
+
/* endByte= */ null,
|
|
1211
|
+
/* initSegmentReference= */ null,
|
|
1212
|
+
/* timestampOffset= */ 0,
|
|
1213
|
+
/* appendWindowStart= */ 0,
|
|
1214
|
+
/* appendWindowEnd= */ Infinity);
|
|
1215
|
+
}
|
|
1201
1216
|
});
|
|
@@ -100,10 +100,13 @@ describe('StreamingEngine', () => {
|
|
|
100
100
|
jasmine.clock().mockDate();
|
|
101
101
|
});
|
|
102
102
|
|
|
103
|
-
/**
|
|
103
|
+
/**
|
|
104
|
+
* @param {boolean=} trickMode
|
|
104
105
|
* @param {number=} mediaOffset The offset from 0 for the segment start times
|
|
106
|
+
* @param {shaka.extern.HlsAes128Key=} hlsAes128Key The AES-128 key to put in
|
|
107
|
+
* the manifest, if one should exist
|
|
105
108
|
*/
|
|
106
|
-
function setupVod(trickMode, mediaOffset) {
|
|
109
|
+
function setupVod(trickMode, mediaOffset, hlsAes128Key) {
|
|
107
110
|
// For VOD, we fake a presentation that has 2 Periods of equal duration
|
|
108
111
|
// (20 seconds), where each Period has 1 Variant and 1 text stream.
|
|
109
112
|
//
|
|
@@ -209,7 +212,8 @@ describe('StreamingEngine', () => {
|
|
|
209
212
|
setupManifest(
|
|
210
213
|
/* firstPeriodStartTime= */ 0,
|
|
211
214
|
/* secondPeriodStartTime= */ 20,
|
|
212
|
-
/* presentationDuration= */ 40
|
|
215
|
+
/* presentationDuration= */ 40,
|
|
216
|
+
hlsAes128Key);
|
|
213
217
|
}
|
|
214
218
|
|
|
215
219
|
function setupLive() {
|
|
@@ -356,8 +360,15 @@ describe('StreamingEngine', () => {
|
|
|
356
360
|
/* delays= */ netEngineDelays);
|
|
357
361
|
}
|
|
358
362
|
|
|
363
|
+
/**
|
|
364
|
+
* @param {number} firstPeriodStartTime
|
|
365
|
+
* @param {number} secondPeriodStartTime
|
|
366
|
+
* @param {number} presentationDuration
|
|
367
|
+
* @param {shaka.extern.HlsAes128Key=} hlsAes128Key
|
|
368
|
+
*/
|
|
359
369
|
function setupManifest(
|
|
360
|
-
firstPeriodStartTime, secondPeriodStartTime, presentationDuration
|
|
370
|
+
firstPeriodStartTime, secondPeriodStartTime, presentationDuration,
|
|
371
|
+
hlsAes128Key) {
|
|
361
372
|
const segmentDurations = {
|
|
362
373
|
audio: segmentData[ContentType.AUDIO].segmentDuration,
|
|
363
374
|
video: segmentData[ContentType.VIDEO].segmentDuration,
|
|
@@ -380,7 +391,7 @@ describe('StreamingEngine', () => {
|
|
|
380
391
|
/** @type {!shaka.media.PresentationTimeline} */(timeline),
|
|
381
392
|
[firstPeriodStartTime, secondPeriodStartTime],
|
|
382
393
|
presentationDuration, segmentDurations, initSegmentRanges,
|
|
383
|
-
timestampOffsets);
|
|
394
|
+
timestampOffsets, hlsAes128Key);
|
|
384
395
|
|
|
385
396
|
audioStream = manifest.variants[0].audio;
|
|
386
397
|
videoStream = manifest.variants[0].video;
|
|
@@ -868,9 +879,9 @@ describe('StreamingEngine', () => {
|
|
|
868
879
|
netEngineDelays.audio = 1.0;
|
|
869
880
|
netEngineDelays.video = 5.0; // Need init segment and media segment
|
|
870
881
|
|
|
871
|
-
mediaSourceEngine.appendBuffer.and.callFake((type, data,
|
|
882
|
+
mediaSourceEngine.appendBuffer.and.callFake((type, data, reference) => {
|
|
872
883
|
// Call to the underlying implementation.
|
|
873
|
-
const p = mediaSourceEngine.appendBufferImpl(type, data,
|
|
884
|
+
const p = mediaSourceEngine.appendBufferImpl(type, data, reference);
|
|
874
885
|
|
|
875
886
|
// Validate that no one media type got ahead of any other.
|
|
876
887
|
let minBuffered = Infinity;
|
|
@@ -1012,8 +1023,8 @@ describe('StreamingEngine', () => {
|
|
|
1012
1023
|
|
|
1013
1024
|
const bufferEnd = {audio: 0, video: 0, text: 0};
|
|
1014
1025
|
mediaSourceEngine.appendBuffer.and.callFake(
|
|
1015
|
-
(type, data,
|
|
1016
|
-
bufferEnd[type] =
|
|
1026
|
+
(type, data, reference) => {
|
|
1027
|
+
bufferEnd[type] = reference && reference.endTime;
|
|
1017
1028
|
return Promise.resolve();
|
|
1018
1029
|
});
|
|
1019
1030
|
mediaSourceEngine.bufferEnd.and.callFake((type) => {
|
|
@@ -1080,9 +1091,9 @@ describe('StreamingEngine', () => {
|
|
|
1080
1091
|
// Replace the whole spy since we want to call the original.
|
|
1081
1092
|
mediaSourceEngine.appendBuffer =
|
|
1082
1093
|
jasmine.createSpy('appendBuffer')
|
|
1083
|
-
.and.callFake(async (type, data,
|
|
1094
|
+
.and.callFake(async (type, data, reference) => {
|
|
1084
1095
|
await p;
|
|
1085
|
-
return Util.invokeSpy(old, type, data,
|
|
1096
|
+
return Util.invokeSpy(old, type, data, reference);
|
|
1086
1097
|
});
|
|
1087
1098
|
|
|
1088
1099
|
await streamingEngine.start();
|
|
@@ -1107,9 +1118,9 @@ describe('StreamingEngine', () => {
|
|
|
1107
1118
|
// Replace the whole spy since we want to call the original.
|
|
1108
1119
|
mediaSourceEngine.appendBuffer =
|
|
1109
1120
|
jasmine.createSpy('appendBuffer')
|
|
1110
|
-
.and.callFake(async (type, data,
|
|
1121
|
+
.and.callFake(async (type, data, reference) => {
|
|
1111
1122
|
await p;
|
|
1112
|
-
return Util.invokeSpy(old, type, data,
|
|
1123
|
+
return Util.invokeSpy(old, type, data, reference);
|
|
1113
1124
|
});
|
|
1114
1125
|
|
|
1115
1126
|
await streamingEngine.start();
|
|
@@ -1750,9 +1761,9 @@ describe('StreamingEngine', () => {
|
|
|
1750
1761
|
// eslint-disable-next-line no-restricted-syntax
|
|
1751
1762
|
shaka.test.FakeMediaSourceEngine.prototype.appendBufferImpl;
|
|
1752
1763
|
mediaSourceEngine.appendBuffer.and.callFake(
|
|
1753
|
-
(type, data,
|
|
1764
|
+
(type, data, reference) => {
|
|
1754
1765
|
expect(presentationTimeInSeconds).toBe(125);
|
|
1755
|
-
if (startTime >= 100) {
|
|
1766
|
+
if (reference && reference.startTime >= 100) {
|
|
1756
1767
|
// Ignore a possible call for the first Period.
|
|
1757
1768
|
expect(Util.invokeSpy(timeline.getSegmentAvailabilityStart))
|
|
1758
1769
|
.toBe(100);
|
|
@@ -1765,7 +1776,7 @@ describe('StreamingEngine', () => {
|
|
|
1765
1776
|
|
|
1766
1777
|
// eslint-disable-next-line no-restricted-syntax
|
|
1767
1778
|
return originalAppendBuffer.call(
|
|
1768
|
-
mediaSourceEngine, type, data,
|
|
1779
|
+
mediaSourceEngine, type, data, reference);
|
|
1769
1780
|
});
|
|
1770
1781
|
|
|
1771
1782
|
await runTest(slideSegmentAvailabilityWindow);
|
|
@@ -1862,14 +1873,14 @@ describe('StreamingEngine', () => {
|
|
|
1862
1873
|
// eslint-disable-next-line no-restricted-syntax
|
|
1863
1874
|
shaka.test.FakeMediaSourceEngine.prototype.appendBufferImpl;
|
|
1864
1875
|
mediaSourceEngine.appendBuffer.and.callFake(
|
|
1865
|
-
(type, data,
|
|
1876
|
+
(type, data, reference) => {
|
|
1866
1877
|
// Reject the first video init segment.
|
|
1867
1878
|
if (data == segmentData[ContentType.VIDEO].initSegments[0]) {
|
|
1868
1879
|
return Promise.reject(expectedError);
|
|
1869
1880
|
} else {
|
|
1870
1881
|
// eslint-disable-next-line no-restricted-syntax
|
|
1871
1882
|
return originalAppendBuffer.call(
|
|
1872
|
-
mediaSourceEngine, type, data,
|
|
1883
|
+
mediaSourceEngine, type, data, reference);
|
|
1873
1884
|
}
|
|
1874
1885
|
});
|
|
1875
1886
|
|
|
@@ -1896,14 +1907,14 @@ describe('StreamingEngine', () => {
|
|
|
1896
1907
|
// eslint-disable-next-line no-restricted-syntax
|
|
1897
1908
|
shaka.test.FakeMediaSourceEngine.prototype.appendBufferImpl;
|
|
1898
1909
|
mediaSourceEngine.appendBuffer.and.callFake(
|
|
1899
|
-
(type, data,
|
|
1910
|
+
(type, data, reference) => {
|
|
1900
1911
|
// Reject the first audio segment.
|
|
1901
1912
|
if (data == segmentData[ContentType.AUDIO].segments[0]) {
|
|
1902
1913
|
return Promise.reject(expectedError);
|
|
1903
1914
|
} else {
|
|
1904
1915
|
// eslint-disable-next-line no-restricted-syntax
|
|
1905
1916
|
return originalAppendBuffer.call(
|
|
1906
|
-
mediaSourceEngine, type, data,
|
|
1917
|
+
mediaSourceEngine, type, data, reference);
|
|
1907
1918
|
}
|
|
1908
1919
|
});
|
|
1909
1920
|
|
|
@@ -2187,7 +2198,7 @@ describe('StreamingEngine', () => {
|
|
|
2187
2198
|
// Now that we're streaming, throw QuotaExceededError on every segment
|
|
2188
2199
|
// to quickly trigger the quota error.
|
|
2189
2200
|
const appendBufferSpy = jasmine.createSpy('appendBuffer');
|
|
2190
|
-
appendBufferSpy.and.callFake((type, data,
|
|
2201
|
+
appendBufferSpy.and.callFake((type, data, reference) => {
|
|
2191
2202
|
throw new shaka.util.Error(
|
|
2192
2203
|
shaka.util.Error.Severity.CRITICAL,
|
|
2193
2204
|
shaka.util.Error.Category.MEDIA,
|
|
@@ -2373,9 +2384,10 @@ describe('StreamingEngine', () => {
|
|
|
2373
2384
|
// Throw two QuotaExceededErrors at different times.
|
|
2374
2385
|
let numErrorsThrown = 0;
|
|
2375
2386
|
appendBufferSpy.and.callFake(
|
|
2376
|
-
(type, data,
|
|
2377
|
-
const throwError =
|
|
2378
|
-
|
|
2387
|
+
(type, data, reference) => {
|
|
2388
|
+
const throwError = reference &&
|
|
2389
|
+
((numErrorsThrown == 0 && reference.startTime == 10) ||
|
|
2390
|
+
(numErrorsThrown == 1 && reference.startTime == 20));
|
|
2379
2391
|
if (throwError) {
|
|
2380
2392
|
numErrorsThrown++;
|
|
2381
2393
|
throw new shaka.util.Error(
|
|
@@ -2386,7 +2398,7 @@ describe('StreamingEngine', () => {
|
|
|
2386
2398
|
} else {
|
|
2387
2399
|
// eslint-disable-next-line no-restricted-syntax
|
|
2388
2400
|
const p = originalAppendBuffer.call(
|
|
2389
|
-
mediaSourceEngine, type, data,
|
|
2401
|
+
mediaSourceEngine, type, data, reference);
|
|
2390
2402
|
return p;
|
|
2391
2403
|
}
|
|
2392
2404
|
});
|
|
@@ -2435,8 +2447,8 @@ describe('StreamingEngine', () => {
|
|
|
2435
2447
|
// Throw QuotaExceededError multiple times after at least one segment of
|
|
2436
2448
|
// each type has been appended.
|
|
2437
2449
|
appendBufferSpy.and.callFake(
|
|
2438
|
-
(type, data,
|
|
2439
|
-
if (startTime >= 10) {
|
|
2450
|
+
(type, data, reference) => {
|
|
2451
|
+
if (reference && reference.startTime >= 10) {
|
|
2440
2452
|
throw new shaka.util.Error(
|
|
2441
2453
|
shaka.util.Error.Severity.CRITICAL,
|
|
2442
2454
|
shaka.util.Error.Category.MEDIA,
|
|
@@ -2445,7 +2457,7 @@ describe('StreamingEngine', () => {
|
|
|
2445
2457
|
} else {
|
|
2446
2458
|
// eslint-disable-next-line no-restricted-syntax
|
|
2447
2459
|
const p = originalAppendBuffer.call(
|
|
2448
|
-
mediaSourceEngine, type, data,
|
|
2460
|
+
mediaSourceEngine, type, data, reference);
|
|
2449
2461
|
return p;
|
|
2450
2462
|
}
|
|
2451
2463
|
});
|
|
@@ -2986,8 +2998,8 @@ describe('StreamingEngine', () => {
|
|
|
2986
2998
|
|
|
2987
2999
|
// Naive buffered range tracking that only tracks the buffer end.
|
|
2988
3000
|
const bufferEnd = {audio: 0, video: 0, text: 0};
|
|
2989
|
-
mediaSourceEngine.appendBuffer.and.callFake((type, data,
|
|
2990
|
-
bufferEnd[type] =
|
|
3001
|
+
mediaSourceEngine.appendBuffer.and.callFake((type, data, reference) => {
|
|
3002
|
+
bufferEnd[type] = reference && reference.endTime;
|
|
2991
3003
|
return Promise.resolve();
|
|
2992
3004
|
});
|
|
2993
3005
|
mediaSourceEngine.bufferEnd.and.callFake((type) => bufferEnd[type]);
|
|
@@ -3281,8 +3293,8 @@ describe('StreamingEngine', () => {
|
|
|
3281
3293
|
|
|
3282
3294
|
const bufferEnd = {audio: 0, video: 0, text: 0};
|
|
3283
3295
|
mediaSourceEngine.appendBuffer.and.callFake(
|
|
3284
|
-
(type, data,
|
|
3285
|
-
bufferEnd[type] =
|
|
3296
|
+
(type, data, reference) => {
|
|
3297
|
+
bufferEnd[type] = reference && reference.endTime;
|
|
3286
3298
|
return Promise.resolve();
|
|
3287
3299
|
});
|
|
3288
3300
|
mediaSourceEngine.bufferEnd.and.callFake((type) => {
|
|
@@ -3429,6 +3441,69 @@ describe('StreamingEngine', () => {
|
|
|
3429
3441
|
expect(alternateVideoStream.createSegmentIndex).not.toHaveBeenCalled();
|
|
3430
3442
|
});
|
|
3431
3443
|
|
|
3444
|
+
describe('AES-128', () => {
|
|
3445
|
+
let key;
|
|
3446
|
+
/** @type {!shaka.extern.HlsAes128Key} */
|
|
3447
|
+
let hlsAes128Key;
|
|
3448
|
+
|
|
3449
|
+
beforeEach(async () => {
|
|
3450
|
+
// Get a key.
|
|
3451
|
+
const keyData = new ArrayBuffer(16);
|
|
3452
|
+
const keyDataView = new DataView(keyData);
|
|
3453
|
+
keyDataView.setInt16(0, 31710); // 0111 1011 1101 1110
|
|
3454
|
+
key = await window.crypto.subtle.importKey(
|
|
3455
|
+
'raw', keyData, 'AES-CBC', true, ['decrypt']);
|
|
3456
|
+
|
|
3457
|
+
// Set up a manifest with AES-128 key info.
|
|
3458
|
+
// We don't actually provide the imported key OR the key fetching function
|
|
3459
|
+
// here, though, so that the individual tests can choose what the starting
|
|
3460
|
+
// state of the hlsAes128Key object is.
|
|
3461
|
+
hlsAes128Key = {method: 'AES-128', firstMediaSequenceNumber: 0};
|
|
3462
|
+
|
|
3463
|
+
setupVod(false, 0, hlsAes128Key);
|
|
3464
|
+
mediaSourceEngine = new shaka.test.FakeMediaSourceEngine(segmentData);
|
|
3465
|
+
presentationTimeInSeconds = 0;
|
|
3466
|
+
createStreamingEngine();
|
|
3467
|
+
streamingEngine.switchVariant(variant);
|
|
3468
|
+
});
|
|
3469
|
+
|
|
3470
|
+
afterEach(async () => {
|
|
3471
|
+
await streamingEngine.destroy();
|
|
3472
|
+
});
|
|
3473
|
+
|
|
3474
|
+
async function runTest() {
|
|
3475
|
+
spyOn(window.crypto.subtle, 'decrypt').and.callThrough();
|
|
3476
|
+
|
|
3477
|
+
await streamingEngine.start();
|
|
3478
|
+
playing = true;
|
|
3479
|
+
await Util.fakeEventLoop(10);
|
|
3480
|
+
|
|
3481
|
+
expect(mediaSourceEngine.appendBuffer).toHaveBeenCalledTimes(2);
|
|
3482
|
+
expect(window.crypto.subtle.decrypt).toHaveBeenCalledTimes(2);
|
|
3483
|
+
expect(window.crypto.subtle.decrypt).toHaveBeenCalledWith(
|
|
3484
|
+
{name: 'AES-CBC', iv: jasmine.any(Object)}, key, jasmine.any(Object));
|
|
3485
|
+
}
|
|
3486
|
+
|
|
3487
|
+
it('decrypts segments', async () => {
|
|
3488
|
+
hlsAes128Key.cryptoKey = key;
|
|
3489
|
+
await runTest();
|
|
3490
|
+
});
|
|
3491
|
+
|
|
3492
|
+
it('downloads key if not pre-filled', async () => {
|
|
3493
|
+
hlsAes128Key.fetchKey = () => {
|
|
3494
|
+
hlsAes128Key.cryptoKey = key;
|
|
3495
|
+
hlsAes128Key.fetchKey = undefined;
|
|
3496
|
+
return Promise.resolve();
|
|
3497
|
+
};
|
|
3498
|
+
|
|
3499
|
+
await runTest();
|
|
3500
|
+
|
|
3501
|
+
// The key should have been fetched.
|
|
3502
|
+
expect(hlsAes128Key.cryptoKey).not.toBeUndefined();
|
|
3503
|
+
expect(hlsAes128Key.fetchKey).toBeUndefined();
|
|
3504
|
+
});
|
|
3505
|
+
});
|
|
3506
|
+
|
|
3432
3507
|
describe('destroy', () => {
|
|
3433
3508
|
it('aborts pending network operations', async () => {
|
|
3434
3509
|
setupVod();
|
|
@@ -78,8 +78,8 @@ shaka.test.FakeMediaSourceEngine = class {
|
|
|
78
78
|
|
|
79
79
|
/** @type {!jasmine.Spy} */
|
|
80
80
|
this.appendBuffer = jasmine.createSpy('appendBuffer')
|
|
81
|
-
.and.callFake((type, data,
|
|
82
|
-
this.appendBufferImpl(type, data,
|
|
81
|
+
.and.callFake((type, data, reference) =>
|
|
82
|
+
this.appendBufferImpl(type, data, reference));
|
|
83
83
|
|
|
84
84
|
/** @type {!jasmine.Spy} */
|
|
85
85
|
this.clear = jasmine.createSpy('clear')
|
|
@@ -229,11 +229,10 @@ shaka.test.FakeMediaSourceEngine = class {
|
|
|
229
229
|
/**
|
|
230
230
|
* @param {string} type
|
|
231
231
|
* @param {!ArrayBuffer} data
|
|
232
|
-
* @param {?
|
|
233
|
-
* @param {?number} endTime
|
|
232
|
+
* @param {?shaka.media.SegmentReference} reference
|
|
234
233
|
* @return {!Promise}
|
|
235
234
|
*/
|
|
236
|
-
appendBufferImpl(type, data,
|
|
235
|
+
appendBufferImpl(type, data, reference) {
|
|
237
236
|
if (!this.segments[type]) {
|
|
238
237
|
throw new Error('unexpected type');
|
|
239
238
|
}
|
|
@@ -257,8 +256,7 @@ shaka.test.FakeMediaSourceEngine = class {
|
|
|
257
256
|
}
|
|
258
257
|
if (i >= 0) {
|
|
259
258
|
// Update the list of which init segment was appended last.
|
|
260
|
-
expect(
|
|
261
|
-
expect(endTime).toBe(null);
|
|
259
|
+
expect(reference).toBe(null);
|
|
262
260
|
this.initSegments[type] =
|
|
263
261
|
this.segmentData[type].initSegments.map((c) => false);
|
|
264
262
|
this.initSegments[type][i] = true;
|
|
@@ -289,8 +287,11 @@ shaka.test.FakeMediaSourceEngine = class {
|
|
|
289
287
|
const expectedStartTime = i * segmentData.segmentDuration;
|
|
290
288
|
const expectedEndTime = expectedStartTime + segmentData.segmentDuration;
|
|
291
289
|
expect(appendedTime).toBe(expectedStartTime);
|
|
292
|
-
expect(
|
|
293
|
-
|
|
290
|
+
expect(reference).not.toBe(null);
|
|
291
|
+
if (reference) {
|
|
292
|
+
expect(reference.startTime).toBe(expectedStartTime);
|
|
293
|
+
expect(reference.endTime).toBe(expectedEndTime);
|
|
294
|
+
}
|
|
294
295
|
|
|
295
296
|
this.segments[type][i] = true;
|
|
296
297
|
return Promise.resolve();
|
|
@@ -481,6 +481,10 @@ shaka.test.FakeSegmentIndex = class {
|
|
|
481
481
|
return this.get(nextPosition - 1);
|
|
482
482
|
},
|
|
483
483
|
|
|
484
|
+
currentPosition: () => {
|
|
485
|
+
return nextPosition;
|
|
486
|
+
},
|
|
487
|
+
|
|
484
488
|
seek: (time) => {
|
|
485
489
|
nextPosition = this.find(time);
|
|
486
490
|
return this.get(nextPosition++);
|