shaka-player 4.3.10 → 4.4.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/release-please.yaml +7 -0
- package/AUTHORS +9 -0
- package/CHANGELOG.md +295 -200
- package/CONTRIBUTORS +8 -0
- package/LICENSE +32 -0
- package/README.md +63 -10
- package/demo/autoTemplate.txt +40 -5
- package/demo/close_button.js +11 -0
- package/demo/common/asset.js +13 -1
- package/demo/common/assets.js +53 -3
- package/demo/common/message_ids.js +25 -1
- package/demo/config.js +69 -10
- package/demo/customWarning.txt +2 -2
- package/demo/index.html +3 -1
- package/demo/locales/en.json +26 -2
- package/demo/locales/source.json +105 -9
- package/demo/main.js +52 -9
- package/demo/search.js +3 -1
- package/demo/service_worker.js +3 -0
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +124 -112
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +124 -112
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +46 -28
- package/dist/locales.js +28 -28
- package/dist/receiver.compiled.debug.js +52 -46
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +52 -46
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +676 -391
- package/dist/shaka-player.compiled.debug.d.ts +676 -391
- package/dist/shaka-player.compiled.debug.externs.js +1188 -616
- package/dist/shaka-player.compiled.debug.js +1045 -700
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +1188 -616
- package/dist/shaka-player.compiled.js +1094 -933
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +677 -392
- package/dist/shaka-player.ui.debug.d.ts +677 -392
- package/dist/shaka-player.ui.debug.externs.js +1023 -451
- package/dist/shaka-player.ui.debug.js +1100 -739
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +1023 -451
- package/dist/shaka-player.ui.js +1244 -1071
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/ad_monetization.md +15 -1
- package/docs/tutorials/application-level-redirects.md +1 -1
- package/docs/tutorials/config.md +9 -5
- package/docs/tutorials/drm-config.md +61 -0
- package/docs/tutorials/fairplay.md +19 -4
- package/docs/tutorials/license-server-auth.md +4 -4
- package/docs/tutorials/license-wrapping.md +2 -2
- package/docs/tutorials/ui-customization.md +7 -3
- package/docs/tutorials/ui.md +7 -7
- package/docs/tutorials/upgrade.md +3 -0
- package/externs/ima.js +123 -2
- package/externs/isoboxer.js +217 -0
- package/externs/mediakeys.js +18 -0
- package/externs/mux.js +1 -105
- package/externs/pictureinpicture.js +48 -0
- package/externs/shaka/ads.js +61 -1
- package/externs/shaka/cea.js +110 -0
- package/externs/shaka/codecs.js +32 -0
- package/externs/shaka/manifest.js +101 -1
- package/externs/shaka/manifest_parser.js +0 -10
- package/externs/shaka/net.js +36 -7
- package/externs/shaka/offline.js +8 -1
- package/externs/shaka/player.js +220 -21
- package/externs/shaka/text.js +1 -382
- package/externs/shaka/transmuxer.js +59 -0
- package/karma.conf.js +13 -0
- package/lib/abr/simple_abr_manager.js +6 -3
- package/lib/ads/ad_manager.js +60 -2
- package/lib/ads/client_side_ad.js +86 -0
- package/lib/ads/client_side_ad_manager.js +79 -3
- package/lib/ads/server_side_ad.js +86 -0
- package/lib/ads/server_side_ad_manager.js +13 -0
- package/lib/cast/cast_utils.js +1 -0
- package/lib/cea/cea608_data_channel.js +24 -14
- package/lib/cea/cea608_memory.js +5 -2
- package/lib/cea/cea708_service.js +8 -9
- package/lib/cea/cea708_window.js +1 -2
- package/lib/cea/cea_decoder.js +23 -6
- package/lib/cea/cea_utils.js +25 -2
- package/lib/cea/dummy_caption_decoder.js +21 -0
- package/lib/cea/dummy_cea_parser.js +1 -3
- package/lib/cea/mp4_cea_parser.js +15 -10
- package/lib/cea/ts_cea_parser.js +69 -0
- package/lib/dash/content_protection.js +32 -2
- package/lib/dash/dash_parser.js +93 -31
- package/lib/dash/mpd_utils.js +6 -25
- package/lib/dash/segment_base.js +12 -14
- package/lib/dash/segment_list.js +10 -6
- package/lib/dash/segment_template.js +349 -32
- package/lib/dependencies/all.js +8 -0
- package/lib/hls/hls_classes.js +33 -8
- package/lib/hls/hls_parser.js +805 -191
- package/lib/hls/manifest_text_parser.js +4 -14
- package/lib/media/adaptation_set_criteria.js +43 -3
- package/lib/media/closed_caption_parser.js +74 -12
- package/lib/media/drm_engine.js +189 -49
- package/lib/media/gap_jumping_controller.js +1 -1
- package/lib/media/manifest_parser.js +34 -0
- package/lib/media/media_source_capabilities.js +10 -0
- package/lib/media/media_source_engine.js +475 -231
- package/lib/media/playhead.js +1 -1
- package/lib/media/presentation_timeline.js +62 -0
- package/lib/media/segment_index.js +50 -14
- package/lib/media/segment_prefetch.js +277 -0
- package/lib/media/segment_reference.js +70 -4
- package/lib/media/streaming_engine.js +258 -81
- package/lib/media/video_wrapper.js +15 -7
- package/lib/mss/content_protection.js +353 -0
- package/lib/mss/mss_parser.js +1081 -0
- package/lib/net/networking_engine.js +60 -10
- package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
- package/lib/offline/manifest_converter.js +6 -0
- package/lib/offline/storage.js +2 -4
- package/lib/player.js +309 -105
- package/lib/polyfill/media_capabilities.js +43 -3
- package/lib/polyfill/patchedmediakeys_apple.js +5 -0
- package/lib/polyfill/patchedmediakeys_nop.js +5 -0
- package/lib/polyfill/patchedmediakeys_webkit.js +5 -0
- package/lib/text/cue.js +208 -130
- package/lib/text/lrc_text_parser.js +2 -2
- package/lib/text/mp4_vtt_parser.js +2 -2
- package/lib/text/sbv_text_parser.js +1 -1
- package/lib/text/simple_text_displayer.js +2 -1
- package/lib/text/srt_text_parser.js +9 -1
- package/lib/text/ssa_text_parser.js +2 -2
- package/lib/text/text_engine.js +3 -21
- package/lib/text/text_utils.js +71 -20
- package/lib/text/ui_text_displayer.js +14 -14
- package/lib/text/vtt_text_parser.js +22 -14
- package/lib/transmuxer/aac_transmuxer.js +224 -0
- package/lib/transmuxer/ac3.js +142 -0
- package/lib/transmuxer/ac3_transmuxer.js +212 -0
- package/lib/transmuxer/adts.js +232 -0
- package/lib/transmuxer/ec3.js +103 -0
- package/lib/transmuxer/ec3_transmuxer.js +212 -0
- package/lib/transmuxer/h264.js +324 -0
- package/lib/transmuxer/mp3_transmuxer.js +204 -0
- package/lib/transmuxer/mpeg_audio.js +196 -0
- package/lib/transmuxer/mpeg_ts_transmuxer.js +182 -0
- package/lib/transmuxer/mss_transmuxer.js +389 -0
- package/lib/{media/transmuxer.js → transmuxer/muxjs_transmuxer.js} +34 -80
- package/lib/transmuxer/transmuxer_engine.js +161 -0
- package/lib/transmuxer/ts_transmuxer.js +738 -0
- package/lib/util/cmcd_manager.js +131 -71
- package/lib/util/error.js +62 -26
- package/lib/util/exp_golomb.js +220 -0
- package/lib/util/fairplay_utils.js +64 -13
- package/lib/util/id3_utils.js +56 -3
- package/lib/util/language_utils.js +11 -8
- package/lib/util/manifest_parser_utils.js +3 -0
- package/lib/util/mime_utils.js +44 -7
- package/lib/util/mp4_box_parsers.js +233 -5
- package/lib/util/mp4_generator.js +1381 -0
- package/lib/util/periods.js +40 -34
- package/lib/util/platform.js +17 -3
- package/lib/util/player_configuration.js +38 -1
- package/lib/util/stream_utils.js +138 -27
- package/lib/util/text_parser.js +1 -1
- package/lib/util/ts_parser.js +470 -47
- package/lib/util/xml_utils.js +16 -3
- package/maintained-branches.md +2 -2
- package/package.json +3 -1
- package/roadmap.md +21 -6
- package/shaka-player.uncompiled.js +18 -0
- package/test/abr/simple_abr_manager_unit.js +32 -4
- package/test/ads/ad_manager_unit.js +18 -2
- package/test/cast/cast_utils_unit.js +7 -2
- package/test/cea/cea608_memory_unit.js +24 -0
- package/test/cea/cea_decoder_unit.js +33 -0
- package/test/dash/dash_parser_content_protection_unit.js +93 -3
- package/test/dash/dash_parser_live_unit.js +56 -13
- package/test/dash/dash_parser_manifest_unit.js +70 -2
- package/test/dash/dash_parser_segment_base_unit.js +14 -9
- package/test/dash/dash_parser_segment_template_unit.js +286 -6
- package/test/demo/demo_unit.js +5 -1
- package/test/hls/hls_live_unit.js +188 -28
- package/test/hls/hls_parser_unit.js +250 -109
- package/test/hls/manifest_text_parser_unit.js +18 -13
- package/test/media/adaptation_set_criteria_unit.js +46 -14
- package/test/media/adaptation_set_unit.js +2 -0
- package/test/media/drm_engine_integration.js +11 -8
- package/test/media/drm_engine_unit.js +220 -7
- package/test/media/media_source_engine_integration.js +122 -38
- package/test/media/media_source_engine_unit.js +133 -153
- package/test/media/playhead_unit.js +3 -0
- package/test/media/presentation_timeline_unit.js +51 -0
- package/test/media/segment_index_unit.js +52 -0
- package/test/media/segment_prefetch_unit.js +243 -0
- package/test/media/streaming_engine_integration.js +9 -3
- package/test/media/streaming_engine_unit.js +440 -59
- package/test/mss/mss_parser_content_protection_unit.js +49 -0
- package/test/mss/mss_parser_unit.js +472 -0
- package/test/mss/mss_player_integration.js +123 -0
- package/test/offline/manifest_convert_unit.js +9 -0
- package/test/offline/storage_integration.js +6 -1
- package/test/player_unit.js +386 -133
- package/test/polyfill/media_capabilities_unit.js +18 -0
- package/test/test/assets/hls-raw-aac/fileSequence0.aac +0 -0
- package/test/test/assets/hls-raw-aac/fileSequence1.aac +0 -0
- package/test/test/assets/hls-raw-aac/fileSequence2.aac +0 -0
- package/test/test/assets/hls-raw-aac/fileSequence3.aac +0 -0
- package/test/test/assets/hls-raw-aac/manifest.m3u8 +4 -0
- package/test/test/assets/hls-raw-aac/stream.m4a.m3u8 +14 -0
- package/test/test/assets/hls-raw-ac3/fileSequence0.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence1.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence2.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence3.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence4.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence5.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence6.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence7.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/prog_index.m3u8 +31 -0
- package/test/test/assets/hls-raw-ec3/fileSequence0.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence1.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence2.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence3.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence4.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence5.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence6.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence7.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/prog_index.m3u8 +31 -0
- package/test/test/assets/hls-raw-mp3/chunklist_w905519204.m3u8 +13 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_0.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_1.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_2.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_3.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/playlist.m3u8 +4 -0
- package/test/test/assets/hls-ts-aac/playlist.m3u8 +23 -0
- package/test/test/assets/hls-ts-aac/segment_0.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_1.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_2.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_3.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_4.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_5.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_6.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_7.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0000.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0001.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0002.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0003.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0004.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0005.ts +0 -0
- package/test/test/assets/hls-ts-ac3/prog_index.m3u8 +19 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0000.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0001.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0002.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0003.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0004.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0005.ts +0 -0
- package/test/test/assets/hls-ts-ec3/prog_index.m3u8 +19 -0
- package/test/test/assets/hls-ts-h264/fileSequence0.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence1.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence2.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence3.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence4.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence5.ts +0 -0
- package/test/test/assets/hls-ts-h264/prog_index.m3u8 +25 -0
- package/test/test/assets/hls-ts-mp3/manifest.m3u8 +13 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_0.ts +0 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_1.ts +0 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_2.ts +0 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_3.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/chunk.m3u8 +17 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_0_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_1_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_2_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_3_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_4_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_5_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/playlist.m3u8 +4 -0
- package/test/test/boot.js +7 -2
- package/test/test/util/fake_ad.js +99 -0
- package/test/test/util/fake_ad_manager.js +7 -1
- package/test/test/util/fake_networking_engine.js +41 -14
- package/test/test/util/fake_segment_prefetch.js +81 -0
- package/test/test/util/manifest_generator.js +19 -5
- package/test/test/util/mss_parser_util.js +115 -0
- package/test/test/util/offline_utils.js +1 -0
- package/test/test/util/simple_fakes.js +12 -3
- package/test/test/util/streaming_engine_util.js +14 -4
- package/test/test/util/ttml_utils.js +2 -2
- package/test/text/cue_integration.js +1 -1
- package/test/text/srt_text_parser_unit.js +78 -0
- package/test/text/text_engine_unit.js +17 -8
- package/test/text/ui_text_displayer_unit.js +4 -4
- package/test/text/vtt_text_parser_unit.js +59 -40
- package/test/text/web_vtt_generator_unit.js +9 -3
- package/test/{media/transmuxer_integration.js → transmuxer/muxjs_transmuxer_integration.js} +30 -33
- package/test/transmuxer/transmuxer_engine_integration.js +60 -0
- package/test/transmuxer/transmuxer_integration.js +296 -0
- package/test/util/cmcd_manager_unit.js +162 -13
- package/test/util/language_utils_unit.js +9 -2
- package/test/util/mp4_box_parsers_unit.js +39 -4
- package/test/util/periods_unit.js +34 -26
- package/test/util/stream_utils_unit.js +60 -107
- package/ui/controls.js +19 -1
- package/ui/controls.less +1 -0
- package/ui/externs/ui.js +11 -1
- package/ui/language_utils.js +15 -0
- package/ui/less/thumbnails.less +26 -0
- package/ui/locales/oc.json +42 -0
- package/ui/pip_button.js +83 -2
- package/ui/range_element.js +15 -0
- package/ui/resolution_selection.js +9 -2
- package/ui/seek_bar.js +223 -0
- package/ui/ui.js +5 -0
- package/lib/cea/i_caption_decoder.js +0 -51
- package/lib/cea/i_cea_parser.js +0 -68
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
describe('Transmuxer Player', () => {
|
|
8
|
+
const Util = shaka.test.Util;
|
|
9
|
+
|
|
10
|
+
/** @type {!jasmine.Spy} */
|
|
11
|
+
let onErrorSpy;
|
|
12
|
+
|
|
13
|
+
/** @type {!HTMLVideoElement} */
|
|
14
|
+
let video;
|
|
15
|
+
/** @type {shaka.Player} */
|
|
16
|
+
let player;
|
|
17
|
+
/** @type {!shaka.util.EventManager} */
|
|
18
|
+
let eventManager;
|
|
19
|
+
|
|
20
|
+
let compiledShaka;
|
|
21
|
+
|
|
22
|
+
/** @type {!shaka.test.Waiter} */
|
|
23
|
+
let waiter;
|
|
24
|
+
|
|
25
|
+
function isAc3Supported() {
|
|
26
|
+
if (!MediaSource.isTypeSupported('audio/mp4; codecs="ac-3"')) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
// AC3 is flaky in some Tizen devices, so we need omit it for now.
|
|
30
|
+
if (shaka.util.Platform.isTizen()) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
// It seems that AC3 on Edge Windows from github actions is not working
|
|
34
|
+
// (in the lab AC3 is working). The AC3 detection is currently hard-coded
|
|
35
|
+
// to true, which leads to a failure in GitHub's environment.
|
|
36
|
+
// We must enable this, once it is resolved:
|
|
37
|
+
// https://bugs.chromium.org/p/chromium/issues/detail?id=1450313
|
|
38
|
+
const chromeVersion = shaka.util.Platform.chromeVersion();
|
|
39
|
+
if (shaka.util.Platform.isEdge() &&
|
|
40
|
+
chromeVersion && chromeVersion <= 116) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function isEc3Supported() {
|
|
47
|
+
if (!MediaSource.isTypeSupported('audio/mp4; codecs="ec-3"')) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
// EC3 is flaky in some Tizen devices, so we need omit it for now.
|
|
51
|
+
if (shaka.util.Platform.isTizen()) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
// It seems that EC3 on Edge Windows from github actions is not working
|
|
55
|
+
// (in the lab EC3 is working). The EC3 detection is currently hard-coded
|
|
56
|
+
// to true, which leads to a failure in GitHub's environment.
|
|
57
|
+
// We must enable this, once it is resolved:
|
|
58
|
+
// https://bugs.chromium.org/p/chromium/issues/detail?id=1450313
|
|
59
|
+
const chromeVersion = shaka.util.Platform.chromeVersion();
|
|
60
|
+
if (shaka.util.Platform.isEdge() &&
|
|
61
|
+
chromeVersion && chromeVersion <= 116) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
beforeAll(async () => {
|
|
68
|
+
video = shaka.test.UiUtils.createVideoElement();
|
|
69
|
+
document.body.appendChild(video);
|
|
70
|
+
compiledShaka =
|
|
71
|
+
await shaka.test.Loader.loadShaka(getClientArg('uncompiled'));
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
beforeEach(async () => {
|
|
75
|
+
await shaka.test.TestScheme.createManifests(compiledShaka, '_compiled');
|
|
76
|
+
player = new compiledShaka.Player(video);
|
|
77
|
+
|
|
78
|
+
player.configure('mediaSource.forceTransmux', true);
|
|
79
|
+
player.configure('streaming.useNativeHlsOnSafari', false);
|
|
80
|
+
|
|
81
|
+
// Disable stall detection, which can interfere with playback tests.
|
|
82
|
+
player.configure('streaming.stallEnabled', false);
|
|
83
|
+
|
|
84
|
+
// Grab event manager from the uncompiled library:
|
|
85
|
+
eventManager = new shaka.util.EventManager();
|
|
86
|
+
waiter = new shaka.test.Waiter(eventManager);
|
|
87
|
+
waiter.setPlayer(player);
|
|
88
|
+
|
|
89
|
+
onErrorSpy = jasmine.createSpy('onError');
|
|
90
|
+
onErrorSpy.and.callFake((event) => fail(event.detail));
|
|
91
|
+
eventManager.listen(player, 'error', Util.spyFunc(onErrorSpy));
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
afterEach(async () => {
|
|
95
|
+
eventManager.release();
|
|
96
|
+
await player.destroy();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
afterAll(() => {
|
|
100
|
+
document.body.removeChild(video);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe('for audio', () => {
|
|
104
|
+
it('raw AAC', async () => {
|
|
105
|
+
await player.load('/base/test/test/assets/hls-raw-aac/manifest.m3u8');
|
|
106
|
+
await video.play();
|
|
107
|
+
expect(player.isLive()).toBe(false);
|
|
108
|
+
|
|
109
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
110
|
+
// seconds, fail the test.
|
|
111
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
112
|
+
|
|
113
|
+
// Play for 15 seconds, but stop early if the video ends. If it takes
|
|
114
|
+
// longer than 45 seconds, fail the test.
|
|
115
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 15, 45);
|
|
116
|
+
|
|
117
|
+
await player.unload();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('raw MP3', async () => {
|
|
121
|
+
if (!MediaSource.isTypeSupported('audio/mp4; codecs="mp3"')) {
|
|
122
|
+
pending('Codec MP3 in MP4 is not supported by the platform.');
|
|
123
|
+
}
|
|
124
|
+
await player.load('/base/test/test/assets/hls-raw-mp3/playlist.m3u8');
|
|
125
|
+
await video.play();
|
|
126
|
+
expect(player.isLive()).toBe(false);
|
|
127
|
+
|
|
128
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
129
|
+
// seconds, fail the test.
|
|
130
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
131
|
+
|
|
132
|
+
// Play for 15 seconds, but stop early if the video ends. If it takes
|
|
133
|
+
// longer than 45 seconds, fail the test.
|
|
134
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 15, 45);
|
|
135
|
+
|
|
136
|
+
await player.unload();
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('raw AC3', async () => {
|
|
140
|
+
if (!isAc3Supported()) {
|
|
141
|
+
pending('Codec AC-3 is not supported by the platform.');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
await player.load('/base/test/test/assets/hls-raw-ac3/prog_index.m3u8');
|
|
145
|
+
await video.play();
|
|
146
|
+
expect(player.isLive()).toBe(false);
|
|
147
|
+
|
|
148
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
149
|
+
// seconds, fail the test.
|
|
150
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
151
|
+
|
|
152
|
+
// Play for 15 seconds, but stop early if the video ends. If it takes
|
|
153
|
+
// longer than 45 seconds, fail the test.
|
|
154
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 15, 45);
|
|
155
|
+
|
|
156
|
+
await player.unload();
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('raw EC3', async () => {
|
|
160
|
+
if (!isEc3Supported()) {
|
|
161
|
+
pending('Codec EC-3 is not supported by the platform.');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
await player.load('/base/test/test/assets/hls-raw-ac3/prog_index.m3u8');
|
|
165
|
+
await video.play();
|
|
166
|
+
expect(player.isLive()).toBe(false);
|
|
167
|
+
|
|
168
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
169
|
+
// seconds, fail the test.
|
|
170
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
171
|
+
|
|
172
|
+
// Play for 15 seconds, but stop early if the video ends. If it takes
|
|
173
|
+
// longer than 45 seconds, fail the test.
|
|
174
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 15, 45);
|
|
175
|
+
|
|
176
|
+
await player.unload();
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('AAC in TS', async () => {
|
|
180
|
+
await player.load('/base/test/test/assets/hls-ts-aac/playlist.m3u8');
|
|
181
|
+
await video.play();
|
|
182
|
+
expect(player.isLive()).toBe(false);
|
|
183
|
+
|
|
184
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
185
|
+
// seconds, fail the test.
|
|
186
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
187
|
+
|
|
188
|
+
// Play for 15 seconds, but stop early if the video ends. If it takes
|
|
189
|
+
// longer than 45 seconds, fail the test.
|
|
190
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 15, 45);
|
|
191
|
+
|
|
192
|
+
await player.unload();
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('MP3 in TS', async () => {
|
|
196
|
+
if (!MediaSource.isTypeSupported('audio/mp4; codecs="mp3"') &&
|
|
197
|
+
!MediaSource.isTypeSupported('audio/mpeg')) {
|
|
198
|
+
pending('Codec MP3 is not supported by the platform.');
|
|
199
|
+
}
|
|
200
|
+
// This tests is flaky in some Tizen devices, so we need omit it for now.
|
|
201
|
+
if (shaka.util.Platform.isTizen()) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
await player.load('/base/test/test/assets/hls-ts-mp3/manifest.m3u8');
|
|
205
|
+
await video.play();
|
|
206
|
+
expect(player.isLive()).toBe(false);
|
|
207
|
+
|
|
208
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
209
|
+
// seconds, fail the test.
|
|
210
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
211
|
+
|
|
212
|
+
// Play for 15 seconds, but stop early if the video ends. If it takes
|
|
213
|
+
// longer than 45 seconds, fail the test.
|
|
214
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 15, 45);
|
|
215
|
+
|
|
216
|
+
await player.unload();
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('AC3 in TS', async () => {
|
|
220
|
+
if (!isAc3Supported()) {
|
|
221
|
+
pending('Codec AC-3 is not supported by the platform.');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
await player.load('/base/test/test/assets/hls-ts-ac3/prog_index.m3u8');
|
|
225
|
+
await video.play();
|
|
226
|
+
expect(player.isLive()).toBe(false);
|
|
227
|
+
|
|
228
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
229
|
+
// seconds, fail the test.
|
|
230
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
231
|
+
|
|
232
|
+
// Play for 15 seconds, but stop early if the video ends. If it takes
|
|
233
|
+
// longer than 45 seconds, fail the test.
|
|
234
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 15, 45);
|
|
235
|
+
|
|
236
|
+
await player.unload();
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it('EC3 in TS', async () => {
|
|
240
|
+
if (!isEc3Supported()) {
|
|
241
|
+
pending('Codec EC-3 is not supported by the platform.');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
await player.load('/base/test/test/assets/hls-ts-ec3/prog_index.m3u8');
|
|
245
|
+
await video.play();
|
|
246
|
+
expect(player.isLive()).toBe(false);
|
|
247
|
+
|
|
248
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
249
|
+
// seconds, fail the test.
|
|
250
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
251
|
+
|
|
252
|
+
// Play for 15 seconds, but stop early if the video ends. If it takes
|
|
253
|
+
// longer than 45 seconds, fail the test.
|
|
254
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 15, 45);
|
|
255
|
+
|
|
256
|
+
await player.unload();
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
describe('for video', () => {
|
|
261
|
+
it('H.264 in TS', async () => {
|
|
262
|
+
await player.load('/base/test/test/assets/hls-ts-h264/prog_index.m3u8');
|
|
263
|
+
await video.play();
|
|
264
|
+
expect(player.isLive()).toBe(false);
|
|
265
|
+
|
|
266
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
267
|
+
// seconds, fail the test.
|
|
268
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
269
|
+
|
|
270
|
+
// Play for 15 seconds, but stop early if the video ends. If it takes
|
|
271
|
+
// longer than 45 seconds, fail the test.
|
|
272
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 15, 45);
|
|
273
|
+
|
|
274
|
+
await player.unload();
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
describe('for muxed content', () => {
|
|
279
|
+
it('H.264+AAC in TS', async () => {
|
|
280
|
+
// eslint-disable-next-line max-len
|
|
281
|
+
await player.load('/base/test/test/assets/hls-ts-muxed-aac-h264/playlist.m3u8');
|
|
282
|
+
await video.play();
|
|
283
|
+
expect(player.isLive()).toBe(false);
|
|
284
|
+
|
|
285
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
286
|
+
// seconds, fail the test.
|
|
287
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
288
|
+
|
|
289
|
+
// Play for 15 seconds, but stop early if the video ends. If it takes
|
|
290
|
+
// longer than 45 seconds, fail the test.
|
|
291
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 15, 45);
|
|
292
|
+
|
|
293
|
+
await player.unload();
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
});
|
|
@@ -67,9 +67,31 @@ describe('CmcdManager', () => {
|
|
|
67
67
|
});
|
|
68
68
|
});
|
|
69
69
|
|
|
70
|
+
const NetworkingEngine = shaka.net.NetworkingEngine;
|
|
71
|
+
const RequestType = NetworkingEngine.RequestType;
|
|
72
|
+
|
|
73
|
+
function createNetworkingEngine(cmcd) {
|
|
74
|
+
const resolveScheme = jasmine.createSpy('cmcd').and.callFake(
|
|
75
|
+
() => shaka.util.AbortableOperation.completed(
|
|
76
|
+
{uri: '', data: new ArrayBuffer(5), headers: {}},
|
|
77
|
+
));
|
|
78
|
+
|
|
79
|
+
NetworkingEngine.registerScheme(
|
|
80
|
+
'cmcd', shaka.test.Util.spyFunc(resolveScheme),
|
|
81
|
+
NetworkingEngine.PluginPriority.FALLBACK);
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
/** @type {shaka.net.NetworkingEngine.OnRequest} */
|
|
85
|
+
function onRequest(type, request, context) {
|
|
86
|
+
cmcd.applyData(type, request, context);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return new NetworkingEngine(undefined, undefined, undefined,
|
|
90
|
+
onRequest);
|
|
91
|
+
}
|
|
92
|
+
|
|
70
93
|
describe('CmcdManager instance', () => {
|
|
71
94
|
const ObjectUtils = shaka.util.ObjectUtils;
|
|
72
|
-
|
|
73
95
|
const playerInterface = {
|
|
74
96
|
isLive: () => false,
|
|
75
97
|
getBandwidthEstimate: () => 10000000,
|
|
@@ -80,6 +102,8 @@ describe('CmcdManager', () => {
|
|
|
80
102
|
{start: 35, end: 40},
|
|
81
103
|
],
|
|
82
104
|
}),
|
|
105
|
+
getCurrentTime: () => 10,
|
|
106
|
+
getPlaybackRate: () => 1,
|
|
83
107
|
getVariantTracks: () => /** @type {Array.<shaka.extern.Track>} */([
|
|
84
108
|
{
|
|
85
109
|
type: 'variant',
|
|
@@ -94,8 +118,6 @@ describe('CmcdManager', () => {
|
|
|
94
118
|
audioBandWidth: 1000000,
|
|
95
119
|
},
|
|
96
120
|
]),
|
|
97
|
-
getPlaybackRate: () => 1,
|
|
98
|
-
getCurrentTime: () => 10,
|
|
99
121
|
};
|
|
100
122
|
|
|
101
123
|
const sid = '2ed2d1cd-970b-48f2-bfb3-50a79e87cfa3';
|
|
@@ -126,18 +148,25 @@ describe('CmcdManager', () => {
|
|
|
126
148
|
streamDataCallback: null,
|
|
127
149
|
};
|
|
128
150
|
|
|
129
|
-
const
|
|
130
|
-
|
|
151
|
+
const createContext = (type) => {
|
|
152
|
+
return {
|
|
153
|
+
type: type,
|
|
154
|
+
stream: /** @type {shaka.extern.Stream} */ ({
|
|
155
|
+
bandwidth: 5234167,
|
|
156
|
+
codecs: 'avc1.42001e',
|
|
157
|
+
mimeType: 'application/mp4',
|
|
158
|
+
type: 'video',
|
|
159
|
+
}),
|
|
160
|
+
segment: /** @type {shaka.media.SegmentReference} */ ({
|
|
161
|
+
startTime: 0,
|
|
162
|
+
endTime: 3.33,
|
|
163
|
+
}),
|
|
164
|
+
};
|
|
131
165
|
};
|
|
132
166
|
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
duration: 3.33,
|
|
137
|
-
mimeType: 'application/mp4',
|
|
138
|
-
codecs: 'avc1.42001e',
|
|
139
|
-
bandwidth: 5234167,
|
|
140
|
-
};
|
|
167
|
+
const AdvancedRequestType = NetworkingEngine.AdvancedRequestType;
|
|
168
|
+
const manifestInfo = createContext(AdvancedRequestType.MPD);
|
|
169
|
+
const segmentInfo = createContext(AdvancedRequestType.MEDIA_SEGMENT);
|
|
141
170
|
|
|
142
171
|
describe('configuration', () => {
|
|
143
172
|
it('does not modify requests when disabled', () => {
|
|
@@ -286,6 +315,126 @@ describe('CmcdManager', () => {
|
|
|
286
315
|
cmcdManager.applySegmentData(r, segmentInfo);
|
|
287
316
|
expect(r.headers['CMCD-Request']).not.toContain(',su');
|
|
288
317
|
});
|
|
318
|
+
|
|
319
|
+
describe('applies core CMCD params to networking engine requests', () => {
|
|
320
|
+
let networkingEngine;
|
|
321
|
+
const uri = 'cmcd://foo';
|
|
322
|
+
const retry = NetworkingEngine.defaultRetryParameters();
|
|
323
|
+
|
|
324
|
+
beforeAll(() => {
|
|
325
|
+
config.useHeaders = false;
|
|
326
|
+
cmcdManager = new CmcdManager(playerInterface, config);
|
|
327
|
+
networkingEngine = createNetworkingEngine(cmcdManager);
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it('HEAD requests', async () => {
|
|
331
|
+
const request = NetworkingEngine.makeRequest([uri], retry);
|
|
332
|
+
request.method = 'HEAD';
|
|
333
|
+
await networkingEngine.request(RequestType.MANIFEST, request);
|
|
334
|
+
|
|
335
|
+
const result = request.uris[0];
|
|
336
|
+
expect(result).toContain('?CMCD=');
|
|
337
|
+
expect(result).toContain(encodeURIComponent('sid="'));
|
|
338
|
+
expect(result).toContain(encodeURIComponent('cid="testing"'));
|
|
339
|
+
expect(result).not.toContain(encodeURIComponent('sf='));
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
it('dash manifest requests', async () => {
|
|
343
|
+
const request = NetworkingEngine.makeRequest([uri], retry);
|
|
344
|
+
await networkingEngine.request(RequestType.MANIFEST, request,
|
|
345
|
+
{type: AdvancedRequestType.MPD});
|
|
346
|
+
|
|
347
|
+
const result = request.uris[0];
|
|
348
|
+
expect(result).toContain(encodeURIComponent('ot=m'));
|
|
349
|
+
expect(result).toContain(encodeURIComponent('sf=d'));
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
it('hls manifest requests', async () => {
|
|
353
|
+
const request = NetworkingEngine.makeRequest([uri], retry);
|
|
354
|
+
await networkingEngine.request(RequestType.MANIFEST, request,
|
|
355
|
+
{type: AdvancedRequestType.MASTER_PLAYLIST});
|
|
356
|
+
|
|
357
|
+
const result = request.uris[0];
|
|
358
|
+
expect(result).toContain(encodeURIComponent('ot=m'));
|
|
359
|
+
expect(result).toContain(encodeURIComponent('sf=h'));
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
it('hls playlist requests', async () => {
|
|
363
|
+
const request = NetworkingEngine.makeRequest([uri], retry);
|
|
364
|
+
await networkingEngine.request(RequestType.MANIFEST, request,
|
|
365
|
+
{type: AdvancedRequestType.MEDIA_PLAYLIST});
|
|
366
|
+
|
|
367
|
+
const result = request.uris[0];
|
|
368
|
+
expect(result).toContain(encodeURIComponent('ot=m'));
|
|
369
|
+
expect(result).toContain(encodeURIComponent('sf=h'));
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
it('init segment requests', async () => {
|
|
373
|
+
const request = NetworkingEngine.makeRequest([uri], retry);
|
|
374
|
+
await networkingEngine.request(RequestType.SEGMENT, request,
|
|
375
|
+
{type: AdvancedRequestType.INIT_SEGMENT});
|
|
376
|
+
|
|
377
|
+
const result = request.uris[0];
|
|
378
|
+
expect(result).toContain(encodeURIComponent('ot=i'));
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
it('media segment requests', async () => {
|
|
382
|
+
const request = NetworkingEngine.makeRequest([uri], retry);
|
|
383
|
+
await networkingEngine.request(RequestType.SEGMENT, request,
|
|
384
|
+
{
|
|
385
|
+
type: AdvancedRequestType.MEDIA_SEGMENT,
|
|
386
|
+
stream: {
|
|
387
|
+
type: 'video',
|
|
388
|
+
},
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
const result = request.uris[0];
|
|
392
|
+
expect(result).toContain(encodeURIComponent('ot=v'));
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
it('key requests', async () => {
|
|
396
|
+
const request = NetworkingEngine.makeRequest([uri], retry);
|
|
397
|
+
await networkingEngine.request(RequestType.KEY, request);
|
|
398
|
+
|
|
399
|
+
const result = request.uris[0];
|
|
400
|
+
expect(result).toContain(encodeURIComponent('ot=k'));
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
it('license requests', async () => {
|
|
404
|
+
const request = NetworkingEngine.makeRequest([uri], retry);
|
|
405
|
+
await networkingEngine.request(RequestType.LICENSE, request);
|
|
406
|
+
|
|
407
|
+
const result = request.uris[0];
|
|
408
|
+
expect(result).toContain(encodeURIComponent('ot=k'));
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
it('cert requests', async () => {
|
|
412
|
+
const request = NetworkingEngine.makeRequest([uri], retry);
|
|
413
|
+
await networkingEngine.request(RequestType.SERVER_CERTIFICATE,
|
|
414
|
+
request);
|
|
415
|
+
|
|
416
|
+
const result = request.uris[0];
|
|
417
|
+
expect(result).toContain(encodeURIComponent('ot=k'));
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
it('timing requests', async () => {
|
|
421
|
+
const request = NetworkingEngine.makeRequest([uri], retry);
|
|
422
|
+
await networkingEngine.request(RequestType.TIMING, request);
|
|
423
|
+
|
|
424
|
+
const result = request.uris[0];
|
|
425
|
+
expect(result).toContain(encodeURIComponent('ot=o'));
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
it('not when enabled is false', async () => {
|
|
429
|
+
config.enabled = false;
|
|
430
|
+
cmcdManager = new CmcdManager(playerInterface, config);
|
|
431
|
+
const request = NetworkingEngine.makeRequest([uri], retry);
|
|
432
|
+
await networkingEngine.request(RequestType.TIMING, request);
|
|
433
|
+
|
|
434
|
+
const result = request.uris[0];
|
|
435
|
+
expect(result).not.toContain('?CMCD=');
|
|
436
|
+
});
|
|
437
|
+
});
|
|
289
438
|
});
|
|
290
439
|
});
|
|
291
440
|
});
|
|
@@ -111,16 +111,23 @@ describe('LanguageUtils', () => {
|
|
|
111
111
|
expect(LanguageUtils.normalize('EN')).toBe('en');
|
|
112
112
|
});
|
|
113
113
|
|
|
114
|
-
it('
|
|
114
|
+
it('standardizes region', () => {
|
|
115
115
|
expect(LanguageUtils.normalize('en-US')).toBe('en-US');
|
|
116
116
|
expect(LanguageUtils.normalize('en-us')).toBe('en-US');
|
|
117
117
|
});
|
|
118
118
|
|
|
119
|
-
it('
|
|
119
|
+
it('ignores unknown base languages', () => {
|
|
120
120
|
expect(LanguageUtils.normalize('elvish')).toBe('elvish');
|
|
121
121
|
expect(LanguageUtils.normalize(
|
|
122
122
|
'elvish-woodland')).toBe('elvish-WOODLAND');
|
|
123
123
|
});
|
|
124
|
+
|
|
125
|
+
it('supports private use tag', () => {
|
|
126
|
+
expect(LanguageUtils.normalize('eng-us-x-1')).toBe('en-US-x-1');
|
|
127
|
+
expect(LanguageUtils.normalize('eng-x-1')).toBe('en-x-1');
|
|
128
|
+
expect(LanguageUtils.normalize(
|
|
129
|
+
'elvish-woodland-x-1')).toBe('elvish-WOODLAND-x-1');
|
|
130
|
+
});
|
|
124
131
|
});
|
|
125
132
|
|
|
126
133
|
describe('getLocaleForText', () => {
|
|
@@ -29,12 +29,18 @@ describe('Mp4BoxParsers', () => {
|
|
|
29
29
|
let defaultSampleDuration;
|
|
30
30
|
let defaultSampleSize;
|
|
31
31
|
let trackId;
|
|
32
|
+
let width;
|
|
33
|
+
let height;
|
|
32
34
|
let timescale;
|
|
35
|
+
let language;
|
|
33
36
|
|
|
34
37
|
const expectedDefaultSampleDuration = 512;
|
|
35
38
|
const expectedDefaultSampleSize = 0;
|
|
36
39
|
const expectedTrackId = 1;
|
|
40
|
+
const expectedWidth = 1685.9375;
|
|
41
|
+
const expectedHeight = 110;
|
|
37
42
|
const expectedTimescale = 12288;
|
|
43
|
+
const expectedLanguage = 'eng';
|
|
38
44
|
|
|
39
45
|
const Mp4Parser = shaka.util.Mp4Parser;
|
|
40
46
|
new Mp4Parser()
|
|
@@ -56,6 +62,8 @@ describe('Mp4BoxParsers', () => {
|
|
|
56
62
|
const parsedTKHDBox = shaka.util.Mp4BoxParsers.parseTKHD(
|
|
57
63
|
box.reader, box.version);
|
|
58
64
|
trackId = parsedTKHDBox.trackId;
|
|
65
|
+
width = parsedTKHDBox.width;
|
|
66
|
+
height = parsedTKHDBox.height;
|
|
59
67
|
tkhdParsed = true;
|
|
60
68
|
})
|
|
61
69
|
.box('mdia', Mp4Parser.children)
|
|
@@ -66,6 +74,7 @@ describe('Mp4BoxParsers', () => {
|
|
|
66
74
|
const parsedMDHDBox = shaka.util.Mp4BoxParsers.parseMDHD(
|
|
67
75
|
box.reader, box.version);
|
|
68
76
|
timescale = parsedMDHDBox.timescale;
|
|
77
|
+
language = parsedMDHDBox.language;
|
|
69
78
|
mdhdParsed = true;
|
|
70
79
|
})
|
|
71
80
|
.parse(videoInitSegment, /* partialOkay= */ true);
|
|
@@ -76,7 +85,10 @@ describe('Mp4BoxParsers', () => {
|
|
|
76
85
|
expect(defaultSampleDuration).toBe(expectedDefaultSampleDuration);
|
|
77
86
|
expect(defaultSampleSize).toBe(expectedDefaultSampleSize);
|
|
78
87
|
expect(trackId).toBe(expectedTrackId);
|
|
88
|
+
expect(width).toBe(expectedWidth);
|
|
89
|
+
expect(height).toBe(expectedHeight);
|
|
79
90
|
expect(timescale).toBe(expectedTimescale);
|
|
91
|
+
expect(language).toBe(expectedLanguage);
|
|
80
92
|
});
|
|
81
93
|
|
|
82
94
|
it('parses video segment', () => {
|
|
@@ -146,14 +158,22 @@ describe('Mp4BoxParsers', () => {
|
|
|
146
158
|
});
|
|
147
159
|
|
|
148
160
|
/**
|
|
149
|
-
* Test on parsing an incomplete TKHD V1 box, since the parser doesn't
|
|
150
|
-
* parse the other fields
|
|
151
161
|
*
|
|
152
162
|
* Explanation on the Uint8Array:
|
|
153
163
|
* [
|
|
154
164
|
* <creation_time, 8 bytes>,
|
|
155
165
|
* <modification_time, 8 bytes>,
|
|
156
|
-
* <track_id, 4 bytes
|
|
166
|
+
* <track_id, 4 bytes>,
|
|
167
|
+
* <reserved, 8 bytes>,
|
|
168
|
+
* <duration, 4 bytes>,
|
|
169
|
+
* <reserved, 8 bytes>,
|
|
170
|
+
* <layer, 2 bytes>,
|
|
171
|
+
* <alternate_group, 2 bytes>,
|
|
172
|
+
* <volume, 2 bytes>,
|
|
173
|
+
* <reserved, 2 bytes>,
|
|
174
|
+
* <matrix_structure, 36 bytes>,
|
|
175
|
+
* <width, 4 bytes>,
|
|
176
|
+
* <height, 4 bytes>
|
|
157
177
|
* ]
|
|
158
178
|
*
|
|
159
179
|
* Time is a 32B integer expressed in seconds since Jan 1, 1904, 0000 UTC
|
|
@@ -164,12 +184,27 @@ describe('Mp4BoxParsers', () => {
|
|
|
164
184
|
0x00, 0x00, 0x00, 0x00, 0xDC, 0xBF, 0x0F, 0xD7, // Creation time
|
|
165
185
|
0x00, 0x00, 0x00, 0x00, 0xDC, 0xBF, 0x0F, 0xD7, // Modification time
|
|
166
186
|
0x00, 0x00, 0x00, 0x01, // Track ID
|
|
167
|
-
|
|
187
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved
|
|
188
|
+
0x00, 0x00, 0x00, 0x00, // Duration
|
|
189
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved
|
|
190
|
+
0x00, 0x00, // Layer
|
|
191
|
+
0x00, 0x00, // Alternate Group
|
|
192
|
+
0x00, 0x00, // Volume
|
|
193
|
+
0x00, 0x00, // Reserved
|
|
194
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Matrix Structure
|
|
195
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Matrix Structure
|
|
196
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Matrix Structure
|
|
197
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Matrix Structure
|
|
198
|
+
0x00, 0x00, 0x00, 0x00, // Matrix Structure
|
|
199
|
+
0x00, 0x40, 0x00, 0x00, // Width
|
|
200
|
+
0x00, 0x40, 0x00, 0x00, // Height
|
|
168
201
|
]);
|
|
169
202
|
const reader = new shaka.util.DataViewReader(
|
|
170
203
|
tkhdBox, shaka.util.DataViewReader.Endianness.BIG_ENDIAN);
|
|
171
204
|
const parsedTkhd = shaka.util.Mp4BoxParsers
|
|
172
205
|
.parseTKHD(reader, /* version= */ 1);
|
|
173
206
|
expect(parsedTkhd.trackId).toBe(1);
|
|
207
|
+
expect(parsedTkhd.width).toBe(64);
|
|
208
|
+
expect(parsedTkhd.height).toBe(64);
|
|
174
209
|
});
|
|
175
210
|
});
|