shaka-player 2.5.1 → 2.5.5

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.
Files changed (166) hide show
  1. package/.csslintrc +13 -0
  2. package/AUTHORS +3 -0
  3. package/CHANGELOG.md +156 -0
  4. package/CONTRIBUTORS +3 -0
  5. package/README.md +3 -0
  6. package/build/README.md +5 -5
  7. package/build/apps.py +3 -1
  8. package/build/build.py +5 -2
  9. package/build/check.py +17 -0
  10. package/build/compiler.py +49 -0
  11. package/build/conformance.textproto +1 -0
  12. package/build/docs.py +0 -6
  13. package/build/generateExterns.js +72 -20
  14. package/build/install-linux-prereqs.sh +4 -4
  15. package/build/shakaBuildHelpers.py +7 -8
  16. package/build/test.py +21 -9
  17. package/build/types/core +1 -0
  18. package/build/types/ui +6 -1
  19. package/demo/asset_card.js +129 -41
  20. package/demo/cast_receiver/receiver_app.css +27 -13
  21. package/demo/close_button.js +10 -15
  22. package/demo/common/asset.js +6 -6
  23. package/demo/common/assets.js +72 -14
  24. package/demo/config.js +28 -25
  25. package/demo/custom.js +20 -16
  26. package/demo/demo.less +107 -16
  27. package/demo/demo_uncompiled.js +33 -0
  28. package/demo/demo_utils.js +4 -3
  29. package/demo/front.js +12 -8
  30. package/demo/index.html +14 -17
  31. package/demo/input.js +30 -23
  32. package/demo/input_container.js +15 -11
  33. package/demo/load.js +5 -7
  34. package/demo/main.js +138 -49
  35. package/demo/search.js +40 -36
  36. package/demo/service_worker.js +1 -1
  37. package/demo/tooltip.js +16 -24
  38. package/dist/.csslintstamp +0 -0
  39. package/dist/controls.css +1 -1
  40. package/dist/controls.css.map +1 -1
  41. package/dist/demo.compiled.debug.js +165 -152
  42. package/dist/demo.compiled.debug.map +4 -4
  43. package/dist/demo.compiled.js +165 -152
  44. package/dist/demo.compiled.map +4 -4
  45. package/dist/demo.css +1 -1
  46. package/dist/demo.css.map +1 -1
  47. package/dist/deps.js +28 -11
  48. package/dist/receiver.compiled.debug.js +11 -11
  49. package/dist/receiver.compiled.debug.map +3 -3
  50. package/dist/receiver.compiled.js +11 -11
  51. package/dist/receiver.compiled.map +3 -3
  52. package/dist/shaka-player.compiled.debug.externs.js +232 -102
  53. package/dist/shaka-player.compiled.debug.js +189 -165
  54. package/dist/shaka-player.compiled.debug.map +4 -4
  55. package/dist/shaka-player.compiled.externs.js +232 -102
  56. package/dist/shaka-player.compiled.js +567 -553
  57. package/dist/shaka-player.compiled.map +4 -4
  58. package/dist/shaka-player.ui.debug.externs.js +338 -113
  59. package/dist/shaka-player.ui.debug.js +296 -276
  60. package/dist/shaka-player.ui.debug.map +4 -4
  61. package/dist/shaka-player.ui.externs.js +338 -113
  62. package/dist/shaka-player.ui.js +685 -671
  63. package/dist/shaka-player.ui.map +4 -4
  64. package/docs/tutorials/drm-config.md +1 -0
  65. package/docs/tutorials/fairplay.md +77 -0
  66. package/docs/tutorials/index.json +1 -0
  67. package/docs/tutorials/manifest-parser.md +1 -1
  68. package/docs/tutorials/ui-customization.md +5 -2
  69. package/docs/tutorials/ui.md +10 -4
  70. package/docs/tutorials/welcome.md +2 -2
  71. package/externs/mediasession.js +16 -1
  72. package/externs/shaka/net.js +14 -4
  73. package/externs/shaka/player.js +136 -90
  74. package/externs/tippy.js +30 -0
  75. package/externs/webkitmediakeys.js +4 -0
  76. package/karma.conf.js +30 -24
  77. package/lib/cast/cast_proxy.js +94 -23
  78. package/lib/cast/cast_receiver.js +8 -1
  79. package/lib/dash/content_protection.js +33 -1
  80. package/lib/dash/dash_parser.js +13 -5
  81. package/lib/hls/hls_parser.js +20 -4
  82. package/lib/media/drm_engine.js +29 -2
  83. package/lib/media/media_source_engine.js +9 -6
  84. package/lib/media/play_rate_controller.js +14 -3
  85. package/lib/media/playhead.js +8 -3
  86. package/lib/media/streaming_engine.js +68 -20
  87. package/lib/media/transmuxer.js +2 -2
  88. package/lib/media/video_wrapper.js +8 -3
  89. package/lib/net/data_uri_plugin.js +5 -2
  90. package/lib/net/http_fetch_plugin.js +3 -3
  91. package/lib/net/http_plugin_utils.js +2 -4
  92. package/lib/net/http_xhr_plugin.js +2 -2
  93. package/lib/net/networking_engine.js +1 -0
  94. package/lib/offline/offline_scheme.js +7 -2
  95. package/lib/player.js +18 -8
  96. package/lib/polyfill/input_event.js +7 -11
  97. package/lib/polyfill/mediasource.js +1 -1
  98. package/lib/polyfill/patchedmediakeys_apple.js +2 -72
  99. package/lib/text/cue.js +1 -1
  100. package/lib/text/ttml_text_parser.js +1 -1
  101. package/lib/util/config_utils.js +1 -0
  102. package/lib/util/error.js +45 -11
  103. package/lib/util/event_manager.js +211 -100
  104. package/lib/util/fairplay_utils.js +122 -0
  105. package/lib/util/i_releasable.js +1 -0
  106. package/lib/util/player_configuration.js +7 -0
  107. package/lib/util/pssh.js +41 -0
  108. package/lib/util/string_utils.js +42 -6
  109. package/lib/util/timer.js +1 -1
  110. package/package.json +33 -33
  111. package/roadmap.md +96 -0
  112. package/shaka-player.uncompiled.js +5 -1
  113. package/test/dash/dash_parser_content_protection_unit.js +35 -1
  114. package/test/dash/dash_parser_manifest_unit.js +60 -0
  115. package/test/hls/hls_live_unit.js +7 -1
  116. package/test/hls/hls_parser_unit.js +50 -0
  117. package/test/media/drm_engine_unit.js +10 -4
  118. package/test/media/media_source_engine_integration.js +12 -0
  119. package/test/media/media_source_engine_unit.js +3 -1
  120. package/test/media/playhead_unit.js +7 -5
  121. package/test/media/streaming_engine_unit.js +46 -1
  122. package/test/media/transmuxer_integration.js +13 -0
  123. package/test/net/data_uri_plugin_unit.js +13 -2
  124. package/test/net/http_plugin_unit.js +17 -12
  125. package/test/net/networking_engine_unit.js +17 -8
  126. package/test/offline/offline_scheme_unit.js +18 -8
  127. package/test/player_external.js +3 -2
  128. package/test/player_integration.js +94 -3
  129. package/test/player_src_equals_integration.js +2 -2
  130. package/test/player_unit.js +21 -8
  131. package/test/test/boot.js +20 -5
  132. package/test/test/externs/jasmine.js +48 -0
  133. package/test/test/util/expect_async_polyfill.js +145 -0
  134. package/test/test/util/fake_networking_engine.js +1 -0
  135. package/test/test/util/manifest_generator.js +2 -1
  136. package/test/test/util/test_scheme.js +34 -2
  137. package/test/test/util/ui_utils.js +41 -0
  138. package/test/test/util/util.js +16 -8
  139. package/test/ui/ui_unit.js +130 -4
  140. package/ui/audio_language_selection.js +17 -96
  141. package/ui/big_play_button.js +61 -0
  142. package/ui/controls.js +226 -335
  143. package/ui/controls.less +3 -5
  144. package/ui/element.js +24 -6
  145. package/ui/externs/ui.js +62 -9
  146. package/ui/fullscreen_button.js +2 -52
  147. package/ui/less/buttons.less +10 -16
  148. package/ui/less/containers.less +75 -20
  149. package/ui/less/general.less +18 -2
  150. package/ui/less/other_elements.less +2 -1
  151. package/ui/less/overflow_menu.less +11 -10
  152. package/ui/less/range_elements.less +12 -10
  153. package/ui/less/spinner.less +2 -0
  154. package/ui/overflow_menu.js +1 -1
  155. package/ui/pip_button.js +1 -1
  156. package/ui/{play_pause_button.js → play_button.js} +17 -47
  157. package/ui/presentation_time.js +17 -12
  158. package/ui/range_element.js +176 -0
  159. package/ui/resolution_selection.js +43 -106
  160. package/ui/seek_bar.js +204 -0
  161. package/ui/settings_menu.js +113 -0
  162. package/ui/small_play_button.js +73 -0
  163. package/ui/text_displayer.js +17 -14
  164. package/ui/text_selection.js +42 -107
  165. package/ui/ui.js +17 -40
  166. package/ui/volume_bar.js +40 -68
package/ui/controls.less CHANGED
@@ -22,7 +22,6 @@
22
22
  @import "less/spinner.less";
23
23
  @import "less/other_elements.less";
24
24
  @import "less/overflow_menu.less";
25
-
26
25
  @import (css, inline) "https://fonts.googleapis.com/css?family=Roboto";
27
26
  @import (css, inline) "https://fonts.googleapis.com/icon?family=Material+Icons";
28
27
 
@@ -35,6 +34,7 @@
35
34
  font-size: 150%;
36
35
  padding: 5px;
37
36
 
37
+ /* dimensions */
38
38
  bottom: 50px;
39
39
  left: 0;
40
40
  right: 0;
@@ -53,12 +53,10 @@ to make them override display setting previously set in
53
53
  .overflowMenu button.
54
54
  See https://goo.gl/egXAJY for explanation of
55
55
  how CSS cascade rules work. */
56
- button.shaka-hidden,
57
- .shaka-hidden {
56
+ button.shaka-hidden, .shaka-hidden {
58
57
  .hidden();
59
58
  }
60
59
 
61
- button.shaka-displayed,
62
- .shaka-displayed {
60
+ button.shaka-displayed, .shaka-displayed {
63
61
  display: flex;
64
62
  }
package/ui/element.js CHANGED
@@ -32,22 +32,40 @@ shaka.ui.Element = class {
32
32
  * @param {!shaka.ui.Controls} controls
33
33
  */
34
34
  constructor(parent, controls) {
35
- /** @protected {HTMLElement} */
35
+ /**
36
+ * @protected {HTMLElement}
37
+ * @exportInterface
38
+ */
36
39
  this.parent = parent;
37
40
 
38
- /** @protected {shaka.ui.Controls} */
41
+ /**
42
+ * @protected {shaka.ui.Controls}
43
+ * @exportInterface
44
+ */
39
45
  this.controls = controls;
40
46
 
41
- /** @protected {shaka.util.EventManager} */
47
+ /**
48
+ * @protected {shaka.util.EventManager}
49
+ * @exportInterface
50
+ */
42
51
  this.eventManager = new shaka.util.EventManager();
43
52
 
44
- /** @protected {shaka.ui.Localization} */
53
+ /**
54
+ * @protected {shaka.ui.Localization}
55
+ * @exportInterface
56
+ */
45
57
  this.localization = this.controls.getLocalization();
46
58
 
47
- /** @protected {shaka.Player} */
59
+ /**
60
+ * @protected {shaka.Player}
61
+ * @exportInterface
62
+ */
48
63
  this.player = this.controls.getPlayer();
49
64
 
50
- /** @protected {HTMLMediaElement} */
65
+ /**
66
+ * @protected {HTMLMediaElement}
67
+ * @exportInterface
68
+ */
51
69
  this.video = this.controls.getVideo();
52
70
  }
53
71
 
package/ui/externs/ui.js CHANGED
@@ -34,7 +34,9 @@ shaka.extern = {};
34
34
  * controlPanelElements: !Array.<string>,
35
35
  * overflowMenuButtons: !Array.<string>,
36
36
  * addSeekBar: boolean,
37
- * castReceiverAppId: string
37
+ * addBigPlayButton: boolean,
38
+ * castReceiverAppId: string,
39
+ * clearBufferOnQualityChange: boolean
38
40
  * }}
39
41
  *
40
42
  * @property {!Array.<string>} controlPanelElements
@@ -43,9 +45,19 @@ shaka.extern = {};
43
45
  * The ordered list of the overflow menu buttons.
44
46
  * @property {boolean} addSeekBar
45
47
  * Whether or not a seek bar should be part of the UI.
48
+ * @property {boolean} addBigPlayButton
49
+ * Whether or not a big play button in the center of the video
50
+ * should be part of the UI.
46
51
  * @property {string} castReceiverAppId
47
52
  * Receiver app id to use for the Chromecast support.
48
- * @exportDoc
53
+ * @property {boolean} clearBufferOnQualityChange
54
+ * Only applicable if the resolution selection is part of the UI.
55
+ * Whether buffer should be cleared when changing resolution
56
+ * via UI. Clearing buffer would result in immidiate change of quality,
57
+ * but playback may flicker/stall for a sec as the content in new
58
+ * resolution is being buffered. Not clearing the buffer will mean
59
+ * we play the content in the previously selected resolution that we
60
+ * already have buffered before switching to the new resolution.
49
61
  */
50
62
  shaka.extern.UIConfiguration;
51
63
 
@@ -57,7 +69,54 @@ shaka.extern.UIConfiguration;
57
69
  * @interface
58
70
  * @exportDoc
59
71
  */
60
- shaka.extern.IUIElement = class {};
72
+ shaka.extern.IUIElement = class {
73
+ /**
74
+ * @param {!HTMLElement} parent
75
+ * @param {!shaka.ui.Controls} controls
76
+ */
77
+ constructor(parent, controls) {
78
+ /**
79
+ * @protected {HTMLElement}
80
+ * @exportDoc
81
+ */
82
+ this.parent;
83
+
84
+ /**
85
+ * @protected {shaka.ui.Controls}
86
+ * @exportDoc
87
+ */
88
+ this.controls;
89
+
90
+ /**
91
+ * @protected {shaka.util.EventManager}
92
+ * @exportDoc
93
+ */
94
+ this.eventManager;
95
+
96
+ /**
97
+ * @protected {shaka.ui.Localization}
98
+ * @exportDoc
99
+ */
100
+ this.localization;
101
+
102
+ /**
103
+ * @protected {shaka.Player}
104
+ * @exportDoc
105
+ */
106
+ this.player;
107
+
108
+ /**
109
+ * @protected {HTMLMediaElement}
110
+ * @exportDoc
111
+ */
112
+ this.video;
113
+ }
114
+
115
+ /**
116
+ * @override
117
+ */
118
+ destroy() {}
119
+ };
61
120
 
62
121
 
63
122
  /**
@@ -74,9 +133,3 @@ shaka.extern.IUIElement.Factory = class {
74
133
  */
75
134
  create(rootElement, controls) {}
76
135
  };
77
-
78
-
79
- /**
80
- * @exportDoc
81
- */
82
- shaka.extern.IUIElement.prototype.destroy = function() {};
@@ -51,9 +51,6 @@ shaka.ui.FullscreenButton = class extends shaka.ui.Element {
51
51
  this.parent.appendChild(this.button_);
52
52
  this.updateAriaLabel_();
53
53
 
54
- /** @private {!HTMLElement} */
55
- this.videoContainer_ = this.controls.getVideoContainer();
56
-
57
54
  this.eventManager.listen(
58
55
  this.localization, shaka.ui.Localization.LOCALE_UPDATED, () => {
59
56
  this.updateAriaLabel_();
@@ -65,14 +62,8 @@ shaka.ui.FullscreenButton = class extends shaka.ui.Element {
65
62
  });
66
63
 
67
64
  this.eventManager.listen(this.button_, 'click', () => {
68
- this.toggleFullScreen_();
69
- });
70
-
71
- if (screen.orientation) {
72
- this.eventManager.listen(screen.orientation, 'change', () => {
73
- this.onScreenRotation_();
74
- });
75
- }
65
+ this.controls.toggleFullScreen();
66
+ });
76
67
 
77
68
  this.eventManager.listen(document, 'fullscreenchange', () => {
78
69
  this.updateIcon_();
@@ -101,47 +92,6 @@ shaka.ui.FullscreenButton = class extends shaka.ui.Element {
101
92
  shaka.ui.Enums.MaterialDesignIcons.EXIT_FULLSCREEN :
102
93
  shaka.ui.Enums.MaterialDesignIcons.FULLSCREEN;
103
94
  }
104
-
105
- /**
106
- * @private
107
- */
108
- async toggleFullScreen_() {
109
- if (document.fullscreenElement) {
110
- document.exitFullscreen();
111
- } else {
112
- // If you are in PiP mode, leave PiP mode first.
113
- try {
114
- if (document.pictureInPictureElement) {
115
- await document.exitPictureInPicture();
116
- }
117
- } catch (error) {
118
- this.controls.dispatchEvent(new shaka.util.FakeEvent('error', {
119
- detail: error,
120
- }));
121
- }
122
- await this.videoContainer_.requestFullscreen();
123
- }
124
- }
125
-
126
- /**
127
- * When a mobile device is rotated to landscape layout, and the video is
128
- * loaded, make the demo app go into fullscreen.
129
- * Similarly, exit fullscreen when the device is rotated to portrait layout.
130
- * @private
131
- */
132
- onScreenRotation_() {
133
- if (!this.video ||
134
- this.video.readyState == 0 ||
135
- this.controls.getCastProxy().isCasting()) return;
136
-
137
- if (screen.orientation.type.includes('landscape') &&
138
- !document.fullscreenElement) {
139
- this.videoContainer_.requestFullscreen();
140
- } else if (screen.orientation.type.includes('portrait') &&
141
- document.fullscreenElement) {
142
- document.exitFullscreen();
143
- }
144
- }
145
95
  };
146
96
 
147
97
 
@@ -19,8 +19,7 @@
19
19
 
20
20
  @play-button-size-percentage: 15%;
21
21
 
22
- /* The giant play button, which sits inside .shaka-player-button-container and
23
- * contains the buffering spinner. */
22
+ /* The giant play button, which sits inside .shaka-player-button-container. */
24
23
  .shaka-play-button {
25
24
  /* Set width & height in a round-about way. By using padding, we can keep
26
25
  * a 1:1 aspect ratio and size the button relative to the container width.
@@ -34,11 +33,6 @@
34
33
  width: 0;
35
34
  height: 0;
36
35
 
37
- /* The width/height hack above requires this to behave as an overlay
38
- * container, and the spinner to behave as an overlay child. Otherwise, the
39
- * spinner constrains to the content area size (0x0). */
40
- .overlay-parent();
41
-
42
36
  /* To be properly positioned in the center, this should have no margin.
43
37
  * This might have been set for buttons generally by the app or user-agent. */
44
38
  margin: 0;
@@ -47,7 +41,7 @@
47
41
  border-radius: 50%;
48
42
 
49
43
  /* A small drop shadow below the button. */
50
- box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 20px 0px;
44
+ box-shadow: rgba(0, 0, 0, 0.1) 0 0 20px 0;
51
45
 
52
46
  /* No border. */
53
47
  border: none;
@@ -58,8 +52,9 @@
58
52
  background-size: 50%;
59
53
  background-repeat: no-repeat;
60
54
  background-position: center center;
55
+
61
56
  /* A background color behind the play arrow. */
62
- background-color: rgba(255, 255, 255, .9);
57
+ background-color: rgba(255, 255, 255, 0.9);
63
58
 
64
59
  /* Actual icon images for the two states this could be in.
65
60
  * These will be inlined as data URIs when compiled, and so do not need to be
@@ -68,6 +63,7 @@
68
63
  &[icon="play"] {
69
64
  background-image: data-uri('images/play_arrow.svg');
70
65
  }
66
+
71
67
  &[icon="pause"] {
72
68
  background-image: data-uri('images/pause.svg');
73
69
  }
@@ -78,7 +74,7 @@
78
74
  * edge. Otherwise, the button is disabled.
79
75
  */
80
76
  .shaka-current-time {
81
- font-size: 16px;
77
+ font-size: 14px;
82
78
  color: rgb(255, 255, 255);
83
79
 
84
80
  /* Make the time element the right size for the text, instead of defaulting
@@ -97,11 +93,11 @@
97
93
 
98
94
  /* Use a consistent outline focus style across browsers. */
99
95
  .shaka-controls-container {
100
- button:focus,
101
- input:focus {
96
+ button:focus, input:focus {
102
97
  /* Most browsers will fall back to "Highlight" (system setting) color for
103
98
  * the focus outline. */
104
99
  outline: 1px solid Highlight;
100
+
105
101
  /* WebKit-based and Blink-based browsers have this as their default outline
106
102
  * color. */
107
103
  outline: 1px solid -webkit-focus-ring-color;
@@ -109,8 +105,7 @@
109
105
 
110
106
  /* Disable this Mozilla-specific focus ring, since we have an outline defined
111
107
  * for focus. */
112
- button::-moz-focus-inner,
113
- input::-moz-focus-outer {
108
+ button:-moz-focus-inner, input:-moz-focus-outer {
114
109
  outline: none;
115
110
  border: 0;
116
111
  }
@@ -120,8 +115,7 @@
120
115
  * it doesn't look great. This removes the outline for
121
116
  * mouse users while leaving it for keyboard users. */
122
117
  .shaka-controls-container:not(.shaka-keyboard-navigation) {
123
- button:focus,
124
- input:focus {
118
+ button:focus, input:focus {
125
119
  outline: none;
126
120
  border: 0;
127
121
  }
@@ -17,6 +17,8 @@
17
17
 
18
18
  /* All of the top-level containers into which various visible features go. */
19
19
 
20
+ @transparent: rgba(0, 0, 0, 0);
21
+
20
22
  /* A container for the entire video + controls combo. This is the auto-setup
21
23
  * div which we populate. */
22
24
  .shaka-video-container {
@@ -31,6 +33,7 @@
31
33
  .material-icons {
32
34
  font-family: 'Material Icons';
33
35
  }
36
+
34
37
  * {
35
38
  font-family: Roboto-Regular, Roboto, sans-serif;
36
39
  }
@@ -43,9 +46,16 @@
43
46
  * single delcaration. Browsers ignore the rest of the list once they hit one
44
47
  * pseudo-class they don't support. */
45
48
  .fullscreen-container() {
46
- width: 100%;
47
- height: 100%;
49
+ .fill-container();
50
+
48
51
  background-color: black;
52
+
53
+ .shaka-text-container {
54
+ /* In fullscreen mode, the text displayer's font size should be relative to
55
+ * the either window height or width (whichever is smaller), instead of a
56
+ * fixed size. */
57
+ font-size: 4.4vmin;
58
+ }
49
59
  }
50
60
  .shaka-video-container:fullscreen { .fullscreen-container(); }
51
61
  .shaka-video-container:-webkit-full-screen { .fullscreen-container(); }
@@ -67,28 +77,23 @@
67
77
  .shaka-controls-container {
68
78
  .overlay-child();
69
79
 
70
- /* The padding defines a region around the video in which controls cannot
71
- * exist. The two-value settings are shorthand for vertical followed by
72
- * horizontal. */
73
- padding: 12px 5px;
74
-
75
80
  /* Without this, the controls container overflows the video container. */
76
81
  box-sizing: border-box;
77
82
 
78
83
  /* A flex container, to make layout of children easier to reason about. */
79
84
  display: flex;
85
+
80
86
  /* Defines in which direction the children should flow. */
81
87
  flex-direction: column;
88
+
82
89
  /* Pushes the children toward the bottom of the container. */
83
90
  justify-content: flex-end;
91
+
84
92
  /* Centers children horizontally. */
85
93
  align-items: center;
86
94
 
87
95
  /* A black gradient at the bottom, behind the controls, but only so high. */
88
- background: linear-gradient(
89
- to top,
90
- rgba(0, 0, 0, 1) 0,
91
- rgba(0, 0, 0, 0) 92px);
96
+ background: linear-gradient(to top, rgba(0, 0, 0, 1) 0, @transparent 92px);
92
97
 
93
98
  /* By default, do not allow any of our controls to shrink.
94
99
  * Specific controls can use .shrinkable() to override. */
@@ -98,7 +103,7 @@
98
103
  opacity: 0;
99
104
 
100
105
  /* When we show/hide this, do it gradually using cubic-bezier timing. */
101
- transition: opacity cubic-bezier(0.4, 0.0, 0.6, 1) 600ms;
106
+ transition: opacity cubic-bezier(0.4, 0, 0.6, 1) 600ms;
102
107
 
103
108
  /* Position the controls container in front of the text container, so that
104
109
  * the text container doesn't interfere with the control buttons. */
@@ -119,6 +124,22 @@
119
124
  }
120
125
  }
121
126
 
127
+ /* Container for controls positioned at the bottom of the video container:
128
+ * controls button panel and the seek bar. */
129
+ .shaka-bottom-controls {
130
+ width: 98%;
131
+ padding: 0;
132
+ padding-left: 2%;
133
+ padding-bottom: 2.5%;
134
+
135
+ /* Position the bottom panel in front of other controls (play button and
136
+ * spinner containers).
137
+ * TODO: A different layout arrangement might be a better solution for this.
138
+ * Need to experiment.
139
+ */
140
+ z-index: 1;
141
+ }
142
+
122
143
  /* This is the container for the horizontal row of controls above the seek bar.
123
144
  * It sits above (Y axis) the seek bar, and below (Y axis) the giant play button
124
145
  * in the middle. */
@@ -131,8 +152,10 @@
131
152
  /* This is itself a flex container, with children layed out horizontally. */
132
153
  display: flex;
133
154
  flex-direction: row;
155
+
134
156
  /* Push children to the right. */
135
157
  justify-content: flex-end;
158
+
136
159
  /* Center children vertically. */
137
160
  align-items: center;
138
161
 
@@ -177,9 +200,9 @@
177
200
  /* Take up as much space as possible, but shrink (vertically) to accomodate
178
201
  * the controls at the bottom. */
179
202
  margin: 0;
180
- width: 100%;
181
- height: 100%;
203
+ .fill-container();
182
204
  .shrinkable();
205
+ .absolute-position();
183
206
 
184
207
  /* Keep the play button in the middle of this container. */
185
208
  display: flex;
@@ -188,11 +211,12 @@
188
211
  }
189
212
 
190
213
  .shaka-text-container {
214
+ .absolute-position();
215
+
191
216
  bottom: 15%;
192
- top: 0;
193
- left: 0;
194
217
  width: 100%;
195
218
  min-width: 48px;
219
+ text-align: center;
196
220
 
197
221
  /* Set the captions in the middle horizontally by default. */
198
222
  display: flex;
@@ -205,13 +229,44 @@
205
229
  * overflow content. */
206
230
  overflow: hidden;
207
231
 
208
- text-align: center;
209
- position: absolute;
232
+ /* These are defaults which are overridden by JS or cue styles. */
233
+ font-size: 20px;
234
+ line-height: 1.4; // relative to font size.
210
235
 
211
236
  span {
212
- font-size: 18px;
237
+ /* These are defaults which are overridden by JS or cue styles. */
238
+ background-color: rgba(0, 0, 0, 0.8);
213
239
  color: rgb(255, 255, 255);
214
240
  display: block;
215
- max-width:95%;
241
+ max-width: 95%;
216
242
  }
217
243
  }
244
+
245
+ /* The buffering spinner. */
246
+ .shaka-spinner-container {
247
+ .absolute-position();
248
+ .fill-container();
249
+
250
+ flex-shrink: 1;
251
+ display: flex;
252
+ justify-content: center;
253
+ align-items: center;
254
+ }
255
+
256
+ @spinner-size-percentage: 15.6%;
257
+
258
+ .shaka-spinner {
259
+ /* This uses the same trickery as the big play button define
260
+ the spinner's width and height. See .shaka-play-button
261
+ for the detailed explanation. */
262
+
263
+ /* For the padding thing to work, spinner div needs to be an
264
+ overlay-parent and spinner svg - an overlay child. */
265
+ .overlay-parent();
266
+
267
+ margin: 0;
268
+ box-sizing: border-box;
269
+ padding: @spinner-size-percentage / 2;
270
+ width: 0;
271
+ height: 0;
272
+ }
@@ -30,6 +30,11 @@
30
30
  display: none;
31
31
  }
32
32
 
33
+ .fill-container() {
34
+ width: 100%;
35
+ height: 100%;
36
+ }
37
+
33
38
  /* For containers which host elements overlaying other things. */
34
39
  .overlay-parent() {
35
40
  /* For a detailed explanation of how this achieves an overlay, please refer
@@ -66,10 +71,21 @@
66
71
  left: 0;
67
72
  right: 0;
68
73
  bottom: 0;
69
- width: 100%;
70
- height: 100%;
71
74
  margin: 0;
72
75
  padding: 0;
76
+
77
+ .fill-container();
78
+ }
79
+
80
+ .absolute-position() {
81
+ /* When setting "position: absolute" it uses the left,right,top,bottom
82
+ * properties to determine the positioning. We should set all these
83
+ * properties to ensure it is positioned properly on all platforms. */
84
+ position: absolute;
85
+ left: 0;
86
+ right: 0;
87
+ top: 0;
88
+ bottom: 0;
73
89
  }
74
90
 
75
91
  /* For things that should not shrink inside a flex container.
@@ -29,6 +29,7 @@
29
29
  /* Make the element grow to take up the remaining space. */
30
30
  flex-grow: 1;
31
31
 
32
- /* Margins don't shrink. Remove margins in order to be more flexible when shrinking. */
32
+ /* Margins don't shrink. Remove margins in order to be more flexible when
33
+ * shrinking. */
33
34
  margin: 0;
34
35
  }
@@ -29,7 +29,7 @@
29
29
 
30
30
  /* Styles for the menu itself. */
31
31
  background: white;
32
- box-shadow: 0 1px 9px 0 rgba(0,0,0,0.40);
32
+ box-shadow: 0 1px 9px 0 rgba(0, 0, 0, 0.4);
33
33
  border-radius: 2px;
34
34
  max-height: 250px;
35
35
  min-width: 180px;
@@ -64,20 +64,21 @@
64
64
  &:hover {
65
65
  background: rgb(224, 224, 224);
66
66
  }
67
+
67
68
  .shaka-keyboard-navigation &:focus {
68
69
  background: rgb(224, 224, 224);
69
70
  }
70
71
  }
71
72
 
72
- /* These are the elements which contain the material design icons. */
73
- /* TODO: Pull MD icon details out of JS. */
73
+ /* These are the elements which contain the material design icons.
74
+ * TODO: Pull MD icon details out of JS. */
74
75
  i {
75
76
  /* TODO(b/116651454): eliminate hard-coded offsets */
76
77
  padding-left: 10px;
77
78
  }
78
79
 
79
- /* If the seekbar is missing, this is positioned lower. */
80
- /* TODO: Solve with flex layout instead? */
80
+ /* If the seekbar is missing, this is positioned lower.
81
+ * TODO: Solve with flex layout instead? */
81
82
  &.shaka-low-position {
82
83
  /* TODO(b/116651454): eliminate hard-coded offsets */
83
84
  bottom: 15px;
@@ -93,6 +94,7 @@
93
94
  .shaka-overflow-menu span {
94
95
  text-align: left;
95
96
  position: relative;
97
+
96
98
  /* TODO(b/116651454): eliminate hard-coded offsets */
97
99
  left: 13px;
98
100
  }
@@ -101,6 +103,7 @@
101
103
  * right of MD icons. */
102
104
  .shaka-overflow-button-label {
103
105
  position: relative;
106
+
104
107
  /* This is a flex container, whose children flow vertically. */
105
108
  display: flex;
106
109
  flex-direction: column;
@@ -114,12 +117,10 @@
114
117
  color: rgba(0, 0, 0, 0.54);
115
118
  }
116
119
 
117
- /* These three submenus have somewhat different margins inside them. */
118
- /* TODO: This is all submenus, but not the top-level menu. Is there a better
120
+ /* These three submenus have somewhat different margins inside them.
121
+ * TODO: This is all submenus, but not the top-level menu. Is there a better
119
122
  * way to express this? */
120
- .shaka-resolutions,
121
- .shaka-audio-languages,
122
- .shaka-text-languages {
123
+ .shaka-resolutions, .shaka-audio-languages, .shaka-text-languages {
123
124
  span {
124
125
  /* TODO(b/116651454): eliminate hard-coded offsets */
125
126
  margin-left: 54px;