shaka-player 4.4.3 → 4.5.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 +2 -27
- package/CHANGELOG.md +64 -45
- package/README.md +16 -10
- package/demo/asset_card.js +18 -21
- package/demo/cast_receiver/index.html +0 -1
- package/demo/close_button.js +0 -3
- package/demo/common/asset.js +22 -5
- package/demo/common/assets.js +132 -49
- package/demo/config.js +192 -253
- package/demo/custom.js +39 -98
- package/demo/front.js +7 -10
- package/demo/index.html +19 -22
- package/demo/input.js +6 -11
- package/demo/input_container.js +8 -9
- package/demo/main.js +51 -123
- package/demo/search.js +22 -34
- package/demo/service_worker.js +0 -3
- package/demo/tooltip.js +3 -5
- package/demo/visualizer.js +3 -5
- package/demo/visualizer_button.js +1 -20
- package/dist/demo.compiled.debug.js +152 -178
- package/dist/demo.compiled.debug.map +4 -4
- package/dist/demo.compiled.js +152 -178
- package/dist/demo.compiled.map +4 -4
- package/dist/deps.js +27 -24
- package/dist/locales.js +31 -31
- package/dist/receiver.compiled.debug.js +22 -43
- package/dist/receiver.compiled.debug.map +4 -4
- package/dist/receiver.compiled.js +22 -43
- package/dist/receiver.compiled.map +4 -4
- package/dist/shaka-player.compiled.d.ts +507 -365
- package/dist/shaka-player.compiled.debug.d.ts +507 -365
- package/dist/shaka-player.compiled.debug.externs.js +205 -51
- package/dist/shaka-player.compiled.debug.js +541 -450
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +205 -51
- package/dist/shaka-player.compiled.js +1120 -1066
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +562 -410
- package/dist/shaka-player.ui.debug.d.ts +562 -410
- package/dist/shaka-player.ui.debug.externs.js +226 -51
- package/dist/shaka-player.ui.debug.js +606 -506
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +226 -51
- package/dist/shaka-player.ui.js +1266 -1207
- package/dist/shaka-player.ui.map +4 -4
- package/docs/design/lcevc-integration.md +14 -14
- package/docs/tutorials/faq.md +27 -55
- package/docs/tutorials/index.json +2 -1
- package/docs/tutorials/lcevc.md +118 -0
- package/docs/tutorials/ui-customization.md +4 -0
- package/externs/css_style_declaration.js +19 -0
- package/externs/lcevc.js +37 -13
- package/externs/media_remote.js +68 -0
- package/externs/mediatailor.js +193 -0
- package/externs/pictureinpicture.js +11 -0
- package/externs/shaka/ads.js +27 -0
- package/externs/shaka/manifest.js +10 -5
- package/externs/shaka/manifest_parser.js +7 -1
- package/externs/shaka/offline.js +4 -0
- package/externs/shaka/player.js +12 -1
- package/karma.conf.js +7 -3
- package/lib/abr/simple_abr_manager.js +43 -3
- package/lib/ads/ad_manager.js +104 -50
- package/lib/ads/media_tailor_ad.js +297 -0
- package/lib/ads/media_tailor_ad_manager.js +828 -0
- package/lib/cea/ts_cea_parser.js +15 -2
- package/lib/config/codec_switching_strategy.js +24 -0
- package/lib/dash/content_protection.js +120 -2
- package/lib/dash/dash_parser.js +75 -12
- package/lib/dash/mpd_utils.js +10 -6
- package/lib/dash/segment_base.js +13 -5
- package/lib/dash/segment_list.js +13 -5
- package/lib/dash/segment_template.js +43 -85
- package/lib/dependencies/all.js +8 -7
- package/lib/hls/hls_parser.js +44 -16
- package/lib/lcevc/lcevc_dec.js +220 -0
- package/lib/media/adaptation_set.js +22 -11
- package/lib/media/adaptation_set_criteria.js +25 -7
- package/lib/media/media_source_engine.js +215 -27
- package/lib/media/segment_index.js +1 -1
- package/lib/media/segment_reference.js +7 -7
- package/lib/media/streaming_engine.js +33 -18
- package/lib/mss/mss_parser.js +1 -0
- package/lib/net/networking_engine.js +1 -0
- 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 +1 -0
- package/lib/offline/storage.js +3 -0
- package/lib/player.js +142 -72
- package/lib/routing/payload.js +5 -1
- package/lib/text/cue.js +15 -0
- package/lib/text/ttml_text_parser.js +17 -0
- package/lib/text/ui_text_displayer.js +4 -0
- package/lib/text/vtt_text_parser.js +33 -20
- package/lib/transmuxer/h265.js +862 -0
- package/lib/transmuxer/mpeg_ts_transmuxer.js +3 -2
- package/lib/transmuxer/ts_transmuxer.js +160 -15
- package/lib/util/error.js +28 -9
- package/lib/util/exp_golomb.js +30 -2
- package/lib/util/fake_event.js +3 -0
- package/lib/util/mp4_generator.js +4 -4
- package/lib/util/periods.js +2 -0
- package/lib/util/platform.js +40 -0
- package/lib/util/player_configuration.js +8 -0
- package/lib/util/state_history.js +6 -2
- package/lib/util/stream_utils.js +133 -217
- package/lib/util/ts_parser.js +226 -40
- package/maintained-branches.md +3 -2
- package/package.json +4 -6
- package/roadmap.md +15 -5
- package/shaka-player.uncompiled.js +2 -1
- package/support.html +0 -1
- package/test/cast/cast_receiver_integration.js +47 -0
- package/test/codec_switching/codec_switching_integration.js +181 -0
- package/test/dash/dash_parser_content_protection_unit.js +2 -0
- package/test/dash/dash_parser_integration.js +73 -0
- package/test/dash/dash_parser_live_unit.js +2 -0
- package/test/dash/dash_parser_manifest_unit.js +42 -0
- package/test/dash/dash_parser_segment_base_unit.js +2 -0
- package/test/dash/dash_parser_segment_list_unit.js +2 -0
- package/test/dash/dash_parser_segment_template_unit.js +2 -0
- package/test/demo/demo_unit.js +0 -16
- package/test/hls/hls_live_unit.js +2 -0
- package/test/hls/hls_parser_unit.js +8 -6
- package/test/media/adaptation_set_criteria_unit.js +118 -0
- package/test/media/adaptation_set_unit.js +1 -0
- package/test/media/media_source_engine_unit.js +165 -1
- package/test/media/segment_index_unit.js +4 -4
- package/test/media/segment_prefetch_unit.js +1 -1
- package/test/media/streaming_engine_unit.js +17 -17
- package/test/mss/mss_parser_unit.js +2 -0
- package/test/offline/manifest_convert_unit.js +5 -0
- package/test/offline/storage_integration.js +1 -4
- package/test/player_unit.js +102 -131
- package/test/routing/walker_unit.js +1 -0
- package/test/test/assets/dash-aes-128/Fragments(video=0,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=20000000,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=40000000,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=60000000,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=i,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/dash.mpd +18 -0
- package/test/test/assets/dash-aes-128/license +1 -0
- package/test/test/assets/dash-multi-codec/audio_en_2c_128k_aac.mp4 +0 -0
- package/test/test/assets/dash-multi-codec/audio_es_2c_64k_opus.webm +0 -0
- package/test/test/assets/dash-multi-codec/dash.mpd +32 -0
- package/test/test/assets/dash-multi-codec/video_144p_108k_h264.mp4 +0 -0
- package/test/test/assets/hls-ts-h265/0.ts +0 -0
- package/test/test/assets/hls-ts-h265/hevc.m3u8 +6 -0
- package/test/test/assets/hls-ts-h265/index.m3u8 +7 -0
- package/test/test/assets/hls-ts-muxed-aac-h265/0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h265/1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h265/media.m3u8 +9 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/media.m3u8 +24 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00000.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00001.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00002.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00003.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00004.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00005.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0000.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0001.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0002.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0003.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/prog_index.m3u8 +14 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/index.m3u8 +23 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-1-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-2-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-3-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-4-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-5-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-6-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-7-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-8-v1-a1.ts +0 -0
- package/test/test/util/dash_parser_util.js +4 -0
- package/test/test/util/fake_ad_manager.js +20 -0
- package/test/test/util/fake_media_source_engine.js +8 -2
- package/test/test/util/manifest_generator.js +7 -3
- package/test/test/util/mss_parser_util.js +4 -0
- package/test/test/util/offline_utils.js +1 -0
- package/test/test/util/streaming_engine_util.js +7 -4
- package/test/text/ttml_text_parser_unit.js +52 -0
- package/test/text/vtt_text_parser_unit.js +103 -31
- package/test/transmuxer/transmuxer_integration.js +117 -0
- package/test/ui/ui_unit.js +3 -10
- package/test/util/stream_utils_unit.js +208 -74
- package/ui/controls.js +125 -0
- package/ui/externs/ui.js +8 -1
- package/ui/pip_button.js +22 -120
- package/ui/remote_button.js +201 -0
- package/ui/ui.js +5 -2
- package/demo/common/message_ids.js +0 -309
- package/demo/locales/en.json +0 -288
- package/demo/locales/source.json +0 -1146
- package/externs/mux.js +0 -69
- package/lib/lcevc/lcevc_dil.js +0 -152
- package/lib/transmuxer/muxjs_transmuxer.js +0 -242
- package/test/transmuxer/muxjs_transmuxer_integration.js +0 -177
package/demo/main.js
CHANGED
|
@@ -10,7 +10,6 @@ goog.provide('shakaDemo.Main');
|
|
|
10
10
|
goog.require('ShakaDemoAssetInfo');
|
|
11
11
|
goog.require('goog.asserts');
|
|
12
12
|
goog.require('shakaDemo.CloseButton');
|
|
13
|
-
goog.require('shakaDemo.MessageIds');
|
|
14
13
|
goog.require('shakaDemo.Utils');
|
|
15
14
|
goog.require('shakaDemo.Visualizer');
|
|
16
15
|
goog.require('shakaDemo.VisualizerButton');
|
|
@@ -122,9 +121,8 @@ shakaDemo.Main = class {
|
|
|
122
121
|
* This does not dispatch the shaka-main-loaded event, so it will not cause
|
|
123
122
|
* the nav bar buttons to be set up.
|
|
124
123
|
* @param {!shaka.ui.Overlay.FailReasonCode} reasonCode
|
|
125
|
-
* @return {!Promise}
|
|
126
124
|
*/
|
|
127
|
-
|
|
125
|
+
initFailed(reasonCode) {
|
|
128
126
|
this.initCommon_();
|
|
129
127
|
|
|
130
128
|
// Set up version links, so the user can switch to compiled mode if
|
|
@@ -155,25 +153,19 @@ shakaDemo.Main = class {
|
|
|
155
153
|
element.classList.add('disabled-by-fail');
|
|
156
154
|
}
|
|
157
155
|
|
|
158
|
-
// Because the UI did not load, this will need to set up a localization
|
|
159
|
-
// object manually.
|
|
160
|
-
this.localization_ = new shaka.ui.Localization(/* fallbackLocale= */ 'en');
|
|
161
|
-
this.localization_.changeLocale(navigator.languages || []);
|
|
162
|
-
await this.setupLocalization_();
|
|
163
|
-
|
|
164
156
|
// Process a synthetic error about lack of browser support.
|
|
165
157
|
const severity = shaka.util.Error.Severity.CRITICAL;
|
|
166
158
|
let href = '';
|
|
167
159
|
let message = '';
|
|
168
160
|
switch (reasonCode) {
|
|
169
161
|
case shaka.ui.Overlay.FailReasonCode.NO_BROWSER_SUPPORT:
|
|
170
|
-
message =
|
|
171
|
-
shakaDemo.MessageIds.FAILURE_NO_BROWSER_SUPPORT);
|
|
162
|
+
message = 'Your browser is not supported!';
|
|
172
163
|
href = 'https://github.com/shaka-project/shaka-player#' +
|
|
173
164
|
'platform-and-browser-support-matrix';
|
|
174
165
|
break;
|
|
175
166
|
case shaka.ui.Overlay.FailReasonCode.PLAYER_FAILED_TO_LOAD:
|
|
176
|
-
message =
|
|
167
|
+
message = 'Shaka Player failed to load! If you are using an adblocker' +
|
|
168
|
+
', try switching to compiled mode at the bottom of the page.';
|
|
177
169
|
break;
|
|
178
170
|
}
|
|
179
171
|
this.handleError_(severity, message, href);
|
|
@@ -205,7 +197,7 @@ shakaDemo.Main = class {
|
|
|
205
197
|
// Optionally enter noinput mode. This has to happen before setting up the
|
|
206
198
|
// player.
|
|
207
199
|
this.noInput_ = 'noinput' in this.getParams_();
|
|
208
|
-
|
|
200
|
+
this.setupPlayer_();
|
|
209
201
|
this.readHash_();
|
|
210
202
|
window.addEventListener('hashchange', () => this.hashChanged_());
|
|
211
203
|
|
|
@@ -392,11 +384,8 @@ shakaDemo.Main = class {
|
|
|
392
384
|
ui.configure(uiConfig);
|
|
393
385
|
}
|
|
394
386
|
|
|
395
|
-
/**
|
|
396
|
-
|
|
397
|
-
* @private
|
|
398
|
-
*/
|
|
399
|
-
async setupPlayer_() {
|
|
387
|
+
/** @private */
|
|
388
|
+
setupPlayer_() {
|
|
400
389
|
const video = /** @type {!HTMLVideoElement} */ (this.video_);
|
|
401
390
|
const ui = video['ui'];
|
|
402
391
|
this.player_ = ui.getControls().getPlayer();
|
|
@@ -443,7 +432,6 @@ shakaDemo.Main = class {
|
|
|
443
432
|
});
|
|
444
433
|
|
|
445
434
|
this.localization_ = this.controls_.getLocalization();
|
|
446
|
-
await this.setupLocalization_();
|
|
447
435
|
|
|
448
436
|
const drawerCloseButton = document.getElementById('drawer-close-button');
|
|
449
437
|
drawerCloseButton.addEventListener('click', () => {
|
|
@@ -481,50 +469,6 @@ shakaDemo.Main = class {
|
|
|
481
469
|
this.hideElement_(drawerCloseButton);
|
|
482
470
|
}
|
|
483
471
|
|
|
484
|
-
/**
|
|
485
|
-
* @return {!Promise}
|
|
486
|
-
* @private
|
|
487
|
-
*/
|
|
488
|
-
async setupLocalization_() {
|
|
489
|
-
// Set up localization lazy-loading.
|
|
490
|
-
const applyNewLocaleIfPossible = () => {
|
|
491
|
-
this.localizeHTMLElements_();
|
|
492
|
-
this.dispatchEventWithName_('shaka-main-locale-changed');
|
|
493
|
-
};
|
|
494
|
-
const UNKNOWN_LOCALES = shaka.ui.Localization.UNKNOWN_LOCALES;
|
|
495
|
-
this.localization_.addEventListener(UNKNOWN_LOCALES, (event) => {
|
|
496
|
-
for (const locale of event['locales']) {
|
|
497
|
-
// This will leave promise rejections uncaught; this is acceptable, as
|
|
498
|
-
// this function is actually expected to fail fairly often, and has
|
|
499
|
-
// built-in fallback behavior (from localization events) without needing
|
|
500
|
-
// to catch the promise rejection.
|
|
501
|
-
this.loadUILocale_(locale).then(() => {
|
|
502
|
-
if (locale == this.uiLocale_) {
|
|
503
|
-
applyNewLocaleIfPossible();
|
|
504
|
-
}
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
});
|
|
508
|
-
const LOCALE_CHANGED = shaka.ui.Localization.LOCALE_CHANGED;
|
|
509
|
-
this.localization_.addEventListener(LOCALE_CHANGED, (event) => {
|
|
510
|
-
applyNewLocaleIfPossible();
|
|
511
|
-
});
|
|
512
|
-
const initialLocaleLoads = [];
|
|
513
|
-
initialLocaleLoads.push(this.loadUILocale_(this.uiLocale_));
|
|
514
|
-
if (this.uiLocale_.includes('-')) {
|
|
515
|
-
// Also try to load the 'base' localization.
|
|
516
|
-
// This is so that, for example, the uiLocale_ is set to 'en-US', it will
|
|
517
|
-
// try to load 'en'.
|
|
518
|
-
initialLocaleLoads.push(this.loadUILocale_(this.uiLocale_.split('-')[0]));
|
|
519
|
-
}
|
|
520
|
-
if (!this.uiLocale_.startsWith('en')) {
|
|
521
|
-
// Load 'en' as a fallback option, if not already loaded.
|
|
522
|
-
initialLocaleLoads.push(this.loadUILocale_('en'));
|
|
523
|
-
}
|
|
524
|
-
await Promise.all(initialLocaleLoads);
|
|
525
|
-
this.localizeHTMLElements_();
|
|
526
|
-
}
|
|
527
|
-
|
|
528
472
|
/** @return {boolean} */
|
|
529
473
|
getIsDrawerOpen() {
|
|
530
474
|
const drawer = document.querySelector('.mdl-layout__drawer');
|
|
@@ -719,13 +663,13 @@ shakaDemo.Main = class {
|
|
|
719
663
|
*
|
|
720
664
|
* @param {!ShakaDemoAssetInfo} asset
|
|
721
665
|
* @param {boolean} needOffline True if offline support is required.
|
|
722
|
-
* @return {?
|
|
666
|
+
* @return {?string} unsupportedReason
|
|
723
667
|
* Null if asset is supported.
|
|
724
668
|
*/
|
|
725
669
|
getAssetUnsupportedReason(asset, needOffline) {
|
|
726
670
|
if (needOffline &&
|
|
727
671
|
(!shaka.offline.Storage.support() || !this.initialStoredList_)) {
|
|
728
|
-
return
|
|
672
|
+
return 'Your browser does not support offline storage.';
|
|
729
673
|
}
|
|
730
674
|
|
|
731
675
|
if (asset.source == shakaAssets.Source.CUSTOM) {
|
|
@@ -736,11 +680,11 @@ shakaDemo.Main = class {
|
|
|
736
680
|
|
|
737
681
|
// Is the asset disabled?
|
|
738
682
|
if (asset.disabled) {
|
|
739
|
-
return
|
|
683
|
+
return 'This asset is disabled.';
|
|
740
684
|
}
|
|
741
685
|
|
|
742
686
|
if (needOffline && !asset.features.includes(shakaAssets.Feature.OFFLINE)) {
|
|
743
|
-
return
|
|
687
|
+
return 'This asset cannot be downloaded.';
|
|
744
688
|
}
|
|
745
689
|
|
|
746
690
|
if (!asset.isClear() && !asset.isAes128()) {
|
|
@@ -748,7 +692,7 @@ shakaDemo.Main = class {
|
|
|
748
692
|
return this.support_.drm[shakaAssets.identifierForKeySystem(drm)];
|
|
749
693
|
});
|
|
750
694
|
if (!hasSupportedDRM) {
|
|
751
|
-
return
|
|
695
|
+
return 'Your browser does not support the required key systems.';
|
|
752
696
|
}
|
|
753
697
|
if (needOffline) {
|
|
754
698
|
const hasSupportedOfflineDRM = asset.drm.some((drm) => {
|
|
@@ -757,7 +701,8 @@ shakaDemo.Main = class {
|
|
|
757
701
|
this.support_.drm[identifier].persistentState;
|
|
758
702
|
});
|
|
759
703
|
if (!hasSupportedOfflineDRM) {
|
|
760
|
-
return
|
|
704
|
+
return 'Your browser does not support offline licenses for the ' +
|
|
705
|
+
'required key systems.';
|
|
761
706
|
}
|
|
762
707
|
}
|
|
763
708
|
}
|
|
@@ -765,15 +710,15 @@ shakaDemo.Main = class {
|
|
|
765
710
|
// Does the browser support the asset's manifest type?
|
|
766
711
|
if (asset.features.includes(shakaAssets.Feature.DASH) &&
|
|
767
712
|
!this.support_.manifest['mpd']) {
|
|
768
|
-
return
|
|
713
|
+
return 'Your browser does not support MPEG-DASH manifests.';
|
|
769
714
|
}
|
|
770
715
|
if (asset.features.includes(shakaAssets.Feature.HLS) &&
|
|
771
716
|
!this.support_.manifest['m3u8']) {
|
|
772
|
-
return
|
|
717
|
+
return 'Your browser does not support HLS manifests.';
|
|
773
718
|
}
|
|
774
719
|
if (asset.features.includes(shakaAssets.Feature.MSS) &&
|
|
775
720
|
!this.support_.manifest['ism']) {
|
|
776
|
-
return
|
|
721
|
+
return 'Your browser does not support MSS manifests.';
|
|
777
722
|
}
|
|
778
723
|
|
|
779
724
|
// Does the asset contain a playable mime type?
|
|
@@ -794,7 +739,7 @@ shakaDemo.Main = class {
|
|
|
794
739
|
return this.support_.media[type];
|
|
795
740
|
});
|
|
796
741
|
if (!hasSupportedMimeType) {
|
|
797
|
-
return
|
|
742
|
+
return 'Your browser does not support the required video format.';
|
|
798
743
|
}
|
|
799
744
|
|
|
800
745
|
return null;
|
|
@@ -841,55 +786,6 @@ shakaDemo.Main = class {
|
|
|
841
786
|
return this.nativeControlsEnabled_;
|
|
842
787
|
}
|
|
843
788
|
|
|
844
|
-
/**
|
|
845
|
-
* Look through all elements in the DOM, and look for things tagged as having
|
|
846
|
-
* a localized string. Then, localize them.
|
|
847
|
-
*
|
|
848
|
-
* @private
|
|
849
|
-
*/
|
|
850
|
-
localizeHTMLElements_() {
|
|
851
|
-
for (const element of document.querySelectorAll('[localized-string]')) {
|
|
852
|
-
const key = element.getAttribute('localized-string');
|
|
853
|
-
const value = shakaDemo.MessageIds[key];
|
|
854
|
-
if (value) {
|
|
855
|
-
element.textContent = this.getLocalizedString(value);
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
/**
|
|
861
|
-
* @param {!shakaDemo.MessageIds} string
|
|
862
|
-
* @return {string}
|
|
863
|
-
*/
|
|
864
|
-
getLocalizedString(string) {
|
|
865
|
-
return this.localization_.resolve(string);
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
/**
|
|
869
|
-
* @param {string} locale
|
|
870
|
-
* @return {!Promise}
|
|
871
|
-
* @private
|
|
872
|
-
*/
|
|
873
|
-
async loadUILocale_(locale) {
|
|
874
|
-
if (!locale) {
|
|
875
|
-
return;
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
const load = async (urlBase) => {
|
|
879
|
-
const url = urlBase + '/locales/' + locale + '.json';
|
|
880
|
-
|
|
881
|
-
try {
|
|
882
|
-
const text = await this.loadText_(url);
|
|
883
|
-
const obj = /** @type {!Object.<string, string>} */(JSON.parse(text));
|
|
884
|
-
const map = new Map(Object.entries(obj));
|
|
885
|
-
this.localization_.insert(locale, map);
|
|
886
|
-
} catch (error) {
|
|
887
|
-
console.warn('Unable to load locale', locale, 'for url', url);
|
|
888
|
-
}
|
|
889
|
-
};
|
|
890
|
-
await Promise.all([load('../ui'), load('../demo')]);
|
|
891
|
-
}
|
|
892
|
-
|
|
893
789
|
/** @param {string} locale */
|
|
894
790
|
setUILocale(locale) {
|
|
895
791
|
this.uiLocale_ = locale;
|
|
@@ -1349,6 +1245,11 @@ shakaDemo.Main = class {
|
|
|
1349
1245
|
if (asset.imaAssetKey || (asset.imaContentSrcId && asset.imaVideoId)) {
|
|
1350
1246
|
manifestUri = await this.getManifestUriFromAdManager_(asset);
|
|
1351
1247
|
}
|
|
1248
|
+
// If it's a MediaTailor asset, request ad-containing manifest
|
|
1249
|
+
// from the ad manager.
|
|
1250
|
+
if (asset.mediaTailorUrl) {
|
|
1251
|
+
manifestUri = await this.getManifestUriFromMediaTailorAdManager_(asset);
|
|
1252
|
+
}
|
|
1352
1253
|
await this.player_.load(
|
|
1353
1254
|
manifestUri,
|
|
1354
1255
|
/* startTime= */ null,
|
|
@@ -1636,6 +1537,34 @@ shakaDemo.Main = class {
|
|
|
1636
1537
|
}
|
|
1637
1538
|
}
|
|
1638
1539
|
|
|
1540
|
+
/**
|
|
1541
|
+
* @param {ShakaDemoAssetInfo} asset
|
|
1542
|
+
* @return {!Promise.<string>}
|
|
1543
|
+
* @private
|
|
1544
|
+
*/
|
|
1545
|
+
async getManifestUriFromMediaTailorAdManager_(asset) {
|
|
1546
|
+
const adManager = this.player_.getAdManager();
|
|
1547
|
+
const container = this.controls_.getServerSideAdContainer();
|
|
1548
|
+
try {
|
|
1549
|
+
goog.asserts.assert(this.video_ != null, 'Video should not be null!');
|
|
1550
|
+
goog.asserts.assert(asset.mediaTailorUrl != null,
|
|
1551
|
+
'Media Tailor info not be null!');
|
|
1552
|
+
const netEngine = this.player_.getNetworkingEngine();
|
|
1553
|
+
goog.asserts.assert(netEngine, 'There should be a net engine.');
|
|
1554
|
+
adManager.initMediaTailor(container, netEngine, this.video_);
|
|
1555
|
+
const uri = await adManager.requestMediaTailorStream(
|
|
1556
|
+
asset.mediaTailorUrl, asset.mediaTailorAdsParams,
|
|
1557
|
+
/* backupUri= */ asset.manifestUri);
|
|
1558
|
+
return uri;
|
|
1559
|
+
} catch (error) {
|
|
1560
|
+
console.log(error);
|
|
1561
|
+
console.warn('Ads code has been prevented from running ' +
|
|
1562
|
+
'or returned an error. Proceeding without ads.');
|
|
1563
|
+
|
|
1564
|
+
return asset.manifestUri;
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1639
1568
|
/**
|
|
1640
1569
|
* Sets up a nav button, and an associated tab.
|
|
1641
1570
|
* This method is meant to be called by the various tabs, as part of their
|
|
@@ -1810,7 +1739,6 @@ shakaDemo.Main = class {
|
|
|
1810
1739
|
// Always show the new error if:
|
|
1811
1740
|
// 1. there is no error showing currently
|
|
1812
1741
|
// 2. the new error is more severe than the old one
|
|
1813
|
-
// Sadly, we do not (yet?) have localizations for error messages.
|
|
1814
1742
|
if (this.currentErrorSeverity_ == null ||
|
|
1815
1743
|
severity > this.currentErrorSeverity_) {
|
|
1816
1744
|
this.errorDisplayLink_.href = href;
|
package/demo/search.js
CHANGED
|
@@ -11,7 +11,6 @@ goog.provide('shakaDemo.Search');
|
|
|
11
11
|
goog.require('shakaDemo.AssetCard');
|
|
12
12
|
goog.require('shakaDemo.BoolInput');
|
|
13
13
|
goog.require('shakaDemo.InputContainer');
|
|
14
|
-
goog.require('shakaDemo.MessageIds');
|
|
15
14
|
goog.require('shakaDemo.SelectInput');
|
|
16
15
|
goog.requireType('ShakaDemoAssetInfo');
|
|
17
16
|
|
|
@@ -60,12 +59,6 @@ shakaDemo.Search = class {
|
|
|
60
59
|
document.addEventListener('shaka-main-offline-progress', () => {
|
|
61
60
|
this.updateOfflineProgress_();
|
|
62
61
|
});
|
|
63
|
-
document.addEventListener('shaka-main-locale-changed', () => {
|
|
64
|
-
this.remakeSearchDiv_(container);
|
|
65
|
-
this.remakeResultsDiv_();
|
|
66
|
-
// Update the componentHandler, to account for any new MDL elements added.
|
|
67
|
-
componentHandler.upgradeDom();
|
|
68
|
-
});
|
|
69
62
|
document.addEventListener('shaka-main-page-changed', () => {
|
|
70
63
|
if (!this.resultsDiv_.childNodes.length &&
|
|
71
64
|
!container.classList.contains('hidden')) {
|
|
@@ -153,7 +146,7 @@ shakaDemo.Search = class {
|
|
|
153
146
|
if (unsupportedReason) {
|
|
154
147
|
c.markAsUnsupported(unsupportedReason);
|
|
155
148
|
} else {
|
|
156
|
-
c.addButton(
|
|
149
|
+
c.addButton('Play', () => {
|
|
157
150
|
shakaDemoMain.loadAsset(asset);
|
|
158
151
|
this.updateSelected_();
|
|
159
152
|
});
|
|
@@ -270,7 +263,7 @@ shakaDemo.Search = class {
|
|
|
270
263
|
* The term this represents.
|
|
271
264
|
* @param {shakaDemo.Search.TermType} type
|
|
272
265
|
* The type of term that this term is.
|
|
273
|
-
* @param {?
|
|
266
|
+
* @param {?string} tooltip
|
|
274
267
|
* @private
|
|
275
268
|
*/
|
|
276
269
|
makeBooleanInput_(searchContainer, choice, type, tooltip) {
|
|
@@ -298,7 +291,7 @@ shakaDemo.Search = class {
|
|
|
298
291
|
* Creates an input for a group of related but mutually-exclusive search
|
|
299
292
|
* terms.
|
|
300
293
|
* @param {!shakaDemo.InputContainer} searchContainer
|
|
301
|
-
* @param {
|
|
294
|
+
* @param {string} name
|
|
302
295
|
* @param {!Array.<!shakaDemo.Search.SearchTerm>} choices
|
|
303
296
|
* An array of the terms in this term group.
|
|
304
297
|
* @param {shakaDemo.Search.TermType} type
|
|
@@ -311,7 +304,7 @@ shakaDemo.Search = class {
|
|
|
311
304
|
const nullOption = '---';
|
|
312
305
|
const valuesObject = {};
|
|
313
306
|
for (const term of choices) {
|
|
314
|
-
valuesObject[term] =
|
|
307
|
+
valuesObject[term] = term;
|
|
315
308
|
}
|
|
316
309
|
valuesObject[nullOption] = nullOption;
|
|
317
310
|
let lastValue = nullOption;
|
|
@@ -357,23 +350,18 @@ shakaDemo.Search = class {
|
|
|
357
350
|
const coreContainer = new shakaDemo.InputContainer(
|
|
358
351
|
container, /* headerText= */ null, shakaDemo.InputContainer.Style.FLEX,
|
|
359
352
|
/* docLink= */ null);
|
|
360
|
-
this.makeSelectInput_(coreContainer,
|
|
361
|
-
shakaDemo.MessageIds.MANIFEST_SEARCH,
|
|
353
|
+
this.makeSelectInput_(coreContainer, 'Manifest',
|
|
362
354
|
[Feature.DASH, Feature.HLS, Feature.MSS], FEATURE);
|
|
363
|
-
this.makeSelectInput_(coreContainer,
|
|
364
|
-
shakaDemo.MessageIds.CONTAINER_SEARCH,
|
|
355
|
+
this.makeSelectInput_(coreContainer, 'Container',
|
|
365
356
|
[Feature.MP4, Feature.MP2TS, Feature.WEBM, Feature.CONTAINERLESS],
|
|
366
357
|
FEATURE);
|
|
367
|
-
this.makeSelectInput_(coreContainer,
|
|
368
|
-
shakaDemo.MessageIds.DRM_SEARCH,
|
|
358
|
+
this.makeSelectInput_(coreContainer, 'DRM',
|
|
369
359
|
Object.values(shakaAssets.KeySystem), DRM);
|
|
370
|
-
this.makeSelectInput_(coreContainer,
|
|
371
|
-
shakaDemo.MessageIds.SOURCE_SEARCH,
|
|
360
|
+
this.makeSelectInput_(coreContainer, 'Source',
|
|
372
361
|
Object.values(shakaAssets.Source).filter((term) => {
|
|
373
362
|
return term != shakaAssets.Source.CUSTOM;
|
|
374
363
|
}), SOURCE);
|
|
375
|
-
this.makeSelectInput_(coreContainer,
|
|
376
|
-
shakaDemo.MessageIds.LIVE_SEARCH,
|
|
364
|
+
this.makeSelectInput_(coreContainer, 'Live',
|
|
377
365
|
[Feature.LOW_LATENCY, Feature.LIVE, Feature.VOD], FEATURE);
|
|
378
366
|
|
|
379
367
|
// Special terms.
|
|
@@ -382,29 +370,29 @@ shakaDemo.Search = class {
|
|
|
382
370
|
container, /* headerText= */ null, containerStyle,
|
|
383
371
|
/* docLink= */ null);
|
|
384
372
|
this.makeBooleanInput_(specialContainer, Feature.HIGH_DEFINITION, FEATURE,
|
|
385
|
-
|
|
373
|
+
'Filters for assets with at least one high-definition video stream.');
|
|
386
374
|
this.makeBooleanInput_(specialContainer, Feature.XLINK, FEATURE,
|
|
387
|
-
|
|
375
|
+
'Filters for assets that have XLINK tags in their manifests, so that ' +
|
|
376
|
+
'they can be broken into multiple files.');
|
|
388
377
|
this.makeBooleanInput_(specialContainer, Feature.SUBTITLES, FEATURE,
|
|
389
|
-
|
|
378
|
+
'Filters for assets with caption tracks, or embedded captions.');
|
|
390
379
|
this.makeBooleanInput_(specialContainer, Feature.TRICK_MODE, FEATURE,
|
|
391
|
-
|
|
380
|
+
'Filters for assets that have special video tracks to be used in ' +
|
|
381
|
+
'trick mode playback (aka fast-forward).');
|
|
392
382
|
this.makeBooleanInput_(specialContainer, Feature.SURROUND, FEATURE,
|
|
393
|
-
|
|
383
|
+
'Filters for assets with at least one surround sound audio track.');
|
|
394
384
|
this.makeBooleanInput_(specialContainer, Feature.OFFLINE, FEATURE,
|
|
395
|
-
|
|
385
|
+
'Filters for assets that can be stored offline.');
|
|
396
386
|
this.makeBooleanInput_(specialContainer, Feature.STORED, FEATURE,
|
|
397
|
-
|
|
387
|
+
'Filters for assets that have been stored offline.');
|
|
398
388
|
this.makeBooleanInput_(specialContainer, Feature.ADS, FEATURE,
|
|
399
|
-
|
|
389
|
+
'Filters for assets that have advertisements.');
|
|
400
390
|
this.makeBooleanInput_(specialContainer, Feature.AUDIO_ONLY, FEATURE,
|
|
401
|
-
|
|
391
|
+
'Filters for assets that do not have video streams.');
|
|
402
392
|
this.makeBooleanInput_(specialContainer, Feature.THUMBNAILS, FEATURE,
|
|
403
|
-
|
|
393
|
+
'Filters for assets that have a thumbnail track.');
|
|
404
394
|
this.makeBooleanInput_(specialContainer, Feature.LCEVC, FEATURE,
|
|
405
|
-
|
|
406
|
-
this.makeBooleanInput_(specialContainer, Feature.LOW_LATENCY,
|
|
407
|
-
FEATURE, shakaDemo.MessageIds.LOW_LATENCY);
|
|
395
|
+
'Filters for assets that have an LCEVC enhancement layer.');
|
|
408
396
|
|
|
409
397
|
container.appendChild(this.resultsDiv_);
|
|
410
398
|
}
|
package/demo/service_worker.js
CHANGED
|
@@ -92,9 +92,6 @@ const OPTIONAL_RESOURCES = [
|
|
|
92
92
|
'https://shaka-player-demo.appspot.com/assets/poster.jpg',
|
|
93
93
|
'https://shaka-player-demo.appspot.com/assets/audioOnly.gif',
|
|
94
94
|
|
|
95
|
-
// The mux.js transmuxing library for MPEG-2 TS and CEA support.
|
|
96
|
-
'../node_modules/mux.js/dist/mux.min.js',
|
|
97
|
-
|
|
98
95
|
// The codem-isoboxer library for MSS support.
|
|
99
96
|
'../node_modules/codem-isoboxer/dist/iso_boxer.min.js',
|
|
100
97
|
|
package/demo/tooltip.js
CHANGED
|
@@ -7,19 +7,17 @@
|
|
|
7
7
|
|
|
8
8
|
goog.provide('shakaDemo.Tooltips');
|
|
9
9
|
|
|
10
|
-
goog.requireType('shakaDemo.MessageIds');
|
|
11
|
-
|
|
12
10
|
/**
|
|
13
11
|
* Creates and contains a tooltip.
|
|
14
12
|
*/
|
|
15
13
|
shakaDemo.Tooltips = class {
|
|
16
14
|
/**
|
|
17
15
|
* @param {!Element} labeledElement
|
|
18
|
-
* @param {
|
|
16
|
+
* @param {string} content
|
|
19
17
|
*/
|
|
20
|
-
static make(labeledElement,
|
|
18
|
+
static make(labeledElement, content) {
|
|
21
19
|
tippy(labeledElement, {
|
|
22
|
-
content
|
|
20
|
+
content,
|
|
23
21
|
placement: 'bottom',
|
|
24
22
|
arrow: true,
|
|
25
23
|
animation: 'scale',
|
package/demo/visualizer.js
CHANGED
|
@@ -84,8 +84,7 @@ shakaDemo.Visualizer = class {
|
|
|
84
84
|
inputContainer.addRow(null, null);
|
|
85
85
|
this.screenshotButton_ = document.createElement('button');
|
|
86
86
|
inputContainer.latestElementContainer.appendChild(this.screenshotButton_);
|
|
87
|
-
this.screenshotButton_.textContent =
|
|
88
|
-
shakaDemo.MessageIds.VISUALIZER_SCREENSHOT_BUTTON);
|
|
87
|
+
this.screenshotButton_.textContent = 'Take Screenshot';
|
|
89
88
|
this.screenshotButton_.classList.add('mdl-button');
|
|
90
89
|
this.screenshotButton_.classList.add('mdl-button--colored');
|
|
91
90
|
this.screenshotButton_.classList.add('mdl-js-button');
|
|
@@ -94,11 +93,10 @@ shakaDemo.Visualizer = class {
|
|
|
94
93
|
this.takeScreenshot_();
|
|
95
94
|
});
|
|
96
95
|
|
|
97
|
-
inputContainer.addRow(
|
|
98
|
-
shakaDemo.MessageIds.VISUALIZER_AUTO_SCREENSHOT_TOGGLE, null);
|
|
96
|
+
inputContainer.addRow('Take Screenshot On Stall', null);
|
|
99
97
|
/** @private {!shakaDemo.BoolInput} */
|
|
100
98
|
this.autoScreenshotToggle_ = new shakaDemo.BoolInput(
|
|
101
|
-
inputContainer,
|
|
99
|
+
inputContainer, 'Take Screenshot On Stall',
|
|
102
100
|
(input) => {
|
|
103
101
|
this.takeAutoScreenshots_ = input.checked;
|
|
104
102
|
});
|
|
@@ -7,8 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
goog.provide('shakaDemo.VisualizerButton');
|
|
9
9
|
|
|
10
|
-
goog.require('shakaDemo.MessageIds');
|
|
11
|
-
|
|
12
10
|
/**
|
|
13
11
|
* A custom UI overflow button, to allow users to show the visualizer.
|
|
14
12
|
* This cannot actually extend shaka.ui.Element, as that class does not exist
|
|
@@ -41,6 +39,7 @@ shakaDemo.VisualizerButton = class extends shaka.ui.Element {
|
|
|
41
39
|
label.classList.add('shaka-overflow-menu-only');
|
|
42
40
|
this.nameSpan_ = document.createElement('span');
|
|
43
41
|
label.appendChild(this.nameSpan_);
|
|
42
|
+
this.nameSpan_.textContent = 'Buffer Visualizer';
|
|
44
43
|
|
|
45
44
|
/** @private {!HTMLElement} */
|
|
46
45
|
this.currentPipState_ = /** @type {!HTMLElement} */ (
|
|
@@ -57,24 +56,6 @@ shakaDemo.VisualizerButton = class extends shaka.ui.Element {
|
|
|
57
56
|
!shakaDemoMain.getIsVisualizerActive());
|
|
58
57
|
this.setIcon_();
|
|
59
58
|
});
|
|
60
|
-
|
|
61
|
-
this.eventManager.listen(
|
|
62
|
-
this.localization, shaka.ui.Localization.LOCALE_UPDATED, () => {
|
|
63
|
-
this.updateLocalizedStrings_();
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
this.eventManager.listen(
|
|
67
|
-
this.localization, shaka.ui.Localization.LOCALE_CHANGED, () => {
|
|
68
|
-
this.updateLocalizedStrings_();
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** @private */
|
|
73
|
-
updateLocalizedStrings_() {
|
|
74
|
-
this.nameSpan_.textContent = shakaDemoMain.getLocalizedString(
|
|
75
|
-
shakaDemo.MessageIds.VISUALIZER_BUTTON);
|
|
76
|
-
// TODO: Make sure that the screenreader description of this control is
|
|
77
|
-
// localized!
|
|
78
59
|
}
|
|
79
60
|
|
|
80
61
|
/** @private */
|