shaka-player 4.2.12 → 4.2.13
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 +15 -0
- package/.github/workflows/selenium-lab-tests.yaml +3 -2
- package/.github/workflows/update-issues.yaml +1 -0
- package/CHANGELOG.md +17 -0
- package/dist/deps.js +1 -1
- package/dist/locales.js +31 -31
- package/dist/shaka-player.compiled.debug.js +23 -24
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.js +368 -369
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.debug.js +27 -29
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.js +383 -383
- package/dist/shaka-player.ui.map +2 -2
- package/docs/tutorials/selenium-grid-config.md +60 -8
- package/karma.conf.js +50 -7
- package/lib/abr/simple_abr_manager.js +5 -5
- package/lib/player.js +1 -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/platform.js +14 -0
- package/lib/util/stream_utils.js +69 -26
- package/package.json +2 -2
- package/test/cast/cast_utils_unit.js +4 -1
- package/test/hls/hls_parser_unit.js +72 -0
- package/test/media/drm_engine_integration.js +2 -2
- package/test/media/segment_index_unit.js +3 -3
- package/test/media/streaming_engine_integration.js +14 -11
- package/test/offline/offline_integration.js +6 -3
- package/test/player_external.js +19 -16
- package/test/player_integration.js +35 -48
- 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/ui_utils.js +9 -2
- 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/range_element.js +5 -0
|
@@ -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
|
+
```
|
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
|
|
|
@@ -603,15 +633,27 @@ function WebDriverScreenshotMiddlewareFactory(launcher) {
|
|
|
603
633
|
}
|
|
604
634
|
|
|
605
635
|
/**
|
|
636
|
+
* @param {karma.Launcher.Browser.spec} spec
|
|
606
637
|
* @param {wd.remote} webDriverClient A WebDriver client, an object from the
|
|
607
638
|
* "wd" package, created by "wd.remote()".
|
|
608
639
|
* @return {!Promise.<!Buffer>} A Buffer containing a PNG screenshot
|
|
609
640
|
*/
|
|
610
|
-
function getScreenshot(webDriverClient) {
|
|
641
|
+
function getScreenshot(spec, webDriverClient) {
|
|
611
642
|
return new Promise((resolve, reject) => {
|
|
612
643
|
webDriverClient.takeScreenshot((error, pngBase64) => {
|
|
613
644
|
if (error) {
|
|
614
645
|
reject(error);
|
|
646
|
+
} else if (pngBase64.error) {
|
|
647
|
+
// In some failure cases, pngBase64 is an object with "error",
|
|
648
|
+
// "message", and "stacktrace" fields. This happens, for example,
|
|
649
|
+
// with a timeout from the screenshot command. This is not an
|
|
650
|
+
// expected situation, so log it. The extra newlines keep this from
|
|
651
|
+
// being overwritten on the terminal when running tests against many
|
|
652
|
+
// browsers at once.
|
|
653
|
+
console.log('\n\nUnexpected screenshot failure:\n' +
|
|
654
|
+
` Error: ${JSON.stringify(pngBase64)}\n` +
|
|
655
|
+
` WebDriver spec: ${JSON.stringify(spec)}\n\n\n`);
|
|
656
|
+
reject(pngBase64);
|
|
615
657
|
} else {
|
|
616
658
|
// Convert the screenshot to a binary buffer.
|
|
617
659
|
resolve(Buffer.from(pngBase64, 'base64'));
|
|
@@ -635,7 +677,8 @@ function WebDriverScreenshotMiddlewareFactory(launcher) {
|
|
|
635
677
|
}
|
|
636
678
|
|
|
637
679
|
/** @type {!Buffer} */
|
|
638
|
-
const fullPageScreenshotData =
|
|
680
|
+
const fullPageScreenshotData =
|
|
681
|
+
await getScreenshot(browser.spec, webDriverClient);
|
|
639
682
|
|
|
640
683
|
// Crop the screenshot to the dimensions specified in the test.
|
|
641
684
|
// Jimp is picky about types, so convert these strings to numbers.
|
|
@@ -754,7 +797,7 @@ function WebDriverScreenshotMiddlewareFactory(launcher) {
|
|
|
754
797
|
// The result is cached for the sake of performance.
|
|
755
798
|
if (webDriverClient.canTakeScreenshot === undefined) {
|
|
756
799
|
try {
|
|
757
|
-
await getScreenshot(webDriverClient);
|
|
800
|
+
await getScreenshot(browser.spec, webDriverClient);
|
|
758
801
|
webDriverClient.canTakeScreenshot = true;
|
|
759
802
|
} catch (error) {
|
|
760
803
|
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.
|
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();
|
|
@@ -6635,7 +6631,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
6635
6631
|
* @define {string} A version number taken from git at compile time.
|
|
6636
6632
|
* @export
|
|
6637
6633
|
*/
|
|
6638
|
-
shaka.Player.version = 'v4.2.
|
|
6634
|
+
shaka.Player.version = 'v4.2.13-uncompiled';
|
|
6639
6635
|
|
|
6640
6636
|
// Initialize the deprecation system using the version string we just set
|
|
6641
6637
|
// 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/platform.js
CHANGED
|
@@ -346,6 +346,20 @@ shaka.util.Platform = class {
|
|
|
346
346
|
return shaka.util.Platform.isApple() && navigator.maxTouchPoints > 1;
|
|
347
347
|
}
|
|
348
348
|
|
|
349
|
+
/**
|
|
350
|
+
* Return true if the platform is a Mac, regardless of the browser.
|
|
351
|
+
*
|
|
352
|
+
* @return {boolean}
|
|
353
|
+
*/
|
|
354
|
+
static isMac() {
|
|
355
|
+
// Try the newer standard first.
|
|
356
|
+
if (navigator.userAgentData && navigator.userAgentData.platform) {
|
|
357
|
+
return navigator.userAgentData.platform.toLowerCase() == 'macos';
|
|
358
|
+
}
|
|
359
|
+
// Fall back to the old API, with less strict matching.
|
|
360
|
+
return navigator.platform.toLowerCase().includes('mac');
|
|
361
|
+
}
|
|
362
|
+
|
|
349
363
|
/**
|
|
350
364
|
* Check if the user agent contains a key. This is the best way we know of
|
|
351
365
|
* right now to detect platforms. If there is a better way, please send a
|
package/lib/util/stream_utils.js
CHANGED
|
@@ -436,47 +436,61 @@ shaka.util.StreamUtils = class {
|
|
|
436
436
|
manifest.variants = manifest.variants.filter((variant) => {
|
|
437
437
|
// See: https://github.com/shaka-project/shaka-player/issues/3860
|
|
438
438
|
const video = variant.video;
|
|
439
|
+
|
|
439
440
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
441
|
+
const ManifestParserUtils = shaka.util.ManifestParserUtils;
|
|
442
|
+
const MimeUtils = shaka.util.MimeUtils;
|
|
443
|
+
const StreamUtils = shaka.util.StreamUtils;
|
|
444
|
+
|
|
440
445
|
if (video) {
|
|
441
|
-
let videoCodecs =
|
|
442
|
-
|
|
446
|
+
let videoCodecs = StreamUtils.getCorrectVideoCodecs_(video.codecs);
|
|
447
|
+
|
|
443
448
|
// For multiplexed streams. Here we must check the audio of the
|
|
444
449
|
// stream to see if it is compatible.
|
|
445
450
|
if (video.codecs.includes(',')) {
|
|
446
451
|
const allCodecs = video.codecs.split(',');
|
|
447
|
-
|
|
452
|
+
|
|
453
|
+
videoCodecs = ManifestParserUtils.guessCodecs(
|
|
448
454
|
ContentType.VIDEO, allCodecs);
|
|
449
|
-
videoCodecs =
|
|
450
|
-
|
|
451
|
-
let audioCodecs =
|
|
455
|
+
videoCodecs = StreamUtils.getCorrectVideoCodecs_(videoCodecs);
|
|
456
|
+
|
|
457
|
+
let audioCodecs = ManifestParserUtils.guessCodecs(
|
|
452
458
|
ContentType.AUDIO, allCodecs);
|
|
453
|
-
audioCodecs =
|
|
454
|
-
|
|
455
|
-
const audioFullType =
|
|
459
|
+
audioCodecs = StreamUtils.getCorrectAudioCodecs_(audioCodecs);
|
|
460
|
+
|
|
461
|
+
const audioFullType = MimeUtils.getFullOrConvertedType(
|
|
456
462
|
video.mimeType, audioCodecs, ContentType.AUDIO);
|
|
463
|
+
|
|
457
464
|
if (!MediaSource.isTypeSupported(audioFullType)) {
|
|
458
465
|
return false;
|
|
459
466
|
}
|
|
467
|
+
|
|
460
468
|
// Update the codec string with the (possibly) converted codecs.
|
|
461
469
|
videoCodecs = [videoCodecs, audioCodecs].join(',');
|
|
462
470
|
}
|
|
463
|
-
|
|
471
|
+
|
|
472
|
+
const fullType = MimeUtils.getFullOrConvertedType(
|
|
464
473
|
video.mimeType, videoCodecs, ContentType.VIDEO);
|
|
474
|
+
|
|
465
475
|
if (!MediaSource.isTypeSupported(fullType)) {
|
|
466
476
|
return false;
|
|
467
477
|
}
|
|
478
|
+
|
|
468
479
|
// Update the codec string with the (possibly) converted codecs.
|
|
469
480
|
video.codecs = videoCodecs;
|
|
470
481
|
}
|
|
482
|
+
|
|
471
483
|
const audio = variant.audio;
|
|
484
|
+
|
|
472
485
|
if (audio) {
|
|
473
|
-
const codecs =
|
|
474
|
-
|
|
475
|
-
const fullType = shaka.util.MimeUtils.getFullOrConvertedType(
|
|
486
|
+
const codecs = StreamUtils.getCorrectAudioCodecs_(audio.codecs);
|
|
487
|
+
const fullType = MimeUtils.getFullOrConvertedType(
|
|
476
488
|
audio.mimeType, codecs, ContentType.AUDIO);
|
|
489
|
+
|
|
477
490
|
if (!MediaSource.isTypeSupported(fullType)) {
|
|
478
491
|
return false;
|
|
479
492
|
}
|
|
493
|
+
|
|
480
494
|
// Update the codec string with the (possibly) converted codecs.
|
|
481
495
|
audio.codecs = codecs;
|
|
482
496
|
}
|
|
@@ -488,7 +502,7 @@ shaka.util.StreamUtils = class {
|
|
|
488
502
|
(video.codecs.includes('avc1.') ||
|
|
489
503
|
video.codecs.includes('avc3.'))) {
|
|
490
504
|
shaka.log.debug('Dropping variant - not compatible with platform',
|
|
491
|
-
|
|
505
|
+
StreamUtils.getVariantSummaryString_(variant));
|
|
492
506
|
return false;
|
|
493
507
|
}
|
|
494
508
|
|
|
@@ -498,7 +512,7 @@ shaka.util.StreamUtils = class {
|
|
|
498
512
|
// Filter out all unsupported variants.
|
|
499
513
|
if (!supported) {
|
|
500
514
|
shaka.log.debug('Dropping variant - not compatible with platform',
|
|
501
|
-
|
|
515
|
+
StreamUtils.getVariantSummaryString_(variant));
|
|
502
516
|
}
|
|
503
517
|
return supported;
|
|
504
518
|
});
|
|
@@ -562,7 +576,11 @@ shaka.util.StreamUtils = class {
|
|
|
562
576
|
static getDecodingConfigs_(variant, usePersistentLicenses, srcEquals) {
|
|
563
577
|
const audio = variant.audio;
|
|
564
578
|
const video = variant.video;
|
|
579
|
+
|
|
565
580
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
581
|
+
const ManifestParserUtils = shaka.util.ManifestParserUtils;
|
|
582
|
+
const MimeUtils = shaka.util.MimeUtils;
|
|
583
|
+
const StreamUtils = shaka.util.StreamUtils;
|
|
566
584
|
|
|
567
585
|
/** @type {!MediaDecodingConfiguration} */
|
|
568
586
|
const mediaDecodingConfig = {
|
|
@@ -571,19 +589,23 @@ shaka.util.StreamUtils = class {
|
|
|
571
589
|
|
|
572
590
|
if (video) {
|
|
573
591
|
let videoCodecs = video.codecs;
|
|
592
|
+
|
|
574
593
|
// For multiplexed streams with audio+video codecs, the config should have
|
|
575
594
|
// AudioConfiguration and VideoConfiguration.
|
|
576
595
|
if (video.codecs.includes(',')) {
|
|
577
596
|
const allCodecs = video.codecs.split(',');
|
|
578
|
-
|
|
597
|
+
|
|
598
|
+
videoCodecs = ManifestParserUtils.guessCodecs(
|
|
579
599
|
ContentType.VIDEO, allCodecs);
|
|
580
|
-
videoCodecs =
|
|
581
|
-
|
|
582
|
-
|
|
600
|
+
videoCodecs = StreamUtils.getCorrectVideoCodecs_(videoCodecs);
|
|
601
|
+
|
|
602
|
+
let audioCodecs = ManifestParserUtils.guessCodecs(
|
|
583
603
|
ContentType.AUDIO, allCodecs);
|
|
604
|
+
audioCodecs = StreamUtils.getCorrectAudioCodecs_(audioCodecs);
|
|
584
605
|
|
|
585
|
-
const audioFullType =
|
|
606
|
+
const audioFullType = MimeUtils.getFullOrConvertedType(
|
|
586
607
|
video.mimeType, audioCodecs, ContentType.AUDIO);
|
|
608
|
+
|
|
587
609
|
mediaDecodingConfig.audio = {
|
|
588
610
|
contentType: audioFullType,
|
|
589
611
|
channels: 2,
|
|
@@ -592,9 +614,11 @@ shaka.util.StreamUtils = class {
|
|
|
592
614
|
spatialRendering: false,
|
|
593
615
|
};
|
|
594
616
|
}
|
|
595
|
-
|
|
596
|
-
|
|
617
|
+
|
|
618
|
+
videoCodecs = StreamUtils.getCorrectVideoCodecs_(videoCodecs);
|
|
619
|
+
const fullType = MimeUtils.getFullOrConvertedType(
|
|
597
620
|
video.mimeType, videoCodecs, ContentType.VIDEO);
|
|
621
|
+
|
|
598
622
|
// VideoConfiguration
|
|
599
623
|
mediaDecodingConfig.video = {
|
|
600
624
|
contentType: fullType,
|
|
@@ -627,9 +651,8 @@ shaka.util.StreamUtils = class {
|
|
|
627
651
|
}
|
|
628
652
|
}
|
|
629
653
|
if (audio) {
|
|
630
|
-
const codecs =
|
|
631
|
-
|
|
632
|
-
const fullType = shaka.util.MimeUtils.getFullOrConvertedType(
|
|
654
|
+
const codecs = StreamUtils.getCorrectAudioCodecs_(audio.codecs);
|
|
655
|
+
const fullType = MimeUtils.getFullOrConvertedType(
|
|
633
656
|
audio.mimeType, codecs, ContentType.AUDIO);
|
|
634
657
|
|
|
635
658
|
// AudioConfiguration
|
|
@@ -760,6 +783,20 @@ shaka.util.StreamUtils = class {
|
|
|
760
783
|
* @private
|
|
761
784
|
*/
|
|
762
785
|
static getCorrectAudioCodecs_(codecs) {
|
|
786
|
+
// According to RFC 6381 section 3.3, 'fLaC' is actually the correct
|
|
787
|
+
// codec string. We still need to map it to 'flac', as some browsers
|
|
788
|
+
// currently don't support 'fLaC', while 'flac' is supported by most
|
|
789
|
+
// major browsers.
|
|
790
|
+
// See https://bugs.chromium.org/p/chromium/issues/detail?id=1422728
|
|
791
|
+
if (codecs === 'fLaC') {
|
|
792
|
+
return 'flac';
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
// The same is true for 'Opus'.
|
|
796
|
+
if (codecs === 'Opus') {
|
|
797
|
+
return 'opus';
|
|
798
|
+
}
|
|
799
|
+
|
|
763
800
|
// Some Tizen devices seem to misreport AC-3 support, but correctly
|
|
764
801
|
// report EC-3 support. So query EC-3 as a fallback for AC-3.
|
|
765
802
|
// See https://github.com/shaka-project/shaka-player/issues/2989 for
|
|
@@ -1238,6 +1275,9 @@ shaka.util.StreamUtils = class {
|
|
|
1238
1275
|
if (textTrack.kind == 'captions') {
|
|
1239
1276
|
track.mimeType = CLOSED_CAPTION_MIMETYPE;
|
|
1240
1277
|
}
|
|
1278
|
+
if (textTrack.kind == 'subtitles') {
|
|
1279
|
+
track.mimeType = 'text/vtt';
|
|
1280
|
+
}
|
|
1241
1281
|
if (textTrack.kind) {
|
|
1242
1282
|
track.roles = [textTrack.kind];
|
|
1243
1283
|
}
|
|
@@ -1285,13 +1325,15 @@ shaka.util.StreamUtils = class {
|
|
|
1285
1325
|
* @private
|
|
1286
1326
|
*/
|
|
1287
1327
|
static html5TrackToGenericShakaTrack_(html5Track) {
|
|
1328
|
+
const language = html5Track.language;
|
|
1329
|
+
|
|
1288
1330
|
/** @type {shaka.extern.Track} */
|
|
1289
1331
|
const track = {
|
|
1290
1332
|
id: shaka.util.StreamUtils.html5TrackId(html5Track),
|
|
1291
1333
|
active: false,
|
|
1292
1334
|
type: '',
|
|
1293
1335
|
bandwidth: 0,
|
|
1294
|
-
language: shaka.util.LanguageUtils.normalize(
|
|
1336
|
+
language: shaka.util.LanguageUtils.normalize(language || 'und'),
|
|
1295
1337
|
label: html5Track.label,
|
|
1296
1338
|
kind: html5Track.kind,
|
|
1297
1339
|
width: null,
|
|
@@ -1321,6 +1363,7 @@ shaka.util.StreamUtils = class {
|
|
|
1321
1363
|
originalAudioId: null,
|
|
1322
1364
|
originalTextId: null,
|
|
1323
1365
|
originalImageId: null,
|
|
1366
|
+
originalLanguage: language,
|
|
1324
1367
|
};
|
|
1325
1368
|
|
|
1326
1369
|
return track;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shaka-player",
|
|
3
3
|
"description": "DASH/EME video player library",
|
|
4
|
-
"version": "4.2.
|
|
4
|
+
"version": "4.2.13",
|
|
5
5
|
"homepage": "https://github.com/shaka-project/shaka-player",
|
|
6
6
|
"author": "Google",
|
|
7
7
|
"maintainers": [
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"karma-coverage": "^2.2.0",
|
|
43
43
|
"karma-jasmine": "^4.0.1",
|
|
44
44
|
"karma-jasmine-ajax": "^0.1.13",
|
|
45
|
-
"karma-local-wd-launcher": "^1.6.
|
|
45
|
+
"karma-local-wd-launcher": "^1.6.4",
|
|
46
46
|
"karma-opera-launcher": "^1.0.0",
|
|
47
47
|
"karma-sourcemap-loader": "^0.3.8",
|
|
48
48
|
"karma-spec-reporter": "^0.0.34",
|
|
@@ -171,7 +171,10 @@ describe('CastUtils', () => {
|
|
|
171
171
|
}
|
|
172
172
|
});
|
|
173
173
|
|
|
174
|
-
|
|
174
|
+
// Disable because these tests are flakey on ChromeLinux, and this whole
|
|
175
|
+
// module will be removed in
|
|
176
|
+
// https://github.com/shaka-project/shaka-player/issues/4214
|
|
177
|
+
xdescribe('TimeRanges', () => {
|
|
175
178
|
/** @type {!HTMLVideoElement} */
|
|
176
179
|
let video;
|
|
177
180
|
/** @type {!shaka.util.EventManager} */
|