shaka-player 3.1.4 → 3.3.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/ISSUE_TEMPLATE/bug_report.md +1 -1
- package/.github/ISSUE_TEMPLATE/feature_request.md +1 -1
- package/.github/ISSUE_TEMPLATE/question.md +1 -1
- package/AUTHORS +6 -5
- package/CHANGELOG.md +363 -0
- package/CONTRIBUTORS +4 -2
- package/README.md +4 -4
- package/build/types/core +3 -0
- package/build/types/offline +1 -0
- package/build/types/polyfill +2 -0
- package/build/types/ui +2 -0
- package/demo/common/asset.js +9 -7
- package/demo/common/assets.js +28 -1
- package/demo/common/message_ids.js +15 -2
- package/demo/config.js +35 -2
- package/demo/index.html +1 -1
- package/demo/locales/en.json +14 -1
- package/demo/locales/source.json +56 -4
- package/demo/main.js +2 -1
- package/dist/controls.css +26 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +24 -21
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +24 -21
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +33 -25
- package/dist/locales.js +31 -29
- package/dist/receiver.compiled.debug.js +14 -12
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +14 -12
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +258 -20
- package/dist/shaka-player.compiled.debug.d.ts +258 -20
- package/dist/shaka-player.compiled.debug.externs.js +1005 -695
- package/dist/shaka-player.compiled.debug.js +720 -640
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +1005 -695
- package/dist/shaka-player.compiled.js +850 -817
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +274 -21
- package/dist/shaka-player.ui.debug.d.ts +274 -21
- package/dist/shaka-player.ui.debug.externs.js +766 -429
- package/dist/shaka-player.ui.debug.js +863 -765
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +766 -429
- package/dist/shaka-player.ui.js +1042 -996
- package/dist/shaka-player.ui.map +4 -4
- package/docs/design/bg-fetch-after.gv +29 -0
- package/docs/design/bg-fetch-after.gv.png +0 -0
- package/docs/design/bg-fetch-before.gv +18 -0
- package/docs/design/bg-fetch-before.gv.png +0 -0
- package/docs/design/bg-fetch.md +134 -0
- package/docs/tutorials/blob-url.md +15 -0
- package/docs/tutorials/index.json +1 -0
- package/docs/tutorials/ui-customization.md +66 -0
- package/docs/tutorials/ui.md +5 -5
- package/externs/aria.js +6 -0
- package/externs/ima.js +3 -0
- package/externs/shaka/ads.js +29 -1
- package/externs/shaka/manifest.js +18 -2
- package/externs/shaka/manifest_parser.js +10 -1
- package/externs/shaka/net.js +20 -4
- package/externs/shaka/offline.js +36 -2
- package/externs/shaka/player.js +182 -13
- package/externs/shaka/text.js +24 -10
- package/externs/texttrack.js +3 -0
- package/externs/webcrypto.js +18 -0
- package/lib/abr/ewma.js +14 -0
- package/lib/abr/ewma_bandwidth_estimator.js +16 -2
- package/lib/abr/simple_abr_manager.js +6 -0
- package/lib/ads/ad_manager.js +16 -15
- package/lib/ads/client_side_ad.js +8 -0
- package/lib/ads/client_side_ad_manager.js +14 -6
- package/lib/ads/server_side_ad.js +7 -0
- package/lib/ads/server_side_ad_manager.js +19 -2
- package/lib/cast/cast_proxy.js +8 -0
- package/lib/cast/cast_utils.js +7 -1
- package/lib/cea/cea608_data_channel.js +56 -56
- package/lib/cea/cea608_memory.js +33 -33
- package/lib/cea/cea708_service.js +43 -43
- package/lib/cea/cea708_window.js +38 -38
- package/lib/cea/cea_decoder.js +13 -14
- package/lib/cea/cea_utils.js +23 -23
- package/lib/cea/dtvcc_packet_builder.js +7 -7
- package/lib/cea/i_caption_decoder.js +2 -3
- package/lib/cea/i_cea_parser.js +2 -2
- package/lib/cea/mp4_cea_parser.js +6 -6
- package/lib/dash/dash_parser.js +53 -14
- package/lib/dash/segment_base.js +25 -1
- package/lib/dash/segment_list.js +18 -9
- package/lib/dash/segment_template.js +23 -10
- package/lib/hls/hls_parser.js +210 -30
- package/lib/media/closed_caption_parser.js +1 -2
- package/lib/media/drm_engine.js +162 -192
- package/lib/media/quality_observer.js +291 -0
- package/lib/media/segment_index.js +9 -1
- package/lib/media/segment_reference.js +37 -5
- package/lib/media/streaming_engine.js +48 -10
- package/lib/net/http_fetch_plugin.js +31 -11
- package/lib/net/http_plugin_utils.js +1 -0
- package/lib/net/http_xhr_plugin.js +40 -14
- package/lib/net/networking_engine.js +82 -18
- package/lib/offline/download_info.js +68 -0
- package/lib/offline/download_manager.js +14 -7
- package/lib/offline/indexeddb/base_storage_cell.js +35 -0
- package/lib/offline/indexeddb/storage_mechanism.js +1 -1
- package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v5_storage_cell.js +5 -0
- package/lib/offline/manifest_converter.js +3 -1
- package/lib/offline/storage.js +404 -297
- package/lib/offline/stored_content_utils.js +2 -0
- package/lib/player.js +622 -153
- package/lib/polyfill/aria.js +82 -0
- package/lib/polyfill/random_uuid.js +52 -0
- package/lib/routing/walker.js +2 -3
- package/lib/text/cue.js +12 -0
- package/lib/text/srt_text_parser.js +4 -4
- package/lib/text/text_engine.js +2 -2
- package/lib/text/ttml_text_parser.js +25 -2
- package/lib/text/ui_text_displayer.js +2 -2
- package/lib/text/vtt_text_parser.js +2 -2
- package/lib/text/web_vtt_generator.js +55 -12
- package/lib/util/cmcd_manager.js +826 -0
- package/lib/util/error.js +12 -0
- package/lib/util/language_utils.js +12 -0
- package/lib/util/manifest_parser_utils.js +1 -0
- package/lib/util/mp4_box_parsers.js +20 -20
- package/lib/util/multi_map.js +8 -0
- package/lib/util/mutex.js +52 -0
- package/lib/util/periods.js +98 -64
- package/lib/util/player_configuration.js +31 -1
- package/lib/util/stream_utils.js +140 -85
- package/lib/util/xml_utils.js +31 -12
- package/package.json +1 -1
- package/roadmap.md +24 -22
- package/shaka-player.uncompiled.js +4 -0
- package/test/cast/cast_utils_unit.js +1 -0
- package/test/cea/cea608_memory_unit.js +1 -1
- package/test/cea/cea708_service_unit.js +8 -8
- package/test/cea/cea708_window_unit.js +6 -6
- package/test/cea/cea_decoder_unit.js +1 -1
- package/test/cea/dtvcc_packet_builder_unit.js +2 -2
- package/test/dash/dash_parser_content_protection_unit.js +2 -0
- package/test/dash/dash_parser_live_unit.js +101 -1
- package/test/dash/dash_parser_manifest_unit.js +78 -2
- package/test/dash/dash_parser_segment_base_unit.js +2 -0
- package/test/dash/dash_parser_segment_list_unit.js +2 -1
- package/test/dash/dash_parser_segment_template_unit.js +2 -1
- package/test/hls/hls_live_unit.js +2 -0
- package/test/hls/hls_parser_unit.js +252 -0
- package/test/media/drm_engine_integration.js +86 -12
- package/test/media/drm_engine_unit.js +310 -450
- package/test/media/quality_observer_unit.js +139 -0
- package/test/media/segment_reference_unit.js +16 -1
- package/test/media/streaming_engine_integration.js +2 -1
- package/test/media/streaming_engine_unit.js +2 -0
- package/test/net/http_plugin_unit.js +20 -15
- package/test/offline/manifest_convert_unit.js +2 -0
- package/test/offline/storage_integration.js +117 -23
- package/test/player_integration.js +151 -0
- package/test/player_src_equals_integration.js +52 -0
- package/test/player_unit.js +11 -33
- package/test/test/assets/chapters.srt +11 -0
- package/test/test/assets/chapters.vtt +10 -0
- package/test/test/util/cea_utils.js +12 -12
- package/test/test/util/dash_parser_util.js +4 -0
- package/test/test/util/fake_ad.js +7 -0
- package/test/test/util/fake_ad_manager.js +7 -0
- package/test/test/util/fake_drm_engine.js +9 -2
- package/test/test/util/manifest_generator.js +5 -2
- package/test/test/util/manifest_parser_util.js +3 -1
- package/test/test/util/test_scheme.js +14 -1
- package/test/text/ttml_text_parser_unit.js +47 -0
- package/test/text/web_vtt_generator_unit.js +81 -7
- package/test/ui/ui_unit.js +250 -0
- package/test/util/cmcd_manager_unit.js +277 -0
- package/test/util/stream_utils_unit.js +118 -10
- package/ui/airplay_button.js +2 -1
- package/ui/audio_language_selection.js +9 -5
- package/ui/cast_button.js +5 -6
- package/ui/constants.js +0 -3
- package/ui/context_menu.js +109 -0
- package/ui/controls.js +41 -7
- package/ui/controls.less +1 -0
- package/ui/enums.js +4 -0
- package/ui/externs/ui.js +28 -1
- package/ui/fast_forward_button.js +16 -8
- package/ui/fullscreen_button.js +2 -3
- package/ui/language_utils.js +1 -1
- package/ui/less/buttons.less +0 -4
- package/ui/less/containers.less +74 -0
- package/ui/less/overflow_menu.less +0 -10
- package/ui/less/tooltip.less +97 -0
- package/ui/locales/en.json +1 -0
- package/ui/locales/source.json +4 -0
- package/ui/loop_button.js +6 -3
- package/ui/mute_button.js +3 -4
- package/ui/overflow_menu.js +7 -28
- package/ui/pip_button.js +10 -7
- package/ui/play_button.js +2 -2
- package/ui/playback_rate_selection.js +11 -15
- package/ui/presentation_time.js +1 -3
- package/ui/resolution_selection.js +11 -7
- package/ui/rewind_button.js +17 -9
- package/ui/seek_bar.js +6 -6
- package/ui/settings_menu.js +36 -4
- package/ui/small_play_button.js +1 -0
- package/ui/spacer.js +1 -1
- package/ui/statistics_button.js +253 -0
- package/ui/text_selection.js +19 -15
- package/ui/ui.js +30 -0
- package/ui/ui_utils.js +1 -1
- package/ui/volume_bar.js +2 -4
|
@@ -87,6 +87,41 @@ describe('Player', () => {
|
|
|
87
87
|
});
|
|
88
88
|
}); // describe('attach')
|
|
89
89
|
|
|
90
|
+
describe('updateStartTime() in manifestparsed event handler', () => {
|
|
91
|
+
it('does not get segments prior to startTime', async () => {
|
|
92
|
+
player.addEventListener('manifestparsed', () => {
|
|
93
|
+
player.updateStartTime(24);
|
|
94
|
+
});
|
|
95
|
+
const results = {
|
|
96
|
+
requestedVideoSegment0: false,
|
|
97
|
+
requestedVideoSegment1: false,
|
|
98
|
+
requestedVideoSegment2: false,
|
|
99
|
+
};
|
|
100
|
+
const expected = {
|
|
101
|
+
requestedVideoSegment0: false,
|
|
102
|
+
requestedVideoSegment1: false,
|
|
103
|
+
requestedVideoSegment2: true,
|
|
104
|
+
};
|
|
105
|
+
player.getNetworkingEngine().registerRequestFilter(
|
|
106
|
+
(type, request) => {
|
|
107
|
+
if (request.uris[0] == 'test:sintel/video/0') {
|
|
108
|
+
results.requestedVideoSegment0 = true;
|
|
109
|
+
}
|
|
110
|
+
if (request.uris[0] == 'test:sintel/video/1') {
|
|
111
|
+
results.requestedVideoSegment1 = true;
|
|
112
|
+
}
|
|
113
|
+
if (request.uris[0] == 'test:sintel/video/2') {
|
|
114
|
+
results.requestedVideoSegment2 = true;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
await player.load('test:sintel_compiled');
|
|
118
|
+
video.play();
|
|
119
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 25, 30);
|
|
120
|
+
expect(results).toEqual(expected);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
|
|
90
125
|
describe('getStats', () => {
|
|
91
126
|
it('gives stats about current stream', async () => {
|
|
92
127
|
// This is tested more in player_unit.js. This is here to test the public
|
|
@@ -652,6 +687,70 @@ describe('Player', () => {
|
|
|
652
687
|
});
|
|
653
688
|
});
|
|
654
689
|
|
|
690
|
+
describe('mediaQualityChanges', () => {
|
|
691
|
+
/** @type {!jasmine.Spy} */
|
|
692
|
+
let onQualityChange;
|
|
693
|
+
/** @type {!shaka.test.Waiter} */
|
|
694
|
+
let waiter;
|
|
695
|
+
|
|
696
|
+
const qualityChange1 = jasmine.objectContaining({
|
|
697
|
+
mediaQuality: jasmine.objectContaining({
|
|
698
|
+
bandwidth: 1,
|
|
699
|
+
codecs: 'mp4a.40.2',
|
|
700
|
+
contentType: 'audio',
|
|
701
|
+
mimeType: 'audio/mp4',
|
|
702
|
+
}),
|
|
703
|
+
type: 'mediaqualitychanged',
|
|
704
|
+
position: jasmine.any(Number),
|
|
705
|
+
});
|
|
706
|
+
const qualityChange2 = jasmine.objectContaining({
|
|
707
|
+
mediaQuality: jasmine.objectContaining({
|
|
708
|
+
bandwidth: 1,
|
|
709
|
+
codecs: 'avc1.42c01e',
|
|
710
|
+
contentType: 'video',
|
|
711
|
+
mimeType: 'video/mp4',
|
|
712
|
+
}),
|
|
713
|
+
type: 'mediaqualitychanged',
|
|
714
|
+
position: jasmine.any(Number),
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
beforeEach(() => {
|
|
718
|
+
onQualityChange = jasmine.createSpy('onQualityChange');
|
|
719
|
+
// const spyFunc = Util.spyFunc(onQualityChange);
|
|
720
|
+
player.addEventListener('mediaqualitychanged',
|
|
721
|
+
Util.spyFunc(onQualityChange));
|
|
722
|
+
waiter = new shaka.test.Waiter(eventManager)
|
|
723
|
+
.timeoutAfter(10)
|
|
724
|
+
.failOnTimeout(true);
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
it('emits audio/video quality changes at start when enabled', async () => {
|
|
728
|
+
player.configure('streaming.observeQualityChanges', true);
|
|
729
|
+
|
|
730
|
+
await player.load('test:sintel_compiled');
|
|
731
|
+
video.play();
|
|
732
|
+
|
|
733
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
734
|
+
// seconds, fail the test.
|
|
735
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
736
|
+
expect(onQualityChange).toHaveBeenCalledTimes(2);
|
|
737
|
+
expect(onQualityChange).toHaveBeenCalledWith(qualityChange1);
|
|
738
|
+
expect(onQualityChange).toHaveBeenCalledWith(qualityChange2);
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
it('does not emit quality changes at start when disabled', async () => {
|
|
742
|
+
player.configure('streaming.observeQualityChanges', false);
|
|
743
|
+
|
|
744
|
+
await player.load('test:sintel_compiled');
|
|
745
|
+
video.play();
|
|
746
|
+
|
|
747
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
748
|
+
// seconds, fail the test.
|
|
749
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
750
|
+
expect(onQualityChange).not.toHaveBeenCalled();
|
|
751
|
+
});
|
|
752
|
+
});
|
|
753
|
+
|
|
655
754
|
describe('seek range', () => {
|
|
656
755
|
// Regression test for Issue #3675.
|
|
657
756
|
it('has a reasonable seek range after going from live to VOD', async () => {
|
|
@@ -959,4 +1058,56 @@ describe('Player', () => {
|
|
|
959
1058
|
}
|
|
960
1059
|
});
|
|
961
1060
|
}); // describe('unloading')
|
|
1061
|
+
|
|
1062
|
+
describe('chapters', () => {
|
|
1063
|
+
it('add external chapters in vtt format', async () => {
|
|
1064
|
+
await player.load('test:sintel_no_text_compiled');
|
|
1065
|
+
const locationUri = new goog.Uri(location.href);
|
|
1066
|
+
const partialUri = new goog.Uri('/base/test/test/assets/chapters.vtt');
|
|
1067
|
+
const absoluteUri = locationUri.resolve(partialUri);
|
|
1068
|
+
await player.addChaptersTrack(absoluteUri.toString(), 'en');
|
|
1069
|
+
|
|
1070
|
+
await shaka.test.Util.delay(1.5);
|
|
1071
|
+
|
|
1072
|
+
const chapters = player.getChapters('en');
|
|
1073
|
+
expect(chapters.length).toBe(3);
|
|
1074
|
+
const chapter1 = chapters[0];
|
|
1075
|
+
expect(chapter1.title).toBe('Chapter 1');
|
|
1076
|
+
expect(chapter1.startTime).toBe(0);
|
|
1077
|
+
expect(chapter1.endTime).toBe(5);
|
|
1078
|
+
const chapter2 = chapters[1];
|
|
1079
|
+
expect(chapter2.title).toBe('Chapter 2');
|
|
1080
|
+
expect(chapter2.startTime).toBe(5);
|
|
1081
|
+
expect(chapter2.endTime).toBe(30);
|
|
1082
|
+
const chapter3 = chapters[2];
|
|
1083
|
+
expect(chapter3.title).toBe('Chapter 3');
|
|
1084
|
+
expect(chapter3.startTime).toBe(30);
|
|
1085
|
+
expect(chapter3.endTime).toBe(61.349);
|
|
1086
|
+
});
|
|
1087
|
+
|
|
1088
|
+
it('add external chapters in srt format', async () => {
|
|
1089
|
+
await player.load('test:sintel_no_text_compiled');
|
|
1090
|
+
const locationUri = new goog.Uri(location.href);
|
|
1091
|
+
const partialUri = new goog.Uri('/base/test/test/assets/chapters.srt');
|
|
1092
|
+
const absoluteUri = locationUri.resolve(partialUri);
|
|
1093
|
+
await player.addChaptersTrack(absoluteUri.toString(), 'en');
|
|
1094
|
+
|
|
1095
|
+
await shaka.test.Util.delay(1.5);
|
|
1096
|
+
|
|
1097
|
+
const chapters = player.getChapters('en');
|
|
1098
|
+
expect(chapters.length).toBe(3);
|
|
1099
|
+
const chapter1 = chapters[0];
|
|
1100
|
+
expect(chapter1.title).toBe('Chapter 1');
|
|
1101
|
+
expect(chapter1.startTime).toBe(0);
|
|
1102
|
+
expect(chapter1.endTime).toBe(5);
|
|
1103
|
+
const chapter2 = chapters[1];
|
|
1104
|
+
expect(chapter2.title).toBe('Chapter 2');
|
|
1105
|
+
expect(chapter2.startTime).toBe(5);
|
|
1106
|
+
expect(chapter2.endTime).toBe(30);
|
|
1107
|
+
const chapter3 = chapters[2];
|
|
1108
|
+
expect(chapter3.title).toBe('Chapter 3');
|
|
1109
|
+
expect(chapter3.startTime).toBe(30);
|
|
1110
|
+
expect(chapter3.endTime).toBe(61.349);
|
|
1111
|
+
});
|
|
1112
|
+
}); // describe('chapters')
|
|
962
1113
|
});
|
|
@@ -326,6 +326,58 @@ describe('Player Src Equals', () => {
|
|
|
326
326
|
expect(newTrack).toBeTruthy();
|
|
327
327
|
});
|
|
328
328
|
|
|
329
|
+
it('add external chapters in vtt format', async () => {
|
|
330
|
+
await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
|
|
331
|
+
|
|
332
|
+
const locationUri = new goog.Uri(location.href);
|
|
333
|
+
const partialUri = new goog.Uri('/base/test/test/assets/chapters.vtt');
|
|
334
|
+
const absoluteUri = locationUri.resolve(partialUri);
|
|
335
|
+
await player.addChaptersTrack(absoluteUri.toString(), 'en');
|
|
336
|
+
|
|
337
|
+
await shaka.test.Util.delay(1.5);
|
|
338
|
+
|
|
339
|
+
const chapters = player.getChapters('en');
|
|
340
|
+
expect(chapters.length).toBe(3);
|
|
341
|
+
const chapter1 = chapters[0];
|
|
342
|
+
expect(chapter1.title).toBe('Chapter 1');
|
|
343
|
+
expect(chapter1.startTime).toBe(0);
|
|
344
|
+
expect(chapter1.endTime).toBe(5);
|
|
345
|
+
const chapter2 = chapters[1];
|
|
346
|
+
expect(chapter2.title).toBe('Chapter 2');
|
|
347
|
+
expect(chapter2.startTime).toBe(5);
|
|
348
|
+
expect(chapter2.endTime).toBe(30);
|
|
349
|
+
const chapter3 = chapters[2];
|
|
350
|
+
expect(chapter3.title).toBe('Chapter 3');
|
|
351
|
+
expect(chapter3.startTime).toBe(30);
|
|
352
|
+
expect(chapter3.endTime).toBe(61.349);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
it('add external chapters in srt format', async () => {
|
|
356
|
+
await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
|
|
357
|
+
|
|
358
|
+
const locationUri = new goog.Uri(location.href);
|
|
359
|
+
const partialUri = new goog.Uri('/base/test/test/assets/chapters.srt');
|
|
360
|
+
const absoluteUri = locationUri.resolve(partialUri);
|
|
361
|
+
await player.addChaptersTrack(absoluteUri.toString(), 'en');
|
|
362
|
+
|
|
363
|
+
await shaka.test.Util.delay(1.5);
|
|
364
|
+
|
|
365
|
+
const chapters = player.getChapters('en');
|
|
366
|
+
expect(chapters.length).toBe(3);
|
|
367
|
+
const chapter1 = chapters[0];
|
|
368
|
+
expect(chapter1.title).toBe('Chapter 1');
|
|
369
|
+
expect(chapter1.startTime).toBe(0);
|
|
370
|
+
expect(chapter1.endTime).toBe(5);
|
|
371
|
+
const chapter2 = chapters[1];
|
|
372
|
+
expect(chapter2.title).toBe('Chapter 2');
|
|
373
|
+
expect(chapter2.startTime).toBe(5);
|
|
374
|
+
expect(chapter2.endTime).toBe(30);
|
|
375
|
+
const chapter3 = chapters[2];
|
|
376
|
+
expect(chapter3.title).toBe('Chapter 3');
|
|
377
|
+
expect(chapter3.startTime).toBe(30);
|
|
378
|
+
expect(chapter3.endTime).toBe(61.349);
|
|
379
|
+
});
|
|
380
|
+
|
|
329
381
|
// Since we are not in-charge of streaming, calling |retryStreaming| should
|
|
330
382
|
// have no effect.
|
|
331
383
|
it('requesting streaming retry does nothing', async () => {
|
package/test/player_unit.js
CHANGED
|
@@ -2809,16 +2809,7 @@ describe('Player', () => {
|
|
|
2809
2809
|
expect(tracks[0].id).toBe(4);
|
|
2810
2810
|
});
|
|
2811
2811
|
|
|
2812
|
-
|
|
2813
|
-
for (const useMediaCapabilities of [true, false]) {
|
|
2814
|
-
const isEnabled = useMediaCapabilities ? 'enabled' : 'disabled';
|
|
2815
|
-
it('removes if key system does not support codec with ' +
|
|
2816
|
-
'MediaCapabilities ' + isEnabled, async () => {
|
|
2817
|
-
await testWithUnsupportedCodec(useMediaCapabilities);
|
|
2818
|
-
});
|
|
2819
|
-
}
|
|
2820
|
-
|
|
2821
|
-
async function testWithUnsupportedCodec(useMediaCapabilities) {
|
|
2812
|
+
it('removes if key system does not support codec', async () => {
|
|
2822
2813
|
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
2823
2814
|
manifest.addVariant(0, (variant) => {
|
|
2824
2815
|
variant.addVideo(1, (stream) => {
|
|
@@ -2836,35 +2827,22 @@ describe('Player', () => {
|
|
|
2836
2827
|
});
|
|
2837
2828
|
});
|
|
2838
2829
|
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
if (videoType.includes('video') &&
|
|
2830
|
+
window.shakaMediaCapabilities.decodingInfo = async (config) => {
|
|
2831
|
+
await Promise.resolve();
|
|
2832
|
+
const videoType = config['video'] ? config['video'].contentType : '';
|
|
2833
|
+
if (videoType.includes('video') &&
|
|
2844
2834
|
videoType.includes('unsupported')) {
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
} else {
|
|
2851
|
-
// We must be careful that our video/unsupported was not filtered out
|
|
2852
|
-
// because of MSE support. We are specifically testing EME-based
|
|
2853
|
-
// filtering of codecs.
|
|
2854
|
-
expect(MediaSource.isTypeSupported('video/unsupported')).toBe(true);
|
|
2855
|
-
// Make sure that drm engine will reject the variant with an unsupported
|
|
2856
|
-
// video mime type.
|
|
2857
|
-
drmEngine.supportsVariant.and.callFake((variant) => {
|
|
2858
|
-
return variant.video.codecs != 'unsupported';
|
|
2859
|
-
});
|
|
2860
|
-
}
|
|
2835
|
+
return {supported: false};
|
|
2836
|
+
} else {
|
|
2837
|
+
return {supported: true};
|
|
2838
|
+
}
|
|
2839
|
+
};
|
|
2861
2840
|
|
|
2862
|
-
player.configure({useMediaCapabilities: useMediaCapabilities});
|
|
2863
2841
|
await player.load(fakeManifestUri, 0, fakeMimeType);
|
|
2864
2842
|
const tracks = player.getVariantTracks();
|
|
2865
2843
|
expect(tracks.length).toBe(1);
|
|
2866
2844
|
expect(tracks[0].id).toBe(1);
|
|
2867
|
-
}
|
|
2845
|
+
});
|
|
2868
2846
|
|
|
2869
2847
|
it('removes based on bandwidth', async () => {
|
|
2870
2848
|
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
@@ -16,9 +16,9 @@ goog.require('shaka.text.Cue');
|
|
|
16
16
|
shaka.test.CeaUtils = class {
|
|
17
17
|
/**
|
|
18
18
|
* Returns a cue with no underline/italics, and default colors
|
|
19
|
-
* @param {
|
|
20
|
-
* @param {
|
|
21
|
-
* @param {
|
|
19
|
+
* @param {number} startTime
|
|
20
|
+
* @param {number} endTime
|
|
21
|
+
* @param {string} payload
|
|
22
22
|
*/
|
|
23
23
|
static createDefaultCue(startTime, endTime, payload) {
|
|
24
24
|
const cue = new shaka.text.Cue(startTime, endTime, payload);
|
|
@@ -29,13 +29,13 @@ shaka.test.CeaUtils = class {
|
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Returns a cue with custom underline, italics, color, background color.
|
|
32
|
-
* @param {
|
|
33
|
-
* @param {
|
|
34
|
-
* @param {
|
|
35
|
-
* @param {
|
|
36
|
-
* @param {
|
|
37
|
-
* @param {
|
|
38
|
-
* @param {
|
|
32
|
+
* @param {number} startTime
|
|
33
|
+
* @param {number} endTime
|
|
34
|
+
* @param {string} payload
|
|
35
|
+
* @param {boolean} underline
|
|
36
|
+
* @param {boolean} italics
|
|
37
|
+
* @param {string} textColor
|
|
38
|
+
* @param {string} backgroundColor
|
|
39
39
|
* @return {!shaka.text.Cue}
|
|
40
40
|
*/
|
|
41
41
|
static createStyledCue(startTime, endTime, payload, underline,
|
|
@@ -54,8 +54,8 @@ shaka.test.CeaUtils = class {
|
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
56
|
* Returns a cue that corresponds to a linebreak.
|
|
57
|
-
* @param {
|
|
58
|
-
* @param {
|
|
57
|
+
* @param {number} startTime
|
|
58
|
+
* @param {number} endTime
|
|
59
59
|
* @return {!shaka.text.Cue}
|
|
60
60
|
*/
|
|
61
61
|
static createLineBreakCue(startTime, endTime) {
|
|
@@ -46,6 +46,8 @@ shaka.test.Dash = class {
|
|
|
46
46
|
|
|
47
47
|
const playerInterface = {
|
|
48
48
|
networkingEngine: networkingEngine,
|
|
49
|
+
modifyManifestRequest: (request, manifestInfo) => {},
|
|
50
|
+
modifySegmentRequest: (request, segmentInfo) => {},
|
|
49
51
|
filter: () => {},
|
|
50
52
|
makeTextStreamsForClosedCaptions: (manifest) => {},
|
|
51
53
|
onTimelineRegionAdded: fail, // Should not have any EventStream elements.
|
|
@@ -78,6 +80,8 @@ shaka.test.Dash = class {
|
|
|
78
80
|
|
|
79
81
|
const playerInterface = {
|
|
80
82
|
networkingEngine: networkingEngine,
|
|
83
|
+
modifyManifestRequest: (request, manifestInfo) => {},
|
|
84
|
+
modifySegmentRequest: (request, segmentInfo) => {},
|
|
81
85
|
filter: () => {},
|
|
82
86
|
makeTextStreamsForClosedCaptions: (manifest) => {},
|
|
83
87
|
onTimelineRegionAdded: fail, // Should not have any EventStream elements.
|
|
@@ -53,6 +53,13 @@ shaka.test.FakeAdManager = class extends shaka.util.FakeEventTarget {
|
|
|
53
53
|
/** @override */
|
|
54
54
|
replaceServerSideAdTagParameters(adTagParameters) {}
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
* @override
|
|
58
|
+
*/
|
|
59
|
+
getServerSideCuePoints() {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
|
|
56
63
|
/** @override */
|
|
57
64
|
getStats() {
|
|
58
65
|
return this.stats_;
|
|
@@ -17,7 +17,7 @@ goog.require('shaka.test.Util');
|
|
|
17
17
|
*/
|
|
18
18
|
shaka.test.FakeDrmEngine = class {
|
|
19
19
|
constructor() {
|
|
20
|
-
/** @private {!Array.<
|
|
20
|
+
/** @private {!Array.<string>} */
|
|
21
21
|
this.offlineSessions_ = [];
|
|
22
22
|
/** @private {?shaka.extern.DrmInfo} */
|
|
23
23
|
this.drmInfo_ = null;
|
|
@@ -45,6 +45,13 @@ shaka.test.FakeDrmEngine = class {
|
|
|
45
45
|
// be returned.
|
|
46
46
|
this.getDrmInfo.and.callFake(() => this.drmInfo_);
|
|
47
47
|
|
|
48
|
+
/** @type {!jasmine.Spy} */
|
|
49
|
+
this.newInitData = jasmine.createSpy('newInitData');
|
|
50
|
+
this.newInitData.and.callFake((initDataType, initData) => {
|
|
51
|
+
const num = 1 + this.offlineSessions_.length;
|
|
52
|
+
this.offlineSessions_.push('session-' + num);
|
|
53
|
+
});
|
|
54
|
+
|
|
48
55
|
/** @type {!jasmine.Spy} */
|
|
49
56
|
this.getExpiration = jasmine.createSpy('getExpiration');
|
|
50
57
|
this.getExpiration.and.returnValue(Infinity);
|
|
@@ -90,7 +97,7 @@ shaka.test.FakeDrmEngine = class {
|
|
|
90
97
|
}
|
|
91
98
|
|
|
92
99
|
/**
|
|
93
|
-
* @param {!Array.<
|
|
100
|
+
* @param {!Array.<string>} sessions
|
|
94
101
|
*/
|
|
95
102
|
setSessionIds(sessions) {
|
|
96
103
|
// Copy the values to break the reference to the input value.
|
|
@@ -407,6 +407,8 @@ shaka.test.ManifestGenerator.DrmInfo = class {
|
|
|
407
407
|
this.keyIds = new Set();
|
|
408
408
|
/** @type {string} */
|
|
409
409
|
this.sessionType = '';
|
|
410
|
+
/** @type {string} */
|
|
411
|
+
this.serverCertificateUri = '';
|
|
410
412
|
|
|
411
413
|
/** @type {shaka.extern.DrmInfo} */
|
|
412
414
|
const foo = this;
|
|
@@ -651,15 +653,16 @@ shaka.test.ManifestGenerator.Stream = class {
|
|
|
651
653
|
* @param {!Array.<string>} uris
|
|
652
654
|
* @param {number} startByte
|
|
653
655
|
* @param {?number} endByte
|
|
656
|
+
* @param {null|shaka.extern.MediaQualityInfo=} mediaQuality
|
|
654
657
|
*/
|
|
655
|
-
setInitSegmentReference(uris, startByte, endByte) {
|
|
658
|
+
setInitSegmentReference(uris, startByte, endByte, mediaQuality) {
|
|
656
659
|
goog.asserts.assert(this.manifest_,
|
|
657
660
|
'A top-level generated Manifest is required to use this method!');
|
|
658
661
|
|
|
659
662
|
const getUris = () => uris;
|
|
660
663
|
this.initSegmentReference_ =
|
|
661
664
|
new this.manifest_.shaka_.media.InitSegmentReference(
|
|
662
|
-
getUris, startByte, endByte);
|
|
665
|
+
getUris, startByte, endByte, mediaQuality);
|
|
663
666
|
}
|
|
664
667
|
|
|
665
668
|
/**
|
|
@@ -56,11 +56,12 @@ shaka.test.ManifestParser = class {
|
|
|
56
56
|
* @param {?number=} endByte
|
|
57
57
|
* @param {number=} timestampOffset
|
|
58
58
|
* @param {!Array.<!shaka.media.SegmentReference>=} partialReferences
|
|
59
|
+
* @param {?string=} tilesLayout
|
|
59
60
|
* @return {!shaka.media.SegmentReference}
|
|
60
61
|
*/
|
|
61
62
|
static makeReference(uri, start, end, baseUri = '',
|
|
62
63
|
startByte = 0, endByte = null, timestampOffset = 0,
|
|
63
|
-
partialReferences = []) {
|
|
64
|
+
partialReferences = [], tilesLayout = '') {
|
|
64
65
|
const getUris = () => uri.length ? [baseUri + uri] : [];
|
|
65
66
|
|
|
66
67
|
// If a test wants to verify these, they can be set explicitly after
|
|
@@ -84,6 +85,7 @@ shaka.test.ManifestParser = class {
|
|
|
84
85
|
appendWindowStart,
|
|
85
86
|
appendWindowEnd,
|
|
86
87
|
partialReferences,
|
|
88
|
+
tilesLayout,
|
|
87
89
|
);
|
|
88
90
|
}
|
|
89
91
|
};
|
|
@@ -206,10 +206,23 @@ shaka.test.TestScheme = class {
|
|
|
206
206
|
* @param {string} name
|
|
207
207
|
*/
|
|
208
208
|
function addStreamInfo(stream, variant, data, contentType, name) {
|
|
209
|
+
const mediaQualityInfo = {
|
|
210
|
+
bandwidth: 1,
|
|
211
|
+
codecs: data[contentType].codecs || 'unknown',
|
|
212
|
+
contentType: contentType,
|
|
213
|
+
mimeType: data[contentType].mimeType,
|
|
214
|
+
audioSamplingRate: null,
|
|
215
|
+
frameRate: null,
|
|
216
|
+
height: null,
|
|
217
|
+
channelsCount: null,
|
|
218
|
+
pixelAspectRatio: null,
|
|
219
|
+
width: null,
|
|
220
|
+
};
|
|
209
221
|
stream.mimeType = data[contentType].mimeType;
|
|
210
222
|
stream.codecs = data[contentType].codecs;
|
|
211
223
|
stream.setInitSegmentReference(
|
|
212
|
-
['test:' + name + '/' + contentType + '/init'], 0, null
|
|
224
|
+
['test:' + name + '/' + contentType + '/init'], 0, null,
|
|
225
|
+
mediaQualityInfo);
|
|
213
226
|
stream.useSegmentTemplate(
|
|
214
227
|
'test:' + name + '/' + contentType + '/%d',
|
|
215
228
|
data[contentType].segmentDuration);
|
|
@@ -1266,6 +1266,8 @@ describe('TtmlTextParser', () => {
|
|
|
1266
1266
|
fontStyle: Cue.fontStyle.ITALIC,
|
|
1267
1267
|
lineHeight: '20px',
|
|
1268
1268
|
fontSize: '10em',
|
|
1269
|
+
textStrokeColor: 'blue',
|
|
1270
|
+
textStrokeWidth: '3px',
|
|
1269
1271
|
},
|
|
1270
1272
|
{
|
|
1271
1273
|
startTime: 2,
|
|
@@ -1277,6 +1279,7 @@ describe('TtmlTextParser', () => {
|
|
|
1277
1279
|
'<tt xmlns:tts="http://www.w3.org/ns/ttml#styling">' +
|
|
1278
1280
|
'<styling>' +
|
|
1279
1281
|
'<style xml:id="s1" tts:color="red" ' +
|
|
1282
|
+
'tts:textOutline="blue 3px" ' +
|
|
1280
1283
|
'tts:backgroundColor="blue" ' +
|
|
1281
1284
|
'tts:fontWeight="bold" ' +
|
|
1282
1285
|
'tts:fontFamily="Times New Roman" ' +
|
|
@@ -1295,6 +1298,50 @@ describe('TtmlTextParser', () => {
|
|
|
1295
1298
|
{periodStart: 0, segmentStart: 0, segmentEnd: 0});
|
|
1296
1299
|
});
|
|
1297
1300
|
|
|
1301
|
+
it('uses text color if tts:textOutline does not specify color', () => {
|
|
1302
|
+
verifyHelper(
|
|
1303
|
+
[
|
|
1304
|
+
{
|
|
1305
|
+
startTime: 1,
|
|
1306
|
+
endTime: 2,
|
|
1307
|
+
payload: 'Test',
|
|
1308
|
+
color: 'red',
|
|
1309
|
+
textStrokeColor: 'red',
|
|
1310
|
+
textStrokeWidth: '3px',
|
|
1311
|
+
},
|
|
1312
|
+
],
|
|
1313
|
+
'<tt xmlns:tts="http://www.w3.org/ns/ttml#styling">' +
|
|
1314
|
+
'<styling>' +
|
|
1315
|
+
'<style xml:id="s1" tts:color="red" ' +
|
|
1316
|
+
'tts:textOutline="3px" />' +
|
|
1317
|
+
'</styling>' +
|
|
1318
|
+
'<body region="subtitleArea"><div>' +
|
|
1319
|
+
'<p begin="00:01.00" end="00:02.00" style="s1">Test</p>' +
|
|
1320
|
+
'</div></body></tt>',
|
|
1321
|
+
{periodStart: 0, segmentStart: 0, segmentEnd: 0});
|
|
1322
|
+
});
|
|
1323
|
+
|
|
1324
|
+
it('does not add an outline if tts:textOutline only contains color', () => {
|
|
1325
|
+
verifyHelper(
|
|
1326
|
+
[
|
|
1327
|
+
{
|
|
1328
|
+
startTime: 1,
|
|
1329
|
+
endTime: 2,
|
|
1330
|
+
payload: 'Test',
|
|
1331
|
+
color: 'red',
|
|
1332
|
+
},
|
|
1333
|
+
],
|
|
1334
|
+
'<tt xmlns:tts="http://www.w3.org/ns/ttml#styling">' +
|
|
1335
|
+
'<styling>' +
|
|
1336
|
+
'<style xml:id="s1" tts:color="red" ' +
|
|
1337
|
+
'tts:textOutline="blue" />' +
|
|
1338
|
+
'</styling>' +
|
|
1339
|
+
'<body region="subtitleArea"><div>' +
|
|
1340
|
+
'<p begin="00:01.00" end="00:02.00" style="s1">Test</p>' +
|
|
1341
|
+
'</div></body></tt>',
|
|
1342
|
+
{periodStart: 0, segmentStart: 0, segmentEnd: 0});
|
|
1343
|
+
});
|
|
1344
|
+
|
|
1298
1345
|
// Regression test for #2623
|
|
1299
1346
|
it('does not apply background colors to containers', () => {
|
|
1300
1347
|
verifyHelper(
|