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.
- package/.csslintrc +13 -0
- package/AUTHORS +3 -0
- package/CHANGELOG.md +156 -0
- package/CONTRIBUTORS +3 -0
- package/README.md +3 -0
- package/build/README.md +5 -5
- package/build/apps.py +3 -1
- package/build/build.py +5 -2
- package/build/check.py +17 -0
- package/build/compiler.py +49 -0
- package/build/conformance.textproto +1 -0
- package/build/docs.py +0 -6
- package/build/generateExterns.js +72 -20
- package/build/install-linux-prereqs.sh +4 -4
- package/build/shakaBuildHelpers.py +7 -8
- package/build/test.py +21 -9
- package/build/types/core +1 -0
- package/build/types/ui +6 -1
- package/demo/asset_card.js +129 -41
- package/demo/cast_receiver/receiver_app.css +27 -13
- package/demo/close_button.js +10 -15
- package/demo/common/asset.js +6 -6
- package/demo/common/assets.js +72 -14
- package/demo/config.js +28 -25
- package/demo/custom.js +20 -16
- package/demo/demo.less +107 -16
- package/demo/demo_uncompiled.js +33 -0
- package/demo/demo_utils.js +4 -3
- package/demo/front.js +12 -8
- package/demo/index.html +14 -17
- package/demo/input.js +30 -23
- package/demo/input_container.js +15 -11
- package/demo/load.js +5 -7
- package/demo/main.js +138 -49
- package/demo/search.js +40 -36
- package/demo/service_worker.js +1 -1
- package/demo/tooltip.js +16 -24
- package/dist/.csslintstamp +0 -0
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +165 -152
- package/dist/demo.compiled.debug.map +4 -4
- package/dist/demo.compiled.js +165 -152
- package/dist/demo.compiled.map +4 -4
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +28 -11
- package/dist/receiver.compiled.debug.js +11 -11
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +11 -11
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.debug.externs.js +232 -102
- package/dist/shaka-player.compiled.debug.js +189 -165
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +232 -102
- package/dist/shaka-player.compiled.js +567 -553
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.debug.externs.js +338 -113
- package/dist/shaka-player.ui.debug.js +296 -276
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +338 -113
- package/dist/shaka-player.ui.js +685 -671
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/drm-config.md +1 -0
- package/docs/tutorials/fairplay.md +77 -0
- package/docs/tutorials/index.json +1 -0
- package/docs/tutorials/manifest-parser.md +1 -1
- package/docs/tutorials/ui-customization.md +5 -2
- package/docs/tutorials/ui.md +10 -4
- package/docs/tutorials/welcome.md +2 -2
- package/externs/mediasession.js +16 -1
- package/externs/shaka/net.js +14 -4
- package/externs/shaka/player.js +136 -90
- package/externs/tippy.js +30 -0
- package/externs/webkitmediakeys.js +4 -0
- package/karma.conf.js +30 -24
- package/lib/cast/cast_proxy.js +94 -23
- package/lib/cast/cast_receiver.js +8 -1
- package/lib/dash/content_protection.js +33 -1
- package/lib/dash/dash_parser.js +13 -5
- package/lib/hls/hls_parser.js +20 -4
- package/lib/media/drm_engine.js +29 -2
- package/lib/media/media_source_engine.js +9 -6
- package/lib/media/play_rate_controller.js +14 -3
- package/lib/media/playhead.js +8 -3
- package/lib/media/streaming_engine.js +68 -20
- package/lib/media/transmuxer.js +2 -2
- package/lib/media/video_wrapper.js +8 -3
- package/lib/net/data_uri_plugin.js +5 -2
- package/lib/net/http_fetch_plugin.js +3 -3
- package/lib/net/http_plugin_utils.js +2 -4
- package/lib/net/http_xhr_plugin.js +2 -2
- package/lib/net/networking_engine.js +1 -0
- package/lib/offline/offline_scheme.js +7 -2
- package/lib/player.js +18 -8
- package/lib/polyfill/input_event.js +7 -11
- package/lib/polyfill/mediasource.js +1 -1
- package/lib/polyfill/patchedmediakeys_apple.js +2 -72
- package/lib/text/cue.js +1 -1
- package/lib/text/ttml_text_parser.js +1 -1
- package/lib/util/config_utils.js +1 -0
- package/lib/util/error.js +45 -11
- package/lib/util/event_manager.js +211 -100
- package/lib/util/fairplay_utils.js +122 -0
- package/lib/util/i_releasable.js +1 -0
- package/lib/util/player_configuration.js +7 -0
- package/lib/util/pssh.js +41 -0
- package/lib/util/string_utils.js +42 -6
- package/lib/util/timer.js +1 -1
- package/package.json +33 -33
- package/roadmap.md +96 -0
- package/shaka-player.uncompiled.js +5 -1
- package/test/dash/dash_parser_content_protection_unit.js +35 -1
- package/test/dash/dash_parser_manifest_unit.js +60 -0
- package/test/hls/hls_live_unit.js +7 -1
- package/test/hls/hls_parser_unit.js +50 -0
- package/test/media/drm_engine_unit.js +10 -4
- package/test/media/media_source_engine_integration.js +12 -0
- package/test/media/media_source_engine_unit.js +3 -1
- package/test/media/playhead_unit.js +7 -5
- package/test/media/streaming_engine_unit.js +46 -1
- package/test/media/transmuxer_integration.js +13 -0
- package/test/net/data_uri_plugin_unit.js +13 -2
- package/test/net/http_plugin_unit.js +17 -12
- package/test/net/networking_engine_unit.js +17 -8
- package/test/offline/offline_scheme_unit.js +18 -8
- package/test/player_external.js +3 -2
- package/test/player_integration.js +94 -3
- package/test/player_src_equals_integration.js +2 -2
- package/test/player_unit.js +21 -8
- package/test/test/boot.js +20 -5
- package/test/test/externs/jasmine.js +48 -0
- package/test/test/util/expect_async_polyfill.js +145 -0
- package/test/test/util/fake_networking_engine.js +1 -0
- package/test/test/util/manifest_generator.js +2 -1
- package/test/test/util/test_scheme.js +34 -2
- package/test/test/util/ui_utils.js +41 -0
- package/test/test/util/util.js +16 -8
- package/test/ui/ui_unit.js +130 -4
- package/ui/audio_language_selection.js +17 -96
- package/ui/big_play_button.js +61 -0
- package/ui/controls.js +226 -335
- package/ui/controls.less +3 -5
- package/ui/element.js +24 -6
- package/ui/externs/ui.js +62 -9
- package/ui/fullscreen_button.js +2 -52
- package/ui/less/buttons.less +10 -16
- package/ui/less/containers.less +75 -20
- package/ui/less/general.less +18 -2
- package/ui/less/other_elements.less +2 -1
- package/ui/less/overflow_menu.less +11 -10
- package/ui/less/range_elements.less +12 -10
- package/ui/less/spinner.less +2 -0
- package/ui/overflow_menu.js +1 -1
- package/ui/pip_button.js +1 -1
- package/ui/{play_pause_button.js → play_button.js} +17 -47
- package/ui/presentation_time.js +17 -12
- package/ui/range_element.js +176 -0
- package/ui/resolution_selection.js +43 -106
- package/ui/seek_bar.js +204 -0
- package/ui/settings_menu.js +113 -0
- package/ui/small_play_button.js +73 -0
- package/ui/text_displayer.js +17 -14
- package/ui/text_selection.js +42 -107
- package/ui/ui.js +17 -40
- package/ui/volume_bar.js +40 -68
package/demo/input_container.js
CHANGED
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
|
|
19
|
+
goog.provide('shakaDemo.InputContainer');
|
|
20
|
+
|
|
21
|
+
|
|
18
22
|
/**
|
|
19
23
|
* Creates elements for containing inputs. It represents a single "section" of
|
|
20
24
|
* input.
|
|
@@ -23,16 +27,16 @@
|
|
|
23
27
|
* It also has an optional header, which can contain style-dependent
|
|
24
28
|
* functionality.
|
|
25
29
|
*/
|
|
26
|
-
class
|
|
30
|
+
shakaDemo.InputContainer = class {
|
|
27
31
|
/**
|
|
28
32
|
* @param {!Element} parentDiv
|
|
29
33
|
* @param {?string} headerText The text to be displayed by the header. If
|
|
30
34
|
* null, there will be no header.
|
|
31
|
-
* @param {!
|
|
35
|
+
* @param {!shakaDemo.InputContainer.Style} style
|
|
32
36
|
* @param {?string} docLink
|
|
33
37
|
*/
|
|
34
38
|
constructor(parentDiv, headerText, style, docLink) {
|
|
35
|
-
/** @private {!
|
|
39
|
+
/** @private {!shakaDemo.InputContainer.Style} */
|
|
36
40
|
this.style_ = style;
|
|
37
41
|
|
|
38
42
|
/** @private {?Element} */
|
|
@@ -57,7 +61,7 @@ class ShakaDemoInputContainer {
|
|
|
57
61
|
this.createHeader_(parentDiv, headerText);
|
|
58
62
|
}
|
|
59
63
|
this.table_.classList.add(style);
|
|
60
|
-
if (style ==
|
|
64
|
+
if (style == shakaDemo.InputContainer.Style.ACCORDION) {
|
|
61
65
|
this.table_.classList.add('hidden');
|
|
62
66
|
}
|
|
63
67
|
parentDiv.appendChild(this.table_);
|
|
@@ -70,7 +74,7 @@ class ShakaDemoInputContainer {
|
|
|
70
74
|
* @return {boolean} true if this is an open accordion menu, false otherwise
|
|
71
75
|
*/
|
|
72
76
|
getIsOpen() {
|
|
73
|
-
if (this.style_ ==
|
|
77
|
+
if (this.style_ == shakaDemo.InputContainer.Style.ACCORDION) {
|
|
74
78
|
return this.table_.classList.contains('show');
|
|
75
79
|
}
|
|
76
80
|
return false;
|
|
@@ -78,7 +82,7 @@ class ShakaDemoInputContainer {
|
|
|
78
82
|
|
|
79
83
|
/** If this is an accordion menu, open it. */
|
|
80
84
|
open() {
|
|
81
|
-
if (!this.style_ ==
|
|
85
|
+
if (!this.style_ == shakaDemo.InputContainer.Style.ACCORDION) {
|
|
82
86
|
return;
|
|
83
87
|
}
|
|
84
88
|
this.table_.classList.remove('hidden');
|
|
@@ -90,7 +94,7 @@ class ShakaDemoInputContainer {
|
|
|
90
94
|
|
|
91
95
|
/** If this is an accordion menu, close it. */
|
|
92
96
|
close() {
|
|
93
|
-
if (this.style_ !=
|
|
97
|
+
if (this.style_ != shakaDemo.InputContainer.Style.ACCORDION) {
|
|
94
98
|
return;
|
|
95
99
|
}
|
|
96
100
|
this.table_.classList.remove('show');
|
|
@@ -106,7 +110,7 @@ class ShakaDemoInputContainer {
|
|
|
106
110
|
* @private
|
|
107
111
|
*/
|
|
108
112
|
createHeader_(parentDiv, headerText) {
|
|
109
|
-
if (this.style_ ==
|
|
113
|
+
if (this.style_ == shakaDemo.InputContainer.Style.ACCORDION) {
|
|
110
114
|
this.header_ = document.createElement('button');
|
|
111
115
|
this.header_.classList.add('mdl-button--raised');
|
|
112
116
|
this.header_.classList.add('mdl-button');
|
|
@@ -182,16 +186,16 @@ class ShakaDemoInputContainer {
|
|
|
182
186
|
|
|
183
187
|
this.latestTooltip = tooltipString;
|
|
184
188
|
if (tooltipString) {
|
|
185
|
-
|
|
189
|
+
shakaDemo.Tooltips.make(this.latestRow_, tooltipString);
|
|
186
190
|
// Keep the row from being focused.
|
|
187
191
|
this.latestRow_.setAttribute('tabindex', -1);
|
|
188
192
|
this.latestRow_.classList.add('borderless');
|
|
189
193
|
}
|
|
190
194
|
}
|
|
191
|
-
}
|
|
195
|
+
};
|
|
192
196
|
|
|
193
197
|
/** @enum {string} */
|
|
194
|
-
|
|
198
|
+
shakaDemo.InputContainer.Style = {
|
|
195
199
|
VERTICAL: 'input-container-style-vertical',
|
|
196
200
|
ACCORDION: 'input-container-style-accordion',
|
|
197
201
|
FLEX: 'input-container-style-flex',
|
package/demo/load.js
CHANGED
|
@@ -87,40 +87,34 @@ function shakaUncompiledModeSupported() {
|
|
|
87
87
|
fragments = fragments ? fragments.split(';') : [];
|
|
88
88
|
var combined = fields.concat(fragments);
|
|
89
89
|
|
|
90
|
-
var scripts = window['UNCOMPILED_JS'];
|
|
91
90
|
var buildType = 'uncompiled';
|
|
92
91
|
var buildSpecified = false;
|
|
93
92
|
|
|
94
93
|
if (!shakaUncompiledModeSupported()) {
|
|
95
94
|
// If uncompiled mode is not supported, default to the compiled debug
|
|
96
95
|
// version, which should still work.
|
|
97
|
-
scripts = window['COMPILED_DEBUG_JS'];
|
|
98
96
|
buildType = 'debug_compiled';
|
|
99
97
|
}
|
|
100
98
|
|
|
101
99
|
if (!navigator.onLine) {
|
|
102
100
|
// If we're offline, default to the compiled version, which may have been
|
|
103
101
|
// cached by the service worker.
|
|
104
|
-
scripts = window['COMPILED_JS'];
|
|
105
102
|
buildType = 'compiled';
|
|
106
103
|
}
|
|
107
104
|
|
|
108
105
|
// Very old browsers do not have Array.prototype.indexOf, so we loop.
|
|
109
106
|
for (var i = 0; i < combined.length; ++i) {
|
|
110
107
|
if (combined[i] == 'build=compiled') {
|
|
111
|
-
scripts = window['COMPILED_JS'];
|
|
112
108
|
buildType = 'compiled';
|
|
113
109
|
buildSpecified = true;
|
|
114
110
|
break;
|
|
115
111
|
}
|
|
116
112
|
if (combined[i] == 'build=debug_compiled') {
|
|
117
|
-
scripts = window['COMPILED_DEBUG_JS'];
|
|
118
113
|
buildType = 'debug_compiled';
|
|
119
114
|
buildSpecified = true;
|
|
120
115
|
break;
|
|
121
116
|
}
|
|
122
117
|
if (combined[i] == 'build=uncompiled') {
|
|
123
|
-
scripts = window['UNCOMPILED_JS'];
|
|
124
118
|
buildType = 'uncompiled';
|
|
125
119
|
buildSpecified = true;
|
|
126
120
|
break;
|
|
@@ -131,7 +125,6 @@ function shakaUncompiledModeSupported() {
|
|
|
131
125
|
// The URL says uncompiled, but we know it won't work. This URL was
|
|
132
126
|
// probably copied from some other browser, but it won't work in this one.
|
|
133
127
|
// Force the use of the compiled debug build and update the hash.
|
|
134
|
-
scripts = window['COMPILED_DEBUG_JS'];
|
|
135
128
|
buildType = 'debug_compiled';
|
|
136
129
|
|
|
137
130
|
// Replace the build type in either the hash or the URL parameters.
|
|
@@ -159,6 +152,11 @@ function shakaUncompiledModeSupported() {
|
|
|
159
152
|
|
|
160
153
|
// The application must define its list of compiled and uncompiled sources
|
|
161
154
|
// before including this loader. The URLs should be relative to the page.
|
|
155
|
+
var scripts = {
|
|
156
|
+
'compiled': window['COMPILED_JS'],
|
|
157
|
+
'debug_compiled': window['COMPILED_DEBUG_JS'],
|
|
158
|
+
'uncompiled': window['UNCOMPILED_JS'],
|
|
159
|
+
}[buildType];
|
|
162
160
|
for (var j = 0; j < scripts.length; ++j) {
|
|
163
161
|
loadRelativeScript(scripts[j]);
|
|
164
162
|
}
|
package/demo/main.js
CHANGED
|
@@ -15,13 +15,17 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
|
|
19
|
+
goog.provide('shakaDemo.Main');
|
|
20
|
+
|
|
21
|
+
|
|
18
22
|
/**
|
|
19
23
|
* Shaka Player demo, main section.
|
|
20
24
|
* This controls the header and the footer, and contains all methods that should
|
|
21
25
|
* be shared by multiple page layouts (loading assets, setting/checking
|
|
22
26
|
* configuration, etc).
|
|
23
27
|
*/
|
|
24
|
-
class
|
|
28
|
+
shakaDemo.Main = class {
|
|
25
29
|
constructor() {
|
|
26
30
|
/** @private {HTMLMediaElement} */
|
|
27
31
|
this.video_ = null;
|
|
@@ -35,6 +39,12 @@ class ShakaDemoMain {
|
|
|
35
39
|
/** @type {?ShakaDemoAssetInfo} */
|
|
36
40
|
this.selectedAsset = null;
|
|
37
41
|
|
|
42
|
+
/**
|
|
43
|
+
* The configuration asked for by the user. I.e., not from the asset.
|
|
44
|
+
* @private {shaka.extern.PlayerConfiguration}
|
|
45
|
+
*/
|
|
46
|
+
this.desiredConfig_;
|
|
47
|
+
|
|
38
48
|
/** @private {shaka.extern.PlayerConfiguration} */
|
|
39
49
|
this.defaultConfig_;
|
|
40
50
|
|
|
@@ -55,6 +65,9 @@ class ShakaDemoMain {
|
|
|
55
65
|
|
|
56
66
|
/** @private {string} */
|
|
57
67
|
this.uiLocale_ = '';
|
|
68
|
+
|
|
69
|
+
/** @private {boolean} */
|
|
70
|
+
this.noInput_ = false;
|
|
58
71
|
}
|
|
59
72
|
|
|
60
73
|
/**
|
|
@@ -64,13 +77,15 @@ class ShakaDemoMain {
|
|
|
64
77
|
*/
|
|
65
78
|
initCommon_() {
|
|
66
79
|
// Display uncaught exceptions. Note that this doesn't seem to work in IE.
|
|
67
|
-
// See
|
|
80
|
+
// See shakaDemo.Main.initWrapper for a failsafe that works for init-time
|
|
68
81
|
// errors on IE.
|
|
69
82
|
window.addEventListener('error', (event) => {
|
|
70
83
|
// Exception to the exceptions we catch: ChromeVox (screenreader) always
|
|
71
84
|
// throws an error as of Chrome 73. Screen these out since they are
|
|
72
85
|
// unrelated to our application and we can't control them.
|
|
73
|
-
if (event.message.includes('cvox.
|
|
86
|
+
if (event.message.includes('cvox.Api')) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
74
89
|
|
|
75
90
|
this.onError_(/** @type {!shaka.util.Error} */ (event.error));
|
|
76
91
|
});
|
|
@@ -79,8 +94,8 @@ class ShakaDemoMain {
|
|
|
79
94
|
document.getElementById('error-display-close-button').addEventListener(
|
|
80
95
|
'click', (event) => this.closeError_());
|
|
81
96
|
|
|
82
|
-
// Set up version
|
|
83
|
-
this.
|
|
97
|
+
// Set up version strings in the appropriate divs.
|
|
98
|
+
this.setUpVersionStrings_();
|
|
84
99
|
}
|
|
85
100
|
|
|
86
101
|
/**
|
|
@@ -127,7 +142,7 @@ class ShakaDemoMain {
|
|
|
127
142
|
|
|
128
143
|
this.video_ =
|
|
129
144
|
/** @type {!HTMLVideoElement} */(document.getElementById('video'));
|
|
130
|
-
this.video_.poster =
|
|
145
|
+
this.video_.poster = shakaDemo.Main.mainPoster_;
|
|
131
146
|
|
|
132
147
|
this.container_ = /** @type {!HTMLElement} */(
|
|
133
148
|
document.getElementsByClassName('video-container')[0]);
|
|
@@ -143,16 +158,40 @@ class ShakaDemoMain {
|
|
|
143
158
|
}
|
|
144
159
|
}
|
|
145
160
|
|
|
161
|
+
// Optionally enter noinput mode. This has to happen before setting up the
|
|
162
|
+
// player.
|
|
163
|
+
this.noInput_ = 'noinput' in this.getParams_();
|
|
146
164
|
this.setupPlayer_();
|
|
147
165
|
this.readHash_();
|
|
148
166
|
window.addEventListener('hashchange', () => this.hashChanged_());
|
|
149
167
|
|
|
150
168
|
await this.setupStorage_();
|
|
151
169
|
|
|
170
|
+
if (this.noInput_) {
|
|
171
|
+
// Set the page to noInput mode, disabling the header and footer.
|
|
172
|
+
const hideClass = 'should-hide-in-no-input-mode';
|
|
173
|
+
for (const element of document.getElementsByClassName(hideClass)) {
|
|
174
|
+
this.hideNode_(element);
|
|
175
|
+
}
|
|
176
|
+
const showClass = 'should-show-in-no-input-mode';
|
|
177
|
+
for (const element of document.getElementsByClassName(showClass)) {
|
|
178
|
+
this.showNode_(element);
|
|
179
|
+
}
|
|
180
|
+
// Also fullscreen the container.
|
|
181
|
+
this.container_.classList.add('no-input-sized');
|
|
182
|
+
document.getElementById('video-bar').classList.add('no-input-sized');
|
|
183
|
+
}
|
|
184
|
+
|
|
152
185
|
// The main page is loaded. Dispatch an event, so the various
|
|
153
186
|
// configurations will load themselves.
|
|
154
187
|
this.dispatchEventWithName_('shaka-main-loaded');
|
|
155
188
|
|
|
189
|
+
// Wait for one interruptor cycle, so that the tabs have time to load.
|
|
190
|
+
// This ensures that, for example, if there is an asset playing at page
|
|
191
|
+
// load time, the video will scroll into view second, and the page won't
|
|
192
|
+
// scroll away from the video.
|
|
193
|
+
await Promise.resolve();
|
|
194
|
+
|
|
156
195
|
// Update the componentHandler, to account for any new MDL elements added.
|
|
157
196
|
componentHandler.upgradeDom();
|
|
158
197
|
|
|
@@ -174,13 +213,19 @@ class ShakaDemoMain {
|
|
|
174
213
|
const ui = video['ui'];
|
|
175
214
|
this.player_ = ui.getControls().getPlayer();
|
|
176
215
|
|
|
177
|
-
|
|
178
|
-
|
|
216
|
+
if (!this.noInput_) {
|
|
217
|
+
// Don't add the close button if in noInput mode; it doesn't make much
|
|
218
|
+
// sense to stop playing a video if you can't start playing other videos.
|
|
179
219
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
220
|
+
// Register custom controls to the UI.
|
|
221
|
+
const factory = new shakaDemo.CloseButton.Factory();
|
|
222
|
+
shaka.ui.Controls.registerElement('close', factory);
|
|
223
|
+
|
|
224
|
+
// Configure UI.
|
|
225
|
+
const uiConfig = ui.getConfiguration();
|
|
226
|
+
uiConfig.controlPanelElements.push('close');
|
|
227
|
+
ui.configure(uiConfig);
|
|
228
|
+
}
|
|
184
229
|
|
|
185
230
|
// Add application-level default configs here. These are not the library
|
|
186
231
|
// defaults, but they are the application defaults. This will affect the
|
|
@@ -192,9 +237,10 @@ class ShakaDemoMain {
|
|
|
192
237
|
|
|
193
238
|
// Get default config.
|
|
194
239
|
this.defaultConfig_ = this.player_.getConfiguration();
|
|
240
|
+
this.desiredConfig_ = this.player_.getConfiguration();
|
|
195
241
|
const languages = navigator.languages || ['en-us'];
|
|
196
|
-
this.
|
|
197
|
-
this.
|
|
242
|
+
this.configure('preferredAudioLanguage', languages[0]);
|
|
243
|
+
this.configure('preferredTextLanguage', languages[0]);
|
|
198
244
|
this.uiLocale_ = languages[0];
|
|
199
245
|
// TODO(#1591): Support multiple language preferences
|
|
200
246
|
|
|
@@ -423,6 +469,11 @@ class ShakaDemoMain {
|
|
|
423
469
|
* @return {?string} unsupportedReason Null if asset is supported.
|
|
424
470
|
*/
|
|
425
471
|
getAssetUnsupportedReason(asset, needOffline) {
|
|
472
|
+
if (needOffline &&
|
|
473
|
+
(!shaka.offline.Storage.support() || !this.initialStoredList_)) {
|
|
474
|
+
return 'Your browser does not support offline storage.';
|
|
475
|
+
}
|
|
476
|
+
|
|
426
477
|
if (asset.source == shakaAssets.Source.CUSTOM) {
|
|
427
478
|
// We can't be sure if custom assets are supported or not. Just assume
|
|
428
479
|
// they are.
|
|
@@ -438,11 +489,7 @@ class ShakaDemoMain {
|
|
|
438
489
|
return 'This asset cannot be downloaded.';
|
|
439
490
|
}
|
|
440
491
|
|
|
441
|
-
if (
|
|
442
|
-
return 'Your browser does not support offline storage.';
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
if (!asset.drm.includes(shakaAssets.KeySystem.CLEAR)) {
|
|
492
|
+
if (!asset.isClear()) {
|
|
446
493
|
const hasSupportedDRM = asset.drm.some((drm) => {
|
|
447
494
|
return this.support_.drm[drm];
|
|
448
495
|
});
|
|
@@ -583,7 +630,7 @@ class ShakaDemoMain {
|
|
|
583
630
|
/* manifestUri= */ manifest,
|
|
584
631
|
/* source= */ shakaAssets.Source.UNKNOWN);
|
|
585
632
|
if ('license' in params) {
|
|
586
|
-
let drmSystems =
|
|
633
|
+
let drmSystems = shakaDemo.Main.commonDrmSystems;
|
|
587
634
|
if ('drmSystem' in params) {
|
|
588
635
|
drmSystems = [params['drmSystem']];
|
|
589
636
|
}
|
|
@@ -618,17 +665,17 @@ class ShakaDemoMain {
|
|
|
618
665
|
value = parseFloat(value);
|
|
619
666
|
}
|
|
620
667
|
|
|
621
|
-
this.
|
|
668
|
+
this.configure(configName, value);
|
|
622
669
|
}
|
|
623
670
|
};
|
|
624
671
|
const config = this.player_.getConfiguration();
|
|
625
|
-
|
|
672
|
+
shakaDemo.Utils.runThroughHashParams(readParam, config);
|
|
626
673
|
}
|
|
627
674
|
if ('lang' in params) {
|
|
628
675
|
// Load the legacy 'lang' hash value.
|
|
629
676
|
const lang = params['lang'];
|
|
630
|
-
this.
|
|
631
|
-
this.
|
|
677
|
+
this.configure('preferredAudioLanguage', lang);
|
|
678
|
+
this.configure('preferredTextLanguage', lang);
|
|
632
679
|
this.setUILocale(lang);
|
|
633
680
|
}
|
|
634
681
|
if ('uilang' in params) {
|
|
@@ -636,10 +683,10 @@ class ShakaDemoMain {
|
|
|
636
683
|
// TODO(#1591): Support multiple language preferences
|
|
637
684
|
}
|
|
638
685
|
if ('noadaptation' in params) {
|
|
639
|
-
this.
|
|
686
|
+
this.configure('abr.enabled', false);
|
|
640
687
|
}
|
|
641
688
|
if ('jumpLargeGaps' in params) {
|
|
642
|
-
this.
|
|
689
|
+
this.configure('streaming.jumpLargeGaps', true);
|
|
643
690
|
}
|
|
644
691
|
|
|
645
692
|
// Add compiled/uncompiled links.
|
|
@@ -675,7 +722,7 @@ class ShakaDemoMain {
|
|
|
675
722
|
this.nativeControlsEnabled_ = 'nativecontrols' in params;
|
|
676
723
|
|
|
677
724
|
// Check if uncompiled mode is supported.
|
|
678
|
-
if (!
|
|
725
|
+
if (!shakaDemo.Utils.browserSupportsUncompiledMode()) {
|
|
679
726
|
const uncompiledLink = document.getElementById('uncompiled-link');
|
|
680
727
|
uncompiledLink.setAttribute('disabled', '');
|
|
681
728
|
uncompiledLink.removeAttribute('href');
|
|
@@ -751,7 +798,7 @@ class ShakaDemoMain {
|
|
|
751
798
|
* @return {*}
|
|
752
799
|
*/
|
|
753
800
|
getCurrentConfigValue(valueName) {
|
|
754
|
-
const config = this.
|
|
801
|
+
const config = this.desiredConfig_;
|
|
755
802
|
return this.getValueFromGivenConfig_(valueName, config);
|
|
756
803
|
}
|
|
757
804
|
|
|
@@ -767,12 +814,18 @@ class ShakaDemoMain {
|
|
|
767
814
|
* @param {*=} value
|
|
768
815
|
*/
|
|
769
816
|
configure(config, value) {
|
|
817
|
+
if (arguments.length == 2 && typeof(config) == 'string') {
|
|
818
|
+
config = shaka.util.ConfigUtils.convertToConfigObject(config, value);
|
|
819
|
+
}
|
|
820
|
+
const asObj = /** @type {!Object} */ (config);
|
|
821
|
+
shaka.util.PlayerConfiguration.mergeConfigObjects(
|
|
822
|
+
this.desiredConfig_, asObj, this.defaultConfig_);
|
|
770
823
|
this.player_.configure(config, value);
|
|
771
824
|
}
|
|
772
825
|
|
|
773
826
|
/** @return {!shaka.extern.PlayerConfiguration} */
|
|
774
827
|
getConfiguration() {
|
|
775
|
-
return this.
|
|
828
|
+
return this.desiredConfig_;
|
|
776
829
|
}
|
|
777
830
|
|
|
778
831
|
/**
|
|
@@ -793,13 +846,24 @@ class ShakaDemoMain {
|
|
|
793
846
|
this.selectedAsset = null;
|
|
794
847
|
const videoBar = document.getElementById('video-bar');
|
|
795
848
|
this.hideNode_(videoBar);
|
|
796
|
-
this.video_.poster =
|
|
849
|
+
this.video_.poster = shakaDemo.Main.mainPoster_;
|
|
797
850
|
|
|
851
|
+
if (document.fullscreenElement) {
|
|
852
|
+
document.exitFullscreen();
|
|
853
|
+
}
|
|
854
|
+
if (document.pictureInPictureElement) {
|
|
855
|
+
document.exitPictureInPicture();
|
|
856
|
+
}
|
|
798
857
|
this.player_.unload();
|
|
799
858
|
|
|
800
859
|
// The currently-selected asset changed, so update asset cards.
|
|
801
860
|
this.dispatchEventWithName_('shaka-main-selected-asset-changed');
|
|
802
861
|
|
|
862
|
+
// Unset media session title, but only if the browser supports that API.
|
|
863
|
+
if (navigator.mediaSession) {
|
|
864
|
+
navigator.mediaSession.metadata = null;
|
|
865
|
+
}
|
|
866
|
+
|
|
803
867
|
// Remake hash, to change the current asset.
|
|
804
868
|
this.remakeHash();
|
|
805
869
|
}
|
|
@@ -821,8 +885,11 @@ class ShakaDemoMain {
|
|
|
821
885
|
if (storage) {
|
|
822
886
|
storage.configure(assetConfig);
|
|
823
887
|
} else {
|
|
824
|
-
|
|
888
|
+
// Re-apply the desired config, to remove previous asset configuration
|
|
889
|
+
// without removing previous user configuration.
|
|
890
|
+
this.player_.configure(this.desiredConfig_);
|
|
825
891
|
this.player_.configure(assetConfig);
|
|
892
|
+
// This uses Player.configure so as to not change |this.desiredConfig_|.
|
|
826
893
|
}
|
|
827
894
|
|
|
828
895
|
const config = storage ?
|
|
@@ -868,7 +935,7 @@ class ShakaDemoMain {
|
|
|
868
935
|
const videoBar = document.getElementById('video-bar');
|
|
869
936
|
this.showNode_(videoBar);
|
|
870
937
|
this.closeError_();
|
|
871
|
-
this.video_.poster =
|
|
938
|
+
this.video_.poster = shakaDemo.Main.mainPoster_;
|
|
872
939
|
|
|
873
940
|
// Scroll to the top of the page, so that if the page is scrolled down,
|
|
874
941
|
// the user won't need to manually scroll up to see the video.
|
|
@@ -916,7 +983,19 @@ class ShakaDemoMain {
|
|
|
916
983
|
null) || asset.manifestUri;
|
|
917
984
|
await this.player_.load(manifestUri);
|
|
918
985
|
if (this.player_.isAudioOnly()) {
|
|
919
|
-
this.video_.poster =
|
|
986
|
+
this.video_.poster = shakaDemo.Main.audioOnlyPoster_;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
// Set media session title, but only if the browser supports that API.
|
|
990
|
+
if (navigator.mediaSession) {
|
|
991
|
+
const metadata = {
|
|
992
|
+
title: asset.name,
|
|
993
|
+
artwork: [{src: asset.iconUri}],
|
|
994
|
+
};
|
|
995
|
+
if (asset.source != shakaAssets.Source.UNKNOWN) {
|
|
996
|
+
metadata.artist = asset.source;
|
|
997
|
+
}
|
|
998
|
+
navigator.mediaSession.metadata = new MediaMetadata(metadata);
|
|
920
999
|
}
|
|
921
1000
|
} catch (reason) {
|
|
922
1001
|
const error = /** @type {!shaka.util.Error} */ (reason);
|
|
@@ -956,7 +1035,7 @@ class ShakaDemoMain {
|
|
|
956
1035
|
}
|
|
957
1036
|
};
|
|
958
1037
|
const config = this.player_.getConfiguration();
|
|
959
|
-
|
|
1038
|
+
shakaDemo.Utils.runThroughHashParams(setParam, config);
|
|
960
1039
|
}
|
|
961
1040
|
if (!this.getCurrentConfigValue('abr.enabled')) {
|
|
962
1041
|
params.push('noadaptation');
|
|
@@ -973,7 +1052,7 @@ class ShakaDemoMain {
|
|
|
973
1052
|
const uri = this.selectedAsset.licenseServers.values().next().value;
|
|
974
1053
|
params.push('license=' + uri);
|
|
975
1054
|
for (const drmSystem of this.selectedAsset.licenseServers.keys()) {
|
|
976
|
-
if (!
|
|
1055
|
+
if (!shakaDemo.Main.commonDrmSystems.includes(drmSystem)) {
|
|
977
1056
|
params.push('drmSystem=' + drmSystem);
|
|
978
1057
|
break;
|
|
979
1058
|
}
|
|
@@ -1000,6 +1079,10 @@ class ShakaDemoMain {
|
|
|
1000
1079
|
}
|
|
1001
1080
|
}
|
|
1002
1081
|
|
|
1082
|
+
if (this.noInput_) {
|
|
1083
|
+
params.push('noinput');
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1003
1086
|
if (this.nativeControlsEnabled_) {
|
|
1004
1087
|
params.push('nativecontrols');
|
|
1005
1088
|
}
|
|
@@ -1136,8 +1219,12 @@ class ShakaDemoMain {
|
|
|
1136
1219
|
document.dispatchEvent(event);
|
|
1137
1220
|
}
|
|
1138
1221
|
|
|
1139
|
-
/**
|
|
1140
|
-
|
|
1222
|
+
/**
|
|
1223
|
+
* Sets the "version-string" divs to a version string.
|
|
1224
|
+
* For example, "v2.5.4-master (uncompiled)".
|
|
1225
|
+
* @private
|
|
1226
|
+
*/
|
|
1227
|
+
setUpVersionStrings_() {
|
|
1141
1228
|
const version = shaka.Player.version;
|
|
1142
1229
|
let split = version.split('-');
|
|
1143
1230
|
let inParen = [];
|
|
@@ -1152,10 +1239,12 @@ class ShakaDemoMain {
|
|
|
1152
1239
|
}
|
|
1153
1240
|
|
|
1154
1241
|
// Put the version into the version string div.
|
|
1155
|
-
const
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1242
|
+
const versionStringDivs = document.getElementsByClassName('version-string');
|
|
1243
|
+
for (const div of versionStringDivs) {
|
|
1244
|
+
div.textContent = split.join('-');
|
|
1245
|
+
if (inParen.length > 0) {
|
|
1246
|
+
div.textContent += ' (' + inParen.join(', ') + ')';
|
|
1247
|
+
}
|
|
1159
1248
|
}
|
|
1160
1249
|
}
|
|
1161
1250
|
|
|
@@ -1245,11 +1334,11 @@ class ShakaDemoMain {
|
|
|
1245
1334
|
this.showPlayer_();
|
|
1246
1335
|
}
|
|
1247
1336
|
}
|
|
1248
|
-
}
|
|
1337
|
+
};
|
|
1249
1338
|
|
|
1250
1339
|
|
|
1251
1340
|
/** @type {!Array.<string>} */
|
|
1252
|
-
|
|
1341
|
+
shakaDemo.Main.commonDrmSystems = [
|
|
1253
1342
|
'com.widevine.alpha',
|
|
1254
1343
|
'com.microsoft.playready',
|
|
1255
1344
|
'com.apple.fps.1_0',
|
|
@@ -1258,14 +1347,14 @@ ShakaDemoMain.commonDrmSystems = [
|
|
|
1258
1347
|
];
|
|
1259
1348
|
|
|
1260
1349
|
|
|
1261
|
-
const shakaDemoMain = new
|
|
1350
|
+
const shakaDemoMain = new shakaDemo.Main();
|
|
1262
1351
|
|
|
1263
1352
|
|
|
1264
1353
|
/**
|
|
1265
1354
|
* @private
|
|
1266
1355
|
* @const {string}
|
|
1267
1356
|
*/
|
|
1268
|
-
|
|
1357
|
+
shakaDemo.Main.mainPoster_ =
|
|
1269
1358
|
'https://shaka-player-demo.appspot.com/assets/poster.jpg';
|
|
1270
1359
|
|
|
1271
1360
|
|
|
@@ -1273,7 +1362,7 @@ ShakaDemoMain.mainPoster_ =
|
|
|
1273
1362
|
* @private
|
|
1274
1363
|
* @const {string}
|
|
1275
1364
|
*/
|
|
1276
|
-
|
|
1365
|
+
shakaDemo.Main.audioOnlyPoster_ =
|
|
1277
1366
|
'https://shaka-player-demo.appspot.com/assets/audioOnly.gif';
|
|
1278
1367
|
|
|
1279
1368
|
|
|
@@ -1286,7 +1375,7 @@ ShakaDemoMain.audioOnlyPoster_ =
|
|
|
1286
1375
|
* @return {!Promise}
|
|
1287
1376
|
* @suppress {accessControls}
|
|
1288
1377
|
*/
|
|
1289
|
-
|
|
1378
|
+
shakaDemo.Main.initWrapper = async (initFn) => {
|
|
1290
1379
|
try {
|
|
1291
1380
|
await initFn();
|
|
1292
1381
|
} catch (error) {
|
|
@@ -1295,8 +1384,8 @@ ShakaDemoMain.initWrapper = async (initFn) => {
|
|
|
1295
1384
|
}
|
|
1296
1385
|
};
|
|
1297
1386
|
document.addEventListener('shaka-ui-loaded', () => {
|
|
1298
|
-
|
|
1387
|
+
shakaDemo.Main.initWrapper(() => shakaDemoMain.init());
|
|
1299
1388
|
});
|
|
1300
1389
|
document.addEventListener('shaka-ui-load-failed', (event) => {
|
|
1301
|
-
|
|
1390
|
+
shakaDemo.Main.initWrapper(() => shakaDemoMain.initFailed());
|
|
1302
1391
|
});
|