shaka-player 3.2.1 → 3.3.1
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 +9 -5
- package/CHANGELOG.md +358 -0
- package/CONTRIBUTORS +7 -2
- package/build/conformance.textproto +183 -169
- package/build/generateExterns.js +1 -1
- package/build/types/core +3 -0
- package/build/types/offline +1 -0
- package/build/types/polyfill +1 -0
- package/build/types/ui +2 -0
- package/demo/common/assets.js +19 -1
- package/demo/common/message_ids.js +13 -1
- package/demo/config.js +31 -1
- package/demo/index.html +1 -1
- package/demo/locales/en.json +12 -0
- package/demo/locales/source.json +48 -0
- package/dist/controls.css +26 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +20 -17
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +20 -17
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +19 -12
- package/dist/locales.js +39 -37
- package/dist/receiver.compiled.debug.js +12 -10
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +12 -10
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +231 -18
- package/dist/shaka-player.compiled.debug.d.ts +231 -18
- package/dist/shaka-player.compiled.debug.externs.js +279 -8
- package/dist/shaka-player.compiled.debug.js +512 -449
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +279 -8
- package/dist/shaka-player.compiled.js +854 -821
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +247 -19
- package/dist/shaka-player.ui.debug.d.ts +247 -19
- package/dist/shaka-player.ui.debug.externs.js +307 -9
- package/dist/shaka-player.ui.debug.js +662 -580
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +307 -9
- package/dist/shaka-player.ui.js +1047 -1000
- 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/fairplay.md +1 -1
- package/docs/tutorials/index.json +1 -0
- package/docs/tutorials/ui-customization.md +66 -0
- package/docs/tutorials/ui.md +5 -5
- package/externs/cmcd.js +186 -0
- package/externs/ima.js +3 -0
- package/externs/shaka/ads.js +5 -0
- package/externs/shaka/manifest.js +12 -1
- package/externs/shaka/manifest_parser.js +10 -1
- package/externs/shaka/net.js +20 -4
- package/externs/shaka/offline.js +31 -2
- package/externs/shaka/player.js +138 -5
- package/externs/shaka/text.js +24 -0
- package/externs/webcrypto.js +18 -0
- package/karma.conf.js +1 -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/client_side_ad.js +8 -0
- package/lib/ads/client_side_ad_manager.js +54 -90
- package/lib/ads/server_side_ad.js +7 -0
- package/lib/ads/server_side_ad_manager.js +7 -10
- package/lib/cast/cast_proxy.js +3 -2
- package/lib/cast/cast_receiver.js +2 -1
- package/lib/cast/cast_sender.js +2 -2
- package/lib/cast/cast_utils.js +1 -0
- package/lib/dash/dash_parser.js +141 -16
- package/lib/dash/segment_base.js +25 -1
- package/lib/dash/segment_list.js +19 -10
- package/lib/dash/segment_template.js +24 -11
- package/lib/hls/hls_parser.js +146 -40
- package/lib/media/drm_engine.js +7 -0
- package/lib/media/gap_jumping_controller.js +4 -2
- package/lib/media/media_source_engine.js +1 -2
- package/lib/media/quality_observer.js +291 -0
- package/lib/media/segment_index.js +8 -1
- package/lib/media/segment_reference.js +37 -4
- package/lib/media/streaming_engine.js +49 -7
- 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 +83 -19
- package/lib/offline/download_info.js +68 -0
- package/lib/offline/download_manager.js +13 -5
- package/lib/offline/indexeddb/base_storage_cell.js +35 -0
- package/lib/offline/indexeddb/storage_mechanism.js +1 -1
- package/lib/offline/indexeddb/v5_storage_cell.js +5 -0
- package/lib/offline/storage.js +393 -284
- package/lib/offline/stored_content_utils.js +2 -0
- package/lib/player.js +249 -43
- package/lib/polyfill/media_capabilities.js +36 -15
- package/lib/polyfill/mediasource.js +6 -0
- package/lib/polyfill/orientation.js +1 -1
- package/lib/polyfill/patchedmediakeys_apple.js +4 -4
- package/lib/polyfill/patchedmediakeys_ms.js +4 -4
- package/lib/polyfill/patchedmediakeys_webkit.js +4 -4
- package/lib/polyfill/random_uuid.js +52 -0
- package/lib/text/cue.js +18 -0
- package/lib/text/mp4_ttml_parser.js +3 -0
- package/lib/text/text_engine.js +14 -2
- package/lib/text/ttml_text_parser.js +114 -60
- package/lib/text/ui_text_displayer.js +95 -41
- package/lib/util/cmcd_manager.js +672 -0
- package/lib/util/error.js +6 -0
- package/lib/util/fake_event.js +53 -7
- package/lib/util/language_utils.js +12 -0
- package/lib/util/mutex.js +52 -0
- package/lib/util/periods.js +102 -65
- package/lib/util/platform.js +13 -1
- package/lib/util/player_configuration.js +18 -0
- package/lib/util/stream_utils.js +99 -10
- package/lib/util/xml_utils.js +19 -0
- package/package.json +2 -2
- package/shaka-player.uncompiled.js +3 -0
- package/test/cast/cast_proxy_unit.js +12 -6
- package/test/cast/cast_utils_unit.js +1 -1
- 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 +222 -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 +7 -1
- package/test/media/closed_caption_parser_unit.js +6 -1
- package/test/media/drm_engine_unit.js +47 -3
- 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 +4 -2
- package/test/media/streaming_engine_unit.js +147 -0
- package/test/net/http_plugin_unit.js +20 -15
- package/test/offline/storage_integration.js +108 -4
- package/test/player_integration.js +178 -8
- package/test/player_src_equals_integration.js +41 -8
- package/test/player_unit.js +19 -9
- package/test/test/assets/3675/chunk-stream0-00001.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00002.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00003.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00004.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00005.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00006.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00007.m4s +0 -0
- package/test/test/assets/3675/dash_0.mpd +30 -0
- package/test/test/assets/3675/dash_1.mpd +30 -0
- package/test/test/assets/3675/dash_2.mpd +30 -0
- package/test/test/assets/3675/dash_3.mpd +30 -0
- package/test/test/assets/3675/dash_4.mpd +30 -0
- package/test/test/assets/3675/dash_5.mpd +26 -0
- package/test/test/assets/3675/init-stream0.m4s +0 -0
- package/test/test/assets/chapters.vtt +2 -2
- package/test/test/assets/chapters2.vtt +10 -0
- 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 +1 -1
- package/test/test/util/fake_drm_engine.js +9 -2
- package/test/test/util/manifest_generator.js +3 -2
- package/test/test/util/test_scheme.js +14 -1
- package/test/test/util/ttml_utils.js +81 -0
- package/test/text/mp4_ttml_parser_unit.js +11 -18
- package/test/text/ttml_text_parser_unit.js +552 -227
- package/test/text/ui_text_displayer_unit.js +29 -17
- package/test/ui/localization_unit.js +15 -14
- package/test/ui/text_displayer_layout_unit.js +13 -1
- package/test/ui/ui_unit.js +250 -0
- package/test/util/cmcd_manager_unit.js +291 -0
- package/test/util/stream_utils_unit.js +45 -4
- package/third_party/closure-uri/uri.js +21 -0
- package/ui/airplay_button.js +1 -0
- package/ui/audio_language_selection.js +7 -0
- package/ui/cast_button.js +3 -3
- package/ui/context_menu.js +109 -0
- package/ui/controls.js +45 -13
- 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 +14 -5
- package/ui/fullscreen_button.js +1 -0
- package/ui/less/buttons.less +0 -4
- package/ui/less/containers.less +77 -7
- 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/ru.json +6 -6
- package/ui/locales/source.json +4 -0
- package/ui/localization.js +28 -51
- package/ui/loop_button.js +5 -0
- package/ui/mute_button.js +2 -1
- package/ui/overflow_menu.js +5 -25
- package/ui/pip_button.js +7 -3
- package/ui/play_button.js +2 -2
- package/ui/playback_rate_selection.js +8 -9
- package/ui/resolution_selection.js +7 -0
- package/ui/rewind_button.js +15 -6
- package/ui/seek_bar.js +4 -2
- package/ui/settings_menu.js +36 -4
- package/ui/small_play_button.js +1 -0
- package/ui/statistics_button.js +253 -0
- package/ui/text_selection.js +12 -4
- package/ui/ui.js +30 -0
- package/ui/volume_bar.js +1 -1
- package/externs/media_capabilities.js +0 -16
package/ui/controls.js
CHANGED
|
@@ -16,6 +16,7 @@ goog.require('shaka.log');
|
|
|
16
16
|
goog.require('shaka.ui.AdCounter');
|
|
17
17
|
goog.require('shaka.ui.AdPosition');
|
|
18
18
|
goog.require('shaka.ui.BigPlayButton');
|
|
19
|
+
goog.require('shaka.ui.ContextMenu');
|
|
19
20
|
goog.require('shaka.ui.Locales');
|
|
20
21
|
goog.require('shaka.ui.Localization');
|
|
21
22
|
goog.require('shaka.ui.SeekBar');
|
|
@@ -323,6 +324,10 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
323
324
|
this.playButton_ = null;
|
|
324
325
|
}
|
|
325
326
|
|
|
327
|
+
if (this.contextMenu_) {
|
|
328
|
+
this.contextMenu_ = null;
|
|
329
|
+
}
|
|
330
|
+
|
|
326
331
|
if (this.controlsContainer_) {
|
|
327
332
|
shaka.util.Dom.removeAllChildren(this.controlsContainer_);
|
|
328
333
|
this.releaseChildElements_();
|
|
@@ -573,9 +578,8 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
573
578
|
}
|
|
574
579
|
}
|
|
575
580
|
} catch (error) {
|
|
576
|
-
this.dispatchEvent(new shaka.util.FakeEvent(
|
|
577
|
-
|
|
578
|
-
}));
|
|
581
|
+
this.dispatchEvent(new shaka.util.FakeEvent(
|
|
582
|
+
'error', (new Map()).set('detail', error)));
|
|
579
583
|
}
|
|
580
584
|
}
|
|
581
585
|
}
|
|
@@ -651,6 +655,10 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
651
655
|
this.addPlayButton_();
|
|
652
656
|
}
|
|
653
657
|
|
|
658
|
+
if (this.config_.customContextMenu) {
|
|
659
|
+
this.addContextMenu_();
|
|
660
|
+
}
|
|
661
|
+
|
|
654
662
|
if (!this.spinnerContainer_) {
|
|
655
663
|
this.addBufferingSpinner_();
|
|
656
664
|
}
|
|
@@ -709,6 +717,14 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
709
717
|
this.elements_.push(this.playButton_);
|
|
710
718
|
}
|
|
711
719
|
|
|
720
|
+
/** @private */
|
|
721
|
+
addContextMenu_() {
|
|
722
|
+
/** @private {shaka.ui.ContextMenu} */
|
|
723
|
+
this.contextMenu_ =
|
|
724
|
+
new shaka.ui.ContextMenu(this.controlsButtonPanel_, this);
|
|
725
|
+
this.elements_.push(this.contextMenu_);
|
|
726
|
+
}
|
|
727
|
+
|
|
712
728
|
/** @private */
|
|
713
729
|
addScrimContainer_() {
|
|
714
730
|
// This is the container that gets styled by CSS to have the
|
|
@@ -723,7 +739,8 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
723
739
|
/** @private {!HTMLElement} */
|
|
724
740
|
this.adPanel_ = shaka.util.Dom.createHTMLElement('div');
|
|
725
741
|
this.adPanel_.classList.add('shaka-ad-controls');
|
|
726
|
-
|
|
742
|
+
const showAdPanel = this.ad_ != null && this.ad_.isLinear();
|
|
743
|
+
shaka.ui.Utils.setDisplay(this.adPanel_, showAdPanel);
|
|
727
744
|
this.bottomControls_.appendChild(this.adPanel_);
|
|
728
745
|
|
|
729
746
|
const adPosition = new shaka.ui.AdPosition(this.adPanel_, this);
|
|
@@ -780,8 +797,12 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
780
797
|
// on the page. The click event listener on window ensures that.
|
|
781
798
|
// However, clicks on the bottom controls don't propagate to the container,
|
|
782
799
|
// so we have to explicitly hide the menus onclick here.
|
|
783
|
-
this.eventManager_.listen(this.bottomControls_, 'click', () => {
|
|
784
|
-
this
|
|
800
|
+
this.eventManager_.listen(this.bottomControls_, 'click', (e) => {
|
|
801
|
+
// We explicitly deny this measure when clicking on buttons that
|
|
802
|
+
// open submenus in the control panel.
|
|
803
|
+
if (!e.target['closest']('.shaka-overflow-button')) {
|
|
804
|
+
this.hideSettingsMenus();
|
|
805
|
+
}
|
|
785
806
|
});
|
|
786
807
|
|
|
787
808
|
this.addAdControls_();
|
|
@@ -791,6 +812,9 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
791
812
|
this.controlsButtonPanel_.classList.add('shaka-controls-button-panel');
|
|
792
813
|
this.controlsButtonPanel_.classList.add(
|
|
793
814
|
'shaka-show-controls-on-mouse-over');
|
|
815
|
+
if (this.config_.enableTooltips) {
|
|
816
|
+
this.controlsButtonPanel_.classList.add('shaka-tooltips-on');
|
|
817
|
+
}
|
|
794
818
|
this.bottomControls_.appendChild(this.controlsButtonPanel_);
|
|
795
819
|
|
|
796
820
|
// Create the elements specified by controlPanelElements
|
|
@@ -860,7 +884,7 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
860
884
|
|
|
861
885
|
|
|
862
886
|
/**
|
|
863
|
-
* Adds a container for
|
|
887
|
+
* Adds a container for client side ad UI with IMA SDK.
|
|
864
888
|
*
|
|
865
889
|
* @private
|
|
866
890
|
*/
|
|
@@ -869,6 +893,9 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
869
893
|
this.clientAdContainer_ = shaka.util.Dom.createHTMLElement('div');
|
|
870
894
|
this.clientAdContainer_.classList.add('shaka-client-side-ad-container');
|
|
871
895
|
shaka.ui.Utils.setDisplay(this.clientAdContainer_, false);
|
|
896
|
+
this.eventManager_.listen(this.clientAdContainer_, 'click', () => {
|
|
897
|
+
this.onContainerClick_();
|
|
898
|
+
});
|
|
872
899
|
this.videoContainer_.appendChild(this.clientAdContainer_);
|
|
873
900
|
}
|
|
874
901
|
|
|
@@ -895,6 +922,12 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
895
922
|
// Listen for click events to dismiss the settings menus.
|
|
896
923
|
this.eventManager_.listen(window, 'click', () => this.hideSettingsMenus());
|
|
897
924
|
|
|
925
|
+
// Avoid having multiple submenus open at the same time.
|
|
926
|
+
this.eventManager_.listen(
|
|
927
|
+
this, 'submenuopen', () => {
|
|
928
|
+
this.hideSettingsMenus();
|
|
929
|
+
});
|
|
930
|
+
|
|
898
931
|
this.eventManager_.listen(this.video_, 'play', () => {
|
|
899
932
|
this.onPlayStateChange_();
|
|
900
933
|
});
|
|
@@ -1101,7 +1134,7 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
1101
1134
|
// recent mouse movement, we're in keyboard navigation, or one of a special
|
|
1102
1135
|
// class of elements is hovered.
|
|
1103
1136
|
if (adIsPaused ||
|
|
1104
|
-
(!this.ad_ && videoIsPaused) ||
|
|
1137
|
+
((!this.ad_ || !this.ad_.isLinear()) && videoIsPaused) ||
|
|
1105
1138
|
this.recentMouseMovement_ ||
|
|
1106
1139
|
keyboardNavigationMode ||
|
|
1107
1140
|
this.isHovered_()) {
|
|
@@ -1145,14 +1178,14 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
1145
1178
|
|
|
1146
1179
|
if (this.anySettingsMenusAreOpen()) {
|
|
1147
1180
|
this.hideSettingsMenusTimer_.tickNow();
|
|
1148
|
-
} else {
|
|
1181
|
+
} else if (this.config_.singleClickForPlayAndPause) {
|
|
1149
1182
|
this.onPlayPauseClick_();
|
|
1150
1183
|
}
|
|
1151
1184
|
}
|
|
1152
1185
|
|
|
1153
1186
|
/** @private */
|
|
1154
1187
|
onPlayPauseClick_() {
|
|
1155
|
-
if (this.ad_) {
|
|
1188
|
+
if (this.ad_ && this.ad_.isLinear()) {
|
|
1156
1189
|
this.playPauseAd();
|
|
1157
1190
|
} else {
|
|
1158
1191
|
this.playPausePresentation();
|
|
@@ -1162,9 +1195,8 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
1162
1195
|
/** @private */
|
|
1163
1196
|
onCastStatusChange_() {
|
|
1164
1197
|
const isCasting = this.castProxy_.isCasting();
|
|
1165
|
-
this.dispatchEvent(new shaka.util.FakeEvent(
|
|
1166
|
-
|
|
1167
|
-
}));
|
|
1198
|
+
this.dispatchEvent(new shaka.util.FakeEvent(
|
|
1199
|
+
'caststatuschanged', (new Map()).set('newStatus', isCasting)));
|
|
1168
1200
|
|
|
1169
1201
|
if (isCasting) {
|
|
1170
1202
|
this.controlsContainer_.setAttribute('casting', 'true');
|
package/ui/controls.less
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
@import "less/other_elements.less";
|
|
13
13
|
@import "less/overflow_menu.less";
|
|
14
14
|
@import "less/ad_controls.less";
|
|
15
|
+
@import "less/tooltip.less";
|
|
15
16
|
@import (css, inline) "https://fonts.googleapis.com/css?family=Roboto";
|
|
16
17
|
// NOTE: Working around google/material-design-icons#958
|
|
17
18
|
@import (css, inline) "https://fonts.googleapis.com/icon?family=Material+Icons+Round";
|
package/ui/enums.js
CHANGED
|
@@ -16,7 +16,9 @@ goog.provide('shaka.ui.Enums');
|
|
|
16
16
|
shaka.ui.Enums.MaterialDesignIcons = {
|
|
17
17
|
'FULLSCREEN': 'fullscreen',
|
|
18
18
|
'EXIT_FULLSCREEN': 'fullscreen_exit',
|
|
19
|
+
'CLOSE': 'close',
|
|
19
20
|
'CLOSED_CAPTIONS': 'closed_caption',
|
|
21
|
+
'CLOSED_CAPTIONS_OFF': 'closed_caption_disabled',
|
|
20
22
|
'CHECKMARK': 'done',
|
|
21
23
|
'LANGUAGE': 'language',
|
|
22
24
|
'PIP': 'picture_in_picture_alt',
|
|
@@ -40,4 +42,6 @@ shaka.ui.Enums.MaterialDesignIcons = {
|
|
|
40
42
|
'UNLOOP': 'repeat_on',
|
|
41
43
|
'AIRPLAY': 'airplay',
|
|
42
44
|
'REPLAY': 'replay',
|
|
45
|
+
'STATISTICS_ON': 'insert_chart_outlined',
|
|
46
|
+
'STATISTICS_OFF': 'insert_chart',
|
|
43
47
|
};
|
package/ui/externs/ui.js
CHANGED
|
@@ -63,8 +63,14 @@ shaka.extern.UIVolumeBarColors;
|
|
|
63
63
|
* @typedef {{
|
|
64
64
|
* controlPanelElements: !Array.<string>,
|
|
65
65
|
* overflowMenuButtons: !Array.<string>,
|
|
66
|
+
* contextMenuElements: !Array.<string>,
|
|
67
|
+
* statisticsList: !Array.<string>,
|
|
68
|
+
* playbackRates: !Array.<number>,
|
|
69
|
+
* fastForwardRates: !Array.<number>,
|
|
70
|
+
* rewindRates: !Array.<number>,
|
|
66
71
|
* addSeekBar: boolean,
|
|
67
72
|
* addBigPlayButton: boolean,
|
|
73
|
+
* customContextMenu: boolean,
|
|
68
74
|
* castReceiverAppId: string,
|
|
69
75
|
* clearBufferOnQualityChange: boolean,
|
|
70
76
|
* showUnbufferedStart: boolean,
|
|
@@ -73,20 +79,34 @@ shaka.extern.UIVolumeBarColors;
|
|
|
73
79
|
* trackLabelFormat: shaka.ui.Overlay.TrackLabelFormat,
|
|
74
80
|
* fadeDelay: number,
|
|
75
81
|
* doubleClickForFullscreen: boolean,
|
|
82
|
+
* singleClickForPlayAndPause: boolean,
|
|
76
83
|
* enableKeyboardPlaybackControls: boolean,
|
|
77
84
|
* enableFullscreenOnRotation: boolean,
|
|
78
|
-
* forceLandscapeOnFullscreen: boolean
|
|
85
|
+
* forceLandscapeOnFullscreen: boolean,
|
|
86
|
+
* enableTooltips: boolean
|
|
79
87
|
* }}
|
|
80
88
|
*
|
|
81
89
|
* @property {!Array.<string>} controlPanelElements
|
|
82
90
|
* The ordered list of control panel elements of the UI.
|
|
83
91
|
* @property {!Array.<string>} overflowMenuButtons
|
|
84
92
|
* The ordered list of the overflow menu buttons.
|
|
93
|
+
* @property {!Array.<string>} contextMenuElements
|
|
94
|
+
* The ordered list of buttons in the context menu.
|
|
95
|
+
* @property {!Array.<string>} statisticsList
|
|
96
|
+
* The ordered list of statistics present in the statistics container.
|
|
97
|
+
* @property {!Array.<number>} playbackRates
|
|
98
|
+
* The ordered list of rates for playback selection.
|
|
99
|
+
* @property {!Array.<number>} fastForwardRates
|
|
100
|
+
* The ordered list of rates for fast forward selection.
|
|
101
|
+
* @property {!Array.<number>} rewindRates
|
|
102
|
+
* The ordered list of rates for rewind selection.
|
|
85
103
|
* @property {boolean} addSeekBar
|
|
86
104
|
* Whether or not a seek bar should be part of the UI.
|
|
87
105
|
* @property {boolean} addBigPlayButton
|
|
88
106
|
* Whether or not a big play button in the center of the video
|
|
89
107
|
* should be part of the UI.
|
|
108
|
+
* @property {boolean} customContextMenu
|
|
109
|
+
* Whether or not a custom context menu replaces the default.
|
|
90
110
|
* @property {string} castReceiverAppId
|
|
91
111
|
* Receiver app id to use for the Chromecast support.
|
|
92
112
|
* @property {boolean} clearBufferOnQualityChange
|
|
@@ -135,6 +155,9 @@ shaka.extern.UIVolumeBarColors;
|
|
|
135
155
|
* Whether or not double-clicking on the UI should cause it to enter
|
|
136
156
|
* fullscreen.
|
|
137
157
|
* Defaults to true.
|
|
158
|
+
* @property {boolean} singleClickForPlayAndPause
|
|
159
|
+
* Whether or not clicking on the video should cause it to play or pause.
|
|
160
|
+
* Defaults to true.
|
|
138
161
|
* @property {boolean} enableKeyboardPlaybackControls
|
|
139
162
|
* Whether or not playback controls via keyboard is enabled, such as seek
|
|
140
163
|
* forward, seek backward, jump to the beginning/end of the video.
|
|
@@ -147,6 +170,10 @@ shaka.extern.UIVolumeBarColors;
|
|
|
147
170
|
* enters fullscreen. Note that this behavior is based on an experimental
|
|
148
171
|
* browser API, and may not work on all platforms.
|
|
149
172
|
* Defaults to true.
|
|
173
|
+
* @property {boolean} enableTooltips
|
|
174
|
+
* Whether or not buttons in the control panel display tooltips that contain
|
|
175
|
+
* information about their function.
|
|
176
|
+
* Defaults to false.
|
|
150
177
|
* @exportDoc
|
|
151
178
|
*/
|
|
152
179
|
shaka.extern.UIConfiguration;
|
|
@@ -32,11 +32,16 @@ shaka.ui.FastForwardButton = class extends shaka.ui.Element {
|
|
|
32
32
|
this.button_ = shaka.util.Dom.createButton();
|
|
33
33
|
this.button_.classList.add('material-icons-round');
|
|
34
34
|
this.button_.classList.add('shaka-fast-forward-button');
|
|
35
|
+
this.button_.classList.add('shaka-tooltip-status');
|
|
36
|
+
this.button_.setAttribute('shaka-status', '1x');
|
|
35
37
|
this.button_.textContent =
|
|
36
38
|
shaka.ui.Enums.MaterialDesignIcons.FAST_FORWARD;
|
|
37
39
|
this.parent.appendChild(this.button_);
|
|
38
40
|
this.updateAriaLabel_();
|
|
39
41
|
|
|
42
|
+
/** @private {!Array.<number>} */
|
|
43
|
+
this.fastForwardRates_ = this.controls.getConfig().fastForwardRates;
|
|
44
|
+
|
|
40
45
|
this.eventManager.listen(
|
|
41
46
|
this.localization, shaka.ui.Localization.LOCALE_UPDATED, () => {
|
|
42
47
|
this.updateAriaLabel_();
|
|
@@ -61,7 +66,7 @@ shaka.ui.FastForwardButton = class extends shaka.ui.Element {
|
|
|
61
66
|
}
|
|
62
67
|
|
|
63
68
|
/**
|
|
64
|
-
* Cycles trick play rate between
|
|
69
|
+
* Cycles trick play rate between the selected fast forward rates.
|
|
65
70
|
* @private
|
|
66
71
|
*/
|
|
67
72
|
fastForward_() {
|
|
@@ -70,11 +75,15 @@ shaka.ui.FastForwardButton = class extends shaka.ui.Element {
|
|
|
70
75
|
}
|
|
71
76
|
|
|
72
77
|
const trickPlayRate = this.player.getPlaybackRate();
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
78
|
+
const newRateIndex = this.fastForwardRates_.indexOf(trickPlayRate) + 1;
|
|
79
|
+
|
|
80
|
+
// When the button is clicked, the next rate in this.fastForwardRates_ is
|
|
81
|
+
// selected. If no more rates are available, the first one is set.
|
|
82
|
+
const newRate = (newRateIndex != this.fastForwardRates_.length) ?
|
|
83
|
+
this.fastForwardRates_[newRateIndex] : this.fastForwardRates_[0];
|
|
77
84
|
this.player.trickPlay(newRate);
|
|
85
|
+
|
|
86
|
+
this.button_.setAttribute('shaka-status', newRate + 'x');
|
|
78
87
|
}
|
|
79
88
|
};
|
|
80
89
|
|
package/ui/fullscreen_button.js
CHANGED
|
@@ -32,6 +32,7 @@ shaka.ui.FullscreenButton = class extends shaka.ui.Element {
|
|
|
32
32
|
this.button_ = shaka.util.Dom.createButton();
|
|
33
33
|
this.button_.classList.add('shaka-fullscreen-button');
|
|
34
34
|
this.button_.classList.add('material-icons-round');
|
|
35
|
+
this.button_.classList.add('shaka-tooltip');
|
|
35
36
|
|
|
36
37
|
// Don't show the button if fullscreen is not supported
|
|
37
38
|
if (!document.fullscreenEnabled) {
|
package/ui/less/buttons.less
CHANGED
|
@@ -75,10 +75,6 @@
|
|
|
75
75
|
.shaka-current-time {
|
|
76
76
|
font-size: 14px;
|
|
77
77
|
color: rgb(255, 255, 255);
|
|
78
|
-
|
|
79
|
-
/* Make the time element the right size for the text, instead of defaulting
|
|
80
|
-
* to the same size as the rest of the controls. */
|
|
81
|
-
height: auto;
|
|
82
78
|
cursor: pointer;
|
|
83
79
|
|
|
84
80
|
&[disabled] {
|
package/ui/less/containers.less
CHANGED
|
@@ -195,6 +195,80 @@
|
|
|
195
195
|
align-items: center;
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
+
.shaka-statistics-container {
|
|
199
|
+
overflow-x: hidden;
|
|
200
|
+
overflow-y: auto;
|
|
201
|
+
|
|
202
|
+
min-width: 300px;
|
|
203
|
+
|
|
204
|
+
color: white;
|
|
205
|
+
background-color: rgba(35, 35, 35, 0.9);
|
|
206
|
+
|
|
207
|
+
font-size: 14px;
|
|
208
|
+
|
|
209
|
+
padding: 5px 10px;
|
|
210
|
+
border-radius: 2px;
|
|
211
|
+
|
|
212
|
+
position: absolute;
|
|
213
|
+
z-index: 2;
|
|
214
|
+
left: 15px;
|
|
215
|
+
top: 15px;
|
|
216
|
+
|
|
217
|
+
/* Fades out with the other controls. */
|
|
218
|
+
.show-when-controls-shown();
|
|
219
|
+
|
|
220
|
+
div {
|
|
221
|
+
display: flex;
|
|
222
|
+
justify-content: space-between;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
span {
|
|
226
|
+
color: rgb(150, 150, 150);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.shaka-context-menu {
|
|
231
|
+
background-color: rgba(35, 35, 35, 0.9);
|
|
232
|
+
|
|
233
|
+
border-radius: 2px;
|
|
234
|
+
|
|
235
|
+
position: absolute;
|
|
236
|
+
z-index: 3;
|
|
237
|
+
|
|
238
|
+
button {
|
|
239
|
+
padding: 5px 10px;
|
|
240
|
+
|
|
241
|
+
width: 100%;
|
|
242
|
+
display: flex;
|
|
243
|
+
align-items: center;
|
|
244
|
+
|
|
245
|
+
color: white;
|
|
246
|
+
background: transparent;
|
|
247
|
+
border: 0;
|
|
248
|
+
cursor: pointer;
|
|
249
|
+
|
|
250
|
+
&:hover {
|
|
251
|
+
background-color: rgba(50, 50, 50, 0.9);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
label {
|
|
256
|
+
padding: 0 20px;
|
|
257
|
+
|
|
258
|
+
align-items: flex-start;
|
|
259
|
+
|
|
260
|
+
color: white;
|
|
261
|
+
cursor: pointer;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.shaka-current-selection-span {
|
|
265
|
+
align-items: flex-start;
|
|
266
|
+
|
|
267
|
+
color: white;
|
|
268
|
+
cursor: pointer;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
198
272
|
.shaka-scrim-container {
|
|
199
273
|
margin: 0;
|
|
200
274
|
.fill-container();
|
|
@@ -229,13 +303,9 @@
|
|
|
229
303
|
transition-delay: 500ms;
|
|
230
304
|
|
|
231
305
|
/* These are defaults which are overridden by JS or cue styles. */
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
line-height: 1.4; // relative to font size.
|
|
236
|
-
background-color: rgba(0, 0, 0, 0.8);
|
|
237
|
-
color: rgb(255, 255, 255);
|
|
238
|
-
}
|
|
306
|
+
font-size: 20px;
|
|
307
|
+
line-height: 1.4; // relative to font size.
|
|
308
|
+
color: rgb(255, 255, 255);
|
|
239
309
|
|
|
240
310
|
span.shaka-text-wrapper {
|
|
241
311
|
display: inline;
|
|
@@ -141,13 +141,3 @@
|
|
|
141
141
|
/* TODO(b/116651454): eliminate hard-coded offsets */
|
|
142
142
|
left: 17px;
|
|
143
143
|
}
|
|
144
|
-
|
|
145
|
-
/* The captions button, when captions are on. */
|
|
146
|
-
.shaka-captions-on {
|
|
147
|
-
color: black;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/* The captions button, when captions are off. */
|
|
151
|
-
.shaka-captions-off {
|
|
152
|
-
color: grey;
|
|
153
|
-
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @license
|
|
3
|
+
* The tooltip is based on https://github.com/felipefialho/css-components/
|
|
4
|
+
* Local modifications have been performed.
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) 2017 Felipe Fialho
|
|
7
|
+
*
|
|
8
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
* in the Software without restriction, including without limitation the rights
|
|
11
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
* furnished to do so, subject to the following conditions:
|
|
14
|
+
*
|
|
15
|
+
* The above copyright notice and this permission notice shall be included in
|
|
16
|
+
* all copies or substantial portions of the Software.
|
|
17
|
+
*
|
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24
|
+
* SOFTWARE.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
@material-icons-width: 32px;
|
|
28
|
+
|
|
29
|
+
.translateX(@percent) {
|
|
30
|
+
-webkit-transform: translateX(percentage(@percent));
|
|
31
|
+
-moz-transform: translateX(percentage(@percent));
|
|
32
|
+
-ms-transform: translateX(percentage(@percent));
|
|
33
|
+
-o-transform: translateX(percentage(@percent));
|
|
34
|
+
transform: translateX(percentage(@percent));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* .shaka-tooltips-on enables the tooltips and is only added to the
|
|
38
|
+
* control panel when the 'enableTooltips' option is set to true */
|
|
39
|
+
.shaka-tooltips-on {
|
|
40
|
+
overflow: visible;
|
|
41
|
+
|
|
42
|
+
& > [class*="shaka-tooltip"] {
|
|
43
|
+
position: relative;
|
|
44
|
+
|
|
45
|
+
/* The :after pseudo-element contains the tooltip */
|
|
46
|
+
&:hover:after, &:focus-visible:after, &:active:after {
|
|
47
|
+
content: attr(aria-label);
|
|
48
|
+
|
|
49
|
+
/* Override .material-icons-round text styling */
|
|
50
|
+
font-family: Roboto-Regular, Roboto, sans-serif;
|
|
51
|
+
line-height: @material-icons-width / 2;
|
|
52
|
+
white-space: nowrap;
|
|
53
|
+
font-size: 13px;
|
|
54
|
+
|
|
55
|
+
/* Styling */
|
|
56
|
+
background: rgba(35, 35, 35, 0.9);
|
|
57
|
+
color: white;
|
|
58
|
+
border-radius: 3px;
|
|
59
|
+
padding: 5px 10px;
|
|
60
|
+
|
|
61
|
+
/* Positioning */
|
|
62
|
+
position: absolute;
|
|
63
|
+
bottom: @material-icons-width + 5px;
|
|
64
|
+
|
|
65
|
+
/* Left attribute is set to half of the width of the parent button */
|
|
66
|
+
left: @material-icons-width / 2;
|
|
67
|
+
|
|
68
|
+
/* The tooltip is also translated 50% to appear centered */
|
|
69
|
+
.translateX(-0.5);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* Adds an additional attribute for the status in .shaka-tooltip-status */
|
|
74
|
+
& > .shaka-tooltip-status {
|
|
75
|
+
&:hover:after, &:focus-visible:after, &:active:after {
|
|
76
|
+
content: attr(aria-label) " (" attr(shaka-status) ")";
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* The first tooltip of the panel is not centered on top of the button
|
|
81
|
+
* but rather aligned with the left border of the control panel */
|
|
82
|
+
button:first-child {
|
|
83
|
+
&:hover:after, &:focus-visible:after, &:active:after {
|
|
84
|
+
left: 0;
|
|
85
|
+
.translateX(0);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* The last tooltip of the panel is not centered on top of the button
|
|
90
|
+
* but rather aligned with the right border of the control panel */
|
|
91
|
+
button:last-child {
|
|
92
|
+
&:hover:after, &:focus-visible:after,&:active:after {
|
|
93
|
+
left: @material-icons-width;
|
|
94
|
+
.translateX(-1);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
package/ui/locales/en.json
CHANGED
package/ui/locales/ru.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"AD_DURATION": "Продолжительность
|
|
3
|
-
"AD_PROGRESS": "
|
|
4
|
-
"AD_TIME": "
|
|
2
|
+
"AD_DURATION": "Продолжительность рекламы",
|
|
3
|
+
"AD_PROGRESS": "Реклама [AD_ON] из [NUM_ADS]",
|
|
4
|
+
"AD_TIME": "Реклама: [AD_TIME]",
|
|
5
5
|
"AUTO_QUALITY": "Авто",
|
|
6
6
|
"BACK": "Назад",
|
|
7
|
-
"CAPTIONS": "
|
|
7
|
+
"CAPTIONS": "Субтитры",
|
|
8
8
|
"CAST": "Транслировать...",
|
|
9
9
|
"ENTER_LOOP_MODE": "Зациклить текущее видео",
|
|
10
10
|
"ENTER_PICTURE_IN_PICTURE": "Перейти в режим \"Картинка в картинке\"",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"MULTIPLE_LANGUAGES": "Несколько языков",
|
|
21
21
|
"MUTE": "Отключить звук",
|
|
22
22
|
"NOT_APPLICABLE": "Неприменимо",
|
|
23
|
-
"OFF": "
|
|
24
|
-
"ON": "
|
|
23
|
+
"OFF": "Выкл.",
|
|
24
|
+
"ON": "Вкл.",
|
|
25
25
|
"PAUSE": "Пауза",
|
|
26
26
|
"PICTURE_IN_PICTURE": "Картинка в картинке",
|
|
27
27
|
"PLAY": "Воспроизвести",
|
package/ui/locales/source.json
CHANGED
|
@@ -138,6 +138,10 @@
|
|
|
138
138
|
"description": "Label for a button used to skip ahead to the live broadcast.",
|
|
139
139
|
"message": "Skip ahead to live"
|
|
140
140
|
},
|
|
141
|
+
"STATISTICS": {
|
|
142
|
+
"description": "Label for a button that displays statistics of the video.",
|
|
143
|
+
"message": "Statistics"
|
|
144
|
+
},
|
|
141
145
|
"SUBTITLE_FORCED": {
|
|
142
146
|
"description": "Label used to identify a subtitle track that is forced to be shown.",
|
|
143
147
|
"message": "Forced"
|