shaka-player 4.2.12 → 4.2.14
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 +11 -0
- package/.github/workflows/build-and-test.yaml +22 -14
- package/.github/workflows/compute-incremental-coverage.py +3 -0
- package/.github/workflows/selenium-lab-tests.yaml +48 -12
- package/.github/workflows/update-issues.yaml +1 -0
- package/CHANGELOG.md +28 -0
- package/demo/common/assets.js +12 -12
- package/demo/main.js +5 -0
- package/dist/demo.compiled.debug.js +13 -13
- package/dist/demo.compiled.debug.map +2 -2
- package/dist/demo.compiled.js +13 -13
- package/dist/demo.compiled.map +2 -2
- package/dist/deps.js +1 -1
- package/dist/locales.js +31 -31
- package/dist/receiver.compiled.debug.js +8 -8
- package/dist/receiver.compiled.debug.map +1 -1
- package/dist/receiver.compiled.js +8 -8
- package/dist/receiver.compiled.map +1 -1
- package/dist/shaka-player.compiled.d.ts +2 -2
- package/dist/shaka-player.compiled.debug.d.ts +2 -2
- package/dist/shaka-player.compiled.debug.js +51 -49
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.js +403 -404
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.d.ts +2 -2
- package/dist/shaka-player.ui.debug.d.ts +2 -2
- package/dist/shaka-player.ui.debug.js +60 -59
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.js +411 -411
- package/dist/shaka-player.ui.map +2 -2
- package/docs/tutorials/selenium-grid-config.md +60 -8
- package/externs/shaka/manifest.js +5 -1
- package/externs/shaka/offline.js +5 -1
- package/karma.conf.js +52 -7
- package/lib/abr/simple_abr_manager.js +5 -5
- package/lib/ads/client_side_ad_manager.js +14 -2
- package/lib/dash/dash_parser.js +1 -0
- package/lib/hls/hls_parser.js +1 -0
- package/lib/media/media_source_engine.js +6 -5
- package/lib/media/streaming_engine.js +2 -2
- package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
- package/lib/offline/manifest_converter.js +1 -0
- package/lib/offline/storage.js +1 -0
- package/lib/player.js +4 -5
- package/lib/polyfill/orientation.js +34 -7
- package/lib/text/vtt_text_parser.js +1 -0
- package/lib/util/manifest_parser_utils.js +4 -2
- package/lib/util/periods.js +2 -0
- package/lib/util/platform.js +22 -0
- package/lib/util/stream_utils.js +69 -26
- package/package.json +3 -3
- package/test/cast/cast_utils_unit.js +4 -1
- package/test/hls/hls_parser_unit.js +72 -0
- package/test/media/adaptation_set_unit.js +1 -0
- package/test/media/drm_engine_integration.js +2 -2
- package/test/media/media_source_engine_unit.js +1 -1
- package/test/media/segment_index_unit.js +3 -3
- package/test/media/streaming_engine_integration.js +14 -11
- package/test/offline/manifest_convert_unit.js +5 -0
- package/test/offline/offline_integration.js +6 -3
- package/test/player_external.js +19 -16
- package/test/player_integration.js +39 -49
- package/test/player_src_equals_integration.js +9 -5
- package/test/test/util/fake_demo_main.js +7 -3
- package/test/test/util/layout_tests.js +2 -2
- package/test/test/util/manifest_generator.js +2 -0
- package/test/test/util/offline_utils.js +1 -0
- package/test/test/util/streaming_engine_util.js +3 -0
- package/test/test/util/ui_utils.js +14 -3
- package/test/test/util/util.js +6 -27
- package/test/test/util/waiter.js +73 -3
- package/test/ui/ad_ui_unit.js +9 -9
- package/test/util/stream_utils_unit.js +46 -0
- package/ui/externs/ui.js +2 -2
- package/ui/range_element.js +5 -0
- package/ui/seek_bar.js +7 -1
|
@@ -47,17 +47,20 @@ vars:
|
|
|
47
47
|
FirefoxMac:
|
|
48
48
|
browser: firefox
|
|
49
49
|
os: Mac
|
|
50
|
-
|
|
50
|
+
extra_configs:
|
|
51
|
+
- *firefox_config
|
|
51
52
|
|
|
52
53
|
FirefoxWindows:
|
|
53
54
|
browser: firefox
|
|
54
55
|
os: Windows
|
|
55
|
-
|
|
56
|
+
extra_configs:
|
|
57
|
+
- *firefox_config
|
|
56
58
|
|
|
57
59
|
FirefoxLinux:
|
|
58
60
|
browser: firefox
|
|
59
61
|
os: Linux
|
|
60
|
-
|
|
62
|
+
extra_configs:
|
|
63
|
+
- *firefox_config
|
|
61
64
|
```
|
|
62
65
|
|
|
63
66
|
### Browsers
|
|
@@ -75,8 +78,8 @@ browser made available to Karma. Within each of those keys are the following:
|
|
|
75
78
|
and must match the string and case used in the Selenium node config.
|
|
76
79
|
- `disabled` (optional): If true, this browser is disabled and will not be
|
|
77
80
|
used unless explicitly requested.
|
|
78
|
-
- `
|
|
79
|
-
merged with the WebDriver launcher config in Karma.
|
|
81
|
+
- `extra_configs` (optional): An array of dictionaries of extra configs which
|
|
82
|
+
will be merged with the WebDriver launcher config in Karma.
|
|
80
83
|
|
|
81
84
|
Examples of basic desktop browsers definitions:
|
|
82
85
|
|
|
@@ -96,9 +99,9 @@ Safari:
|
|
|
96
99
|
SafariTP:
|
|
97
100
|
browser: safari
|
|
98
101
|
os: Mac
|
|
99
|
-
|
|
100
|
-
safari.options:
|
|
101
|
-
|
|
102
|
+
extra_configs:
|
|
103
|
+
- safari.options:
|
|
104
|
+
technologyPreview: true
|
|
102
105
|
|
|
103
106
|
ChromeWindows:
|
|
104
107
|
browser: chrome
|
|
@@ -120,3 +123,52 @@ FirefoxLinux:
|
|
|
120
123
|
browser: firefox
|
|
121
124
|
os: Linux
|
|
122
125
|
```
|
|
126
|
+
|
|
127
|
+
### Composing configs
|
|
128
|
+
|
|
129
|
+
You can define variables for browser configs that can be composed together in
|
|
130
|
+
`extra_configs`. For example, below you will see some basic definitions for
|
|
131
|
+
Chrome arguments and parameters, and then an additional config with an argument
|
|
132
|
+
that is only needed for some platforms. `karma.conf.js` will merge those
|
|
133
|
+
argument lists intelligently when it loads the YAML config.
|
|
134
|
+
|
|
135
|
+
```yaml
|
|
136
|
+
vars:
|
|
137
|
+
basic_chrome_config: &basic_chrome_config
|
|
138
|
+
goog:chromeOptions:
|
|
139
|
+
args:
|
|
140
|
+
# Normally, Chrome disallows autoplaying videos in many cases. Enable
|
|
141
|
+
# it for testing.
|
|
142
|
+
- "--autoplay-policy=no-user-gesture-required"
|
|
143
|
+
|
|
144
|
+
# Instruct chromedriver not to disable component updater.
|
|
145
|
+
excludeSwitches:
|
|
146
|
+
- "disable-component-update"
|
|
147
|
+
|
|
148
|
+
headless_chrome_config: &headless_chrome_config
|
|
149
|
+
goog:chromeOptions:
|
|
150
|
+
args:
|
|
151
|
+
# Run in headless mode.
|
|
152
|
+
- "--headless"
|
|
153
|
+
|
|
154
|
+
ChromeLinux:
|
|
155
|
+
browser: chrome
|
|
156
|
+
os: Mac
|
|
157
|
+
extra_configs:
|
|
158
|
+
- *basic_chrome_config
|
|
159
|
+
|
|
160
|
+
ChromeWindows:
|
|
161
|
+
browser: chrome
|
|
162
|
+
os: Mac
|
|
163
|
+
extra_configs:
|
|
164
|
+
- *basic_chrome_config
|
|
165
|
+
|
|
166
|
+
ChromeMac:
|
|
167
|
+
browser: chrome
|
|
168
|
+
os: Mac
|
|
169
|
+
# Take the parameters and arguments for basic_chrome_config, then append the
|
|
170
|
+
# arguments for headless_chrome_config.
|
|
171
|
+
extra_configs:
|
|
172
|
+
- *basic_chrome_config
|
|
173
|
+
- *headless_chrome_config
|
|
174
|
+
```
|
|
@@ -321,7 +321,8 @@ shaka.extern.FetchCryptoKeysFunction;
|
|
|
321
321
|
* tilesLayout: (string|undefined),
|
|
322
322
|
* matchedStreams:
|
|
323
323
|
* (!Array.<shaka.extern.Stream>|!Array.<shaka.extern.StreamDB>|
|
|
324
|
-
* undefined)
|
|
324
|
+
* undefined),
|
|
325
|
+
* external: boolean
|
|
325
326
|
* }}
|
|
326
327
|
*
|
|
327
328
|
* @description
|
|
@@ -434,6 +435,9 @@ shaka.extern.FetchCryptoKeysFunction;
|
|
|
434
435
|
* @property {(!Array.<shaka.extern.Stream>|!Array.<shaka.extern.StreamDB>|
|
|
435
436
|
* undefined)} matchedStreams
|
|
436
437
|
* The streams in all periods which match the stream. Used for Dash.
|
|
438
|
+
* @property {boolean} external
|
|
439
|
+
* Indicate if the stream was added externally.
|
|
440
|
+
* Eg: external text tracks.
|
|
437
441
|
*
|
|
438
442
|
* @exportDoc
|
|
439
443
|
*/
|
package/externs/shaka/offline.js
CHANGED
|
@@ -132,7 +132,8 @@ shaka.extern.ManifestDB;
|
|
|
132
132
|
* audioSamplingRate: ?number,
|
|
133
133
|
* spatialAudio: boolean,
|
|
134
134
|
* closedCaptions: Map.<string, string>,
|
|
135
|
-
* tilesLayout: (string|undefined)
|
|
135
|
+
* tilesLayout: (string|undefined),
|
|
136
|
+
* external: boolean
|
|
136
137
|
* }}
|
|
137
138
|
*
|
|
138
139
|
* @property {number} id
|
|
@@ -193,6 +194,9 @@ shaka.extern.ManifestDB;
|
|
|
193
194
|
* The value is a grid-item-dimension consisting of two positive decimal
|
|
194
195
|
* integers in the format: column-x-row ('4x3'). It describes the arrangement
|
|
195
196
|
* of Images in a Grid. The minimum valid LAYOUT is '1x1'.
|
|
197
|
+
* @property {boolean} external
|
|
198
|
+
* Indicate if the stream was added externally.
|
|
199
|
+
* Eg: external text tracks.
|
|
196
200
|
*/
|
|
197
201
|
shaka.extern.StreamDB;
|
|
198
202
|
|
package/karma.conf.js
CHANGED
|
@@ -7,9 +7,11 @@
|
|
|
7
7
|
// Karma configuration
|
|
8
8
|
// Install required modules by running "npm install"
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
// lodash is an indirect dependency, depended on by Karma
|
|
11
|
+
const _ = require('lodash');
|
|
11
12
|
const fs = require('fs');
|
|
12
13
|
const glob = require('glob');
|
|
14
|
+
const Jimp = require('jimp');
|
|
13
15
|
const path = require('path');
|
|
14
16
|
const rimraf = require('rimraf');
|
|
15
17
|
const {ssim} = require('ssim.js');
|
|
@@ -17,6 +19,32 @@ const util = require('karma/common/util');
|
|
|
17
19
|
const which = require('which');
|
|
18
20
|
const yaml = require('js-yaml');
|
|
19
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Like Object.assign, but recursive and doesn't clobber objects and arrays.
|
|
24
|
+
* If two arrays are merged, they are concatenated.
|
|
25
|
+
* Ex:
|
|
26
|
+
* mergeConfigs({ foo: 'bar', args: [1, 2, 3] },
|
|
27
|
+
* { baz: 'blah', args: [4, 5, 6] })
|
|
28
|
+
* => { foo: 'bar', baz: 'blah', args: [1, 2, 3, 4, 5, 6] }
|
|
29
|
+
*
|
|
30
|
+
* @param {Object} first
|
|
31
|
+
* @param {Object} second
|
|
32
|
+
* @return {Object}
|
|
33
|
+
*/
|
|
34
|
+
function mergeConfigs(first, second) {
|
|
35
|
+
return _.mergeWith(
|
|
36
|
+
first,
|
|
37
|
+
second,
|
|
38
|
+
(firstValue, secondValue) => {
|
|
39
|
+
// Merge arrays by concatenation.
|
|
40
|
+
if (Array.isArray(firstValue)) {
|
|
41
|
+
return firstValue.concat(secondValue);
|
|
42
|
+
}
|
|
43
|
+
// Use lodash's default merge behavior for everything else.
|
|
44
|
+
return undefined;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
20
48
|
/**
|
|
21
49
|
* @param {Object} config
|
|
22
50
|
*/
|
|
@@ -78,7 +106,7 @@ module.exports = (config) => {
|
|
|
78
106
|
}
|
|
79
107
|
|
|
80
108
|
// Add standard WebDriver configs.
|
|
81
|
-
|
|
109
|
+
mergeConfigs(launcher, {
|
|
82
110
|
base: 'WebDriver',
|
|
83
111
|
config: {hostname: gridHostname, port: gridPort},
|
|
84
112
|
pseudoActivityInterval: 20000,
|
|
@@ -87,8 +115,10 @@ module.exports = (config) => {
|
|
|
87
115
|
version: metadata.version,
|
|
88
116
|
});
|
|
89
117
|
|
|
90
|
-
if (metadata.
|
|
91
|
-
|
|
118
|
+
if (metadata.extra_configs) {
|
|
119
|
+
for (const config of metadata.extra_configs) {
|
|
120
|
+
mergeConfigs(launcher, config);
|
|
121
|
+
}
|
|
92
122
|
}
|
|
93
123
|
}
|
|
94
124
|
|
|
@@ -321,6 +351,8 @@ module.exports = (config) => {
|
|
|
321
351
|
},
|
|
322
352
|
|
|
323
353
|
babelPreprocessor: {
|
|
354
|
+
// Cache results in .babel-cache
|
|
355
|
+
cachePath: '.babel-cache',
|
|
324
356
|
options: {
|
|
325
357
|
presets: ['@babel/preset-env'],
|
|
326
358
|
// Add source maps so that backtraces refer to the original code.
|
|
@@ -603,15 +635,27 @@ function WebDriverScreenshotMiddlewareFactory(launcher) {
|
|
|
603
635
|
}
|
|
604
636
|
|
|
605
637
|
/**
|
|
638
|
+
* @param {karma.Launcher.Browser.spec} spec
|
|
606
639
|
* @param {wd.remote} webDriverClient A WebDriver client, an object from the
|
|
607
640
|
* "wd" package, created by "wd.remote()".
|
|
608
641
|
* @return {!Promise.<!Buffer>} A Buffer containing a PNG screenshot
|
|
609
642
|
*/
|
|
610
|
-
function getScreenshot(webDriverClient) {
|
|
643
|
+
function getScreenshot(spec, webDriverClient) {
|
|
611
644
|
return new Promise((resolve, reject) => {
|
|
612
645
|
webDriverClient.takeScreenshot((error, pngBase64) => {
|
|
613
646
|
if (error) {
|
|
614
647
|
reject(error);
|
|
648
|
+
} else if (pngBase64.error) {
|
|
649
|
+
// In some failure cases, pngBase64 is an object with "error",
|
|
650
|
+
// "message", and "stacktrace" fields. This happens, for example,
|
|
651
|
+
// with a timeout from the screenshot command. This is not an
|
|
652
|
+
// expected situation, so log it. The extra newlines keep this from
|
|
653
|
+
// being overwritten on the terminal when running tests against many
|
|
654
|
+
// browsers at once.
|
|
655
|
+
console.log('\n\nUnexpected screenshot failure:\n' +
|
|
656
|
+
` Error: ${JSON.stringify(pngBase64)}\n` +
|
|
657
|
+
` WebDriver spec: ${JSON.stringify(spec)}\n\n\n`);
|
|
658
|
+
reject(pngBase64);
|
|
615
659
|
} else {
|
|
616
660
|
// Convert the screenshot to a binary buffer.
|
|
617
661
|
resolve(Buffer.from(pngBase64, 'base64'));
|
|
@@ -635,7 +679,8 @@ function WebDriverScreenshotMiddlewareFactory(launcher) {
|
|
|
635
679
|
}
|
|
636
680
|
|
|
637
681
|
/** @type {!Buffer} */
|
|
638
|
-
const fullPageScreenshotData =
|
|
682
|
+
const fullPageScreenshotData =
|
|
683
|
+
await getScreenshot(browser.spec, webDriverClient);
|
|
639
684
|
|
|
640
685
|
// Crop the screenshot to the dimensions specified in the test.
|
|
641
686
|
// Jimp is picky about types, so convert these strings to numbers.
|
|
@@ -754,7 +799,7 @@ function WebDriverScreenshotMiddlewareFactory(launcher) {
|
|
|
754
799
|
// The result is cached for the sake of performance.
|
|
755
800
|
if (webDriverClient.canTakeScreenshot === undefined) {
|
|
756
801
|
try {
|
|
757
|
-
await getScreenshot(webDriverClient);
|
|
802
|
+
await getScreenshot(browser.spec, webDriverClient);
|
|
758
803
|
webDriverClient.canTakeScreenshot = true;
|
|
759
804
|
} catch (error) {
|
|
760
805
|
webDriverClient.canTakeScreenshot = false;
|
|
@@ -48,6 +48,9 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
48
48
|
/** @private {shaka.abr.EwmaBandwidthEstimator} */
|
|
49
49
|
this.bandwidthEstimator_ = new shaka.abr.EwmaBandwidthEstimator();
|
|
50
50
|
|
|
51
|
+
/** @private {?function():void} */
|
|
52
|
+
this.onNetworkInformationChange_ = null;
|
|
53
|
+
|
|
51
54
|
// Some browsers implement the Network Information API, which allows
|
|
52
55
|
// retrieving information about a user's network connection. We listen
|
|
53
56
|
// to the change event to be able to make quick changes in case the type
|
|
@@ -98,9 +101,6 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
98
101
|
/** @private {ResizeObserver} */
|
|
99
102
|
this.resizeObserver_ = null;
|
|
100
103
|
|
|
101
|
-
/** @private {?function():void} */
|
|
102
|
-
this.onNetworkInformationChange_ = null;
|
|
103
|
-
|
|
104
104
|
/** @private {shaka.util.Timer} */
|
|
105
105
|
this.resizeObserverTimer_ = new shaka.util.Timer(() => {
|
|
106
106
|
if (this.config_.restrictToElementSize) {
|
|
@@ -175,8 +175,8 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
175
175
|
if (this.resizeObserver_ && this.config_.restrictToElementSize) {
|
|
176
176
|
const devicePixelRatio =
|
|
177
177
|
this.config_.ignoreDevicePixelRatio ? 1 : window.devicePixelRatio;
|
|
178
|
-
maxHeight = this.mediaElement_.
|
|
179
|
-
maxWidth = this.mediaElement_.
|
|
178
|
+
maxHeight = this.mediaElement_.clientHeight * devicePixelRatio;
|
|
179
|
+
maxWidth = this.mediaElement_.clientWidth * devicePixelRatio;
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
// Get sorted Variants.
|
|
@@ -33,6 +33,9 @@ shaka.ads.ClientSideAdManager = class {
|
|
|
33
33
|
/** @private {HTMLMediaElement} */
|
|
34
34
|
this.video_ = video;
|
|
35
35
|
|
|
36
|
+
/** @private {boolean} */
|
|
37
|
+
this.videoPlayed_ = false;
|
|
38
|
+
|
|
36
39
|
/** @private {ResizeObserver} */
|
|
37
40
|
this.resizeObserver_ = null;
|
|
38
41
|
|
|
@@ -82,6 +85,10 @@ shaka.ads.ClientSideAdManager = class {
|
|
|
82
85
|
this.eventManager_.listen(this.video_, 'ended', () => {
|
|
83
86
|
this.adsLoader_.contentComplete();
|
|
84
87
|
});
|
|
88
|
+
|
|
89
|
+
this.eventManager_.listenOnce(this.video_, 'play', () => {
|
|
90
|
+
this.videoPlayed_ = true;
|
|
91
|
+
});
|
|
85
92
|
}
|
|
86
93
|
|
|
87
94
|
/**
|
|
@@ -219,9 +226,14 @@ shaka.ads.ClientSideAdManager = class {
|
|
|
219
226
|
// seen the ads actually play until requestAds() is called.
|
|
220
227
|
// Note: We listen for a play event to avoid autoplay issues that might
|
|
221
228
|
// crash IMA.
|
|
222
|
-
|
|
229
|
+
if (this.videoPlayed_) {
|
|
223
230
|
this.imaAdsManager_.start();
|
|
224
|
-
}
|
|
231
|
+
} else {
|
|
232
|
+
this.eventManager_.listenOnce(this.video_, 'play', () => {
|
|
233
|
+
this.videoPlayed_ = true;
|
|
234
|
+
this.imaAdsManager_.start();
|
|
235
|
+
});
|
|
236
|
+
}
|
|
225
237
|
} catch (adError) {
|
|
226
238
|
// If there was a problem with the VAST response,
|
|
227
239
|
// we we won't be getting an ad. Hide ad UI if we showed it already
|
package/lib/dash/dash_parser.js
CHANGED
package/lib/hls/hls_parser.js
CHANGED
|
@@ -354,7 +354,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
354
354
|
let mimeType = shaka.util.MimeUtils.getFullType(
|
|
355
355
|
stream.mimeType, stream.codecs);
|
|
356
356
|
if (contentType == ContentType.TEXT) {
|
|
357
|
-
this.reinitText(mimeType, sequenceMode);
|
|
357
|
+
this.reinitText(mimeType, sequenceMode, stream.external);
|
|
358
358
|
} else {
|
|
359
359
|
if ((forceTransmuxTS || !MediaSource.isTypeSupported(mimeType)) &&
|
|
360
360
|
shaka.media.Transmuxer.isSupported(mimeType, contentType)) {
|
|
@@ -383,13 +383,14 @@ shaka.media.MediaSourceEngine = class {
|
|
|
383
383
|
* Reinitialize the TextEngine for a new text type.
|
|
384
384
|
* @param {string} mimeType
|
|
385
385
|
* @param {boolean} sequenceMode
|
|
386
|
+
* @param {boolean} external
|
|
386
387
|
*/
|
|
387
|
-
reinitText(mimeType, sequenceMode) {
|
|
388
|
+
reinitText(mimeType, sequenceMode, external) {
|
|
388
389
|
if (!this.textEngine_) {
|
|
389
390
|
this.textEngine_ = new shaka.text.TextEngine(this.textDisplayer_);
|
|
390
391
|
}
|
|
391
392
|
this.textEngine_.initParser(mimeType, sequenceMode,
|
|
392
|
-
this.segmentRelativeVttTiming_);
|
|
393
|
+
external || this.segmentRelativeVttTiming_);
|
|
393
394
|
}
|
|
394
395
|
|
|
395
396
|
/**
|
|
@@ -564,7 +565,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
564
565
|
// the video stream, so textEngine may not have been initialized.
|
|
565
566
|
if (!this.textEngine_) {
|
|
566
567
|
this.reinitText(shaka.util.MimeUtils.CEA608_CLOSED_CAPTION_MIMETYPE,
|
|
567
|
-
this.sequenceMode_);
|
|
568
|
+
this.sequenceMode_, /* external= */ false);
|
|
568
569
|
}
|
|
569
570
|
|
|
570
571
|
if (transmuxedData.metadata) {
|
|
@@ -593,7 +594,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
593
594
|
} else if (hasClosedCaptions) {
|
|
594
595
|
if (!this.textEngine_) {
|
|
595
596
|
this.reinitText(shaka.util.MimeUtils.CEA608_CLOSED_CAPTION_MIMETYPE,
|
|
596
|
-
this.sequenceMode_);
|
|
597
|
+
this.sequenceMode_, /* external= */ false);
|
|
597
598
|
}
|
|
598
599
|
// If it is the init segment for closed captions, initialize the closed
|
|
599
600
|
// caption parser.
|
|
@@ -240,7 +240,7 @@ shaka.media.StreamingEngine = class {
|
|
|
240
240
|
const mimeType = shaka.util.MimeUtils.getFullType(
|
|
241
241
|
stream.mimeType, stream.codecs);
|
|
242
242
|
this.playerInterface_.mediaSourceEngine.reinitText(
|
|
243
|
-
mimeType, this.manifest_.sequenceMode);
|
|
243
|
+
mimeType, this.manifest_.sequenceMode, stream.external);
|
|
244
244
|
|
|
245
245
|
const textDisplayer =
|
|
246
246
|
this.playerInterface_.mediaSourceEngine.getTextDisplayer();
|
|
@@ -447,7 +447,7 @@ shaka.media.StreamingEngine = class {
|
|
|
447
447
|
const fullMimeType = shaka.util.MimeUtils.getFullType(
|
|
448
448
|
stream.mimeType, stream.codecs);
|
|
449
449
|
this.playerInterface_.mediaSourceEngine.reinitText(
|
|
450
|
-
fullMimeType, this.manifest_.sequenceMode);
|
|
450
|
+
fullMimeType, this.manifest_.sequenceMode, stream.external);
|
|
451
451
|
}
|
|
452
452
|
|
|
453
453
|
// Releases the segmentIndex of the old stream.
|
package/lib/offline/storage.js
CHANGED
package/lib/player.js
CHANGED
|
@@ -2069,10 +2069,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2069
2069
|
|
|
2070
2070
|
this.playhead_.setStartTime(adjustedTime);
|
|
2071
2071
|
}
|
|
2072
|
-
|
|
2073
|
-
// Since the first streams just became active, send an adaptation event.
|
|
2074
|
-
this.onAdaptation_(null,
|
|
2075
|
-
shaka.util.StreamUtils.variantToTrack(initialVariant));
|
|
2076
2072
|
}
|
|
2077
2073
|
|
|
2078
2074
|
this.playhead_.ready();
|
|
@@ -2237,6 +2233,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2237
2233
|
audioSamplingRate: null,
|
|
2238
2234
|
spatialAudio: false,
|
|
2239
2235
|
closedCaptions: null,
|
|
2236
|
+
external: false,
|
|
2240
2237
|
},
|
|
2241
2238
|
bandwidth: 100,
|
|
2242
2239
|
allowedByApplication: true,
|
|
@@ -4631,6 +4628,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4631
4628
|
audioSamplingRate: null,
|
|
4632
4629
|
spatialAudio: false,
|
|
4633
4630
|
closedCaptions: null,
|
|
4631
|
+
external: true,
|
|
4634
4632
|
};
|
|
4635
4633
|
|
|
4636
4634
|
const fullMimeType = shaka.util.MimeUtils.getFullType(
|
|
@@ -5061,6 +5059,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5061
5059
|
audioSamplingRate: null,
|
|
5062
5060
|
spatialAudio: false,
|
|
5063
5061
|
closedCaptions: null,
|
|
5062
|
+
external: false,
|
|
5064
5063
|
};
|
|
5065
5064
|
manifest.textStreams.push(textStream);
|
|
5066
5065
|
closedCaptionsSet.add(id);
|
|
@@ -6635,7 +6634,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
6635
6634
|
* @define {string} A version number taken from git at compile time.
|
|
6636
6635
|
* @export
|
|
6637
6636
|
*/
|
|
6638
|
-
shaka.Player.version = 'v4.2.
|
|
6637
|
+
shaka.Player.version = 'v4.2.14-uncompiled';
|
|
6639
6638
|
|
|
6640
6639
|
// Initialize the deprecation system using the version string we just set
|
|
6641
6640
|
// on the player.
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
goog.provide('shaka.polyfill.Orientation');
|
|
8
8
|
|
|
9
|
+
goog.require('shaka.log');
|
|
9
10
|
goog.require('shaka.util.FakeEvent');
|
|
10
11
|
goog.require('shaka.util.FakeEventTarget');
|
|
11
12
|
goog.require('shaka.polyfill');
|
|
@@ -23,21 +24,47 @@ shaka.polyfill.Orientation = class {
|
|
|
23
24
|
* @export
|
|
24
25
|
*/
|
|
25
26
|
static install() {
|
|
26
|
-
if (screen.orientation) {
|
|
27
|
+
if (screen.orientation && screen.orientation.unlock) {
|
|
27
28
|
// Not needed.
|
|
29
|
+
shaka.log.info('Using native screen.orientation');
|
|
28
30
|
return;
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (window.orientation != undefined) {
|
|
33
|
+
if (screen.orientation != undefined) {
|
|
34
|
+
// There are some platforms where screen.orientation is defined but
|
|
35
|
+
// incomplete (e.g. Safari).
|
|
36
|
+
// Install a very simple polyfill in that case.
|
|
37
|
+
shaka.polyfill.Orientation.installBasedOnScreenMethods_();
|
|
38
|
+
} else if (window.orientation != undefined) {
|
|
39
|
+
// There is no way to check to see if the 'orientationchange' event exists
|
|
40
|
+
// on window, which could theoretically lead to this making a
|
|
41
|
+
// screen.orientation object that doesn't actually work.
|
|
42
|
+
// However, it looks like all platforms that support the deprecated
|
|
43
|
+
// window.orientation feature also support that event.
|
|
37
44
|
shaka.polyfill.Orientation.installBasedOnWindowMethods_();
|
|
38
45
|
}
|
|
39
46
|
}
|
|
40
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Modifies screen.orientation to add no-ops for missing methods.
|
|
50
|
+
* Meant for cases where screen.orientation is defined, but has missing
|
|
51
|
+
* methods that cannot be properly polyfilled.
|
|
52
|
+
* @private
|
|
53
|
+
*/
|
|
54
|
+
static installBasedOnScreenMethods_() {
|
|
55
|
+
if (screen.orientation.lock === undefined) {
|
|
56
|
+
screen.orientation.lock = (orientation) => {
|
|
57
|
+
shaka.log.info('screen.orientation.lock is a no-op');
|
|
58
|
+
return Promise.resolve();
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
if (screen.orientation.unlock === undefined) {
|
|
62
|
+
screen.orientation.unlock = () => {
|
|
63
|
+
shaka.log.info('screen.orientation.unlock is a no-op');
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
41
68
|
/**
|
|
42
69
|
* Makes a polyfill for orientation, based on window methods.
|
|
43
70
|
* Note that some of the features this is based on are deprecated, so this
|
|
@@ -180,8 +180,10 @@ shaka.util.ManifestParserUtils.VIDEO_CODEC_REGEXPS_ = [
|
|
|
180
180
|
*/
|
|
181
181
|
shaka.util.ManifestParserUtils.AUDIO_CODEC_REGEXPS_ = [
|
|
182
182
|
/^vorbis$/,
|
|
183
|
-
/^
|
|
184
|
-
/^
|
|
183
|
+
/^Opus$/, // correct codec string according to RFC 6381 section 3.3
|
|
184
|
+
/^opus$/, // some manifests wrongfully use this
|
|
185
|
+
/^fLaC$/, // correct codec string according to RFC 6381 section 3.3
|
|
186
|
+
/^flac$/, // some manifests wrongfully use this
|
|
185
187
|
/^mp4a/,
|
|
186
188
|
/^[ae]c-3$/,
|
|
187
189
|
/^ac-4$/,
|
package/lib/util/periods.js
CHANGED
|
@@ -1491,6 +1491,7 @@ shaka.util.PeriodCombiner = class {
|
|
|
1491
1491
|
audioSamplingRate: null,
|
|
1492
1492
|
spatialAudio: false,
|
|
1493
1493
|
closedCaptions: null,
|
|
1494
|
+
external: false,
|
|
1494
1495
|
};
|
|
1495
1496
|
}
|
|
1496
1497
|
|
|
@@ -1527,6 +1528,7 @@ shaka.util.PeriodCombiner = class {
|
|
|
1527
1528
|
audioSamplingRate: null,
|
|
1528
1529
|
spatialAudio: false,
|
|
1529
1530
|
closedCaptions: null,
|
|
1531
|
+
external: false,
|
|
1530
1532
|
};
|
|
1531
1533
|
}
|
|
1532
1534
|
|
package/lib/util/platform.js
CHANGED
|
@@ -214,6 +214,7 @@ shaka.util.Platform = class {
|
|
|
214
214
|
!shaka.util.Platform.isTizen() &&
|
|
215
215
|
!shaka.util.Platform.isEOS() &&
|
|
216
216
|
!shaka.util.Platform.isVirginMedia() &&
|
|
217
|
+
!shaka.util.Platform.isOrange() &&
|
|
217
218
|
!shaka.util.Platform.isPS4() &&
|
|
218
219
|
!shaka.util.Platform.isAmazonFireTV();
|
|
219
220
|
}
|
|
@@ -253,6 +254,13 @@ shaka.util.Platform = class {
|
|
|
253
254
|
return shaka.util.Platform.userAgentContains_('VirginMedia');
|
|
254
255
|
}
|
|
255
256
|
|
|
257
|
+
/**
|
|
258
|
+
* Check if the current platform is Orange.
|
|
259
|
+
*/
|
|
260
|
+
static isOrange() {
|
|
261
|
+
return shaka.util.Platform.userAgentContains_('SOPOpenBrowser');
|
|
262
|
+
}
|
|
263
|
+
|
|
256
264
|
/**
|
|
257
265
|
* Check if the current platform is Amazon Fire TV.
|
|
258
266
|
* https://developer.amazon.com/docs/fire-tv/identify-amazon-fire-tv-devices.html
|
|
@@ -346,6 +354,20 @@ shaka.util.Platform = class {
|
|
|
346
354
|
return shaka.util.Platform.isApple() && navigator.maxTouchPoints > 1;
|
|
347
355
|
}
|
|
348
356
|
|
|
357
|
+
/**
|
|
358
|
+
* Return true if the platform is a Mac, regardless of the browser.
|
|
359
|
+
*
|
|
360
|
+
* @return {boolean}
|
|
361
|
+
*/
|
|
362
|
+
static isMac() {
|
|
363
|
+
// Try the newer standard first.
|
|
364
|
+
if (navigator.userAgentData && navigator.userAgentData.platform) {
|
|
365
|
+
return navigator.userAgentData.platform.toLowerCase() == 'macos';
|
|
366
|
+
}
|
|
367
|
+
// Fall back to the old API, with less strict matching.
|
|
368
|
+
return navigator.platform.toLowerCase().includes('mac');
|
|
369
|
+
}
|
|
370
|
+
|
|
349
371
|
/**
|
|
350
372
|
* Check if the user agent contains a key. This is the best way we know of
|
|
351
373
|
* right now to detect platforms. If there is a better way, please send a
|