shaka-player 4.3.14 → 4.3.15
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/workflows/shaka-bot-commands/lib.sh +37 -12
- package/.github/workflows/shaka-bot-commands/main.sh +4 -2
- package/.github/workflows/talk-to-shaka-bot.yaml +1 -0
- package/CHANGELOG.md +9 -0
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/locales.js +32 -32
- package/dist/shaka-player.compiled.debug.js +14 -12
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.js +113 -113
- package/dist/shaka-player.compiled.map +2 -2
- package/dist/shaka-player.ui.debug.js +16 -15
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.js +227 -227
- package/dist/shaka-player.ui.map +2 -2
- package/lib/deprecate/deprecate.js +1 -1
- package/lib/hls/hls_parser.js +16 -1
- package/lib/media/manifest_parser.js +2 -1
- package/lib/player.js +2 -2
- package/lib/polyfill/mediasource.js +5 -36
- package/lib/text/vtt_text_parser.js +2 -1
- package/lib/util/error.js +1 -0
- package/package.json +2 -2
- package/test/hls/hls_parser_unit.js +28 -0
- package/test/player_integration.js +9 -1
- package/test/player_load_graph_integration.js +13 -7
- package/test/player_src_equals_integration.js +2 -2
- package/test/player_unit.js +9 -3
- package/test/text/vtt_text_parser_unit.js +31 -0
- package/ui/less/containers.less +1 -0
package/lib/hls/hls_parser.js
CHANGED
|
@@ -3382,7 +3382,22 @@ shaka.hls.HlsParser = class {
|
|
|
3382
3382
|
* @return {?shaka.extern.DrmInfo}
|
|
3383
3383
|
* @private
|
|
3384
3384
|
*/
|
|
3385
|
-
static identityDrmParser_(drmTag) {
|
|
3385
|
+
static identityDrmParser_(drmTag, mimeType) {
|
|
3386
|
+
if (mimeType == 'video/mp2t') {
|
|
3387
|
+
throw new shaka.util.Error(
|
|
3388
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
3389
|
+
shaka.util.Error.Category.MANIFEST,
|
|
3390
|
+
shaka.util.Error.Code.HLS_MSE_ENCRYPTED_MP2T_NOT_SUPPORTED);
|
|
3391
|
+
}
|
|
3392
|
+
|
|
3393
|
+
if (shaka.util.Platform.isMediaKeysPolyfilled()) {
|
|
3394
|
+
throw new shaka.util.Error(
|
|
3395
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
3396
|
+
shaka.util.Error.Category.MANIFEST,
|
|
3397
|
+
shaka.util.Error.Code
|
|
3398
|
+
.HLS_MSE_ENCRYPTED_LEGACY_APPLE_MEDIA_KEYS_NOT_SUPPORTED);
|
|
3399
|
+
}
|
|
3400
|
+
|
|
3386
3401
|
const method = drmTag.getRequiredAttrValue('METHOD');
|
|
3387
3402
|
const VALID_METHODS = ['SAMPLE-AES', 'SAMPLE-AES-CTR'];
|
|
3388
3403
|
if (!VALID_METHODS.includes(method)) {
|
package/lib/player.js
CHANGED
|
@@ -2120,7 +2120,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2120
2120
|
this.abrManager_ = abrFactory();
|
|
2121
2121
|
if (typeof this.abrManager_.setMediaElement != 'function') {
|
|
2122
2122
|
shaka.Deprecate.deprecateFeature(5,
|
|
2123
|
-
'AbrManager',
|
|
2123
|
+
'AbrManager w/o setMediaElement',
|
|
2124
2124
|
'Please use an AbrManager with setMediaElement function.');
|
|
2125
2125
|
this.abrManager_.setMediaElement = () => {};
|
|
2126
2126
|
}
|
|
@@ -7032,7 +7032,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
7032
7032
|
* @export
|
|
7033
7033
|
*/
|
|
7034
7034
|
// eslint-disable-next-line no-useless-concat
|
|
7035
|
-
shaka.Player.version = 'v4.3.
|
|
7035
|
+
shaka.Player.version = 'v4.3.15' + '-uncompiled'; // x-release-please-version
|
|
7036
7036
|
|
|
7037
7037
|
// Initialize the deprecation system using the version string we just set
|
|
7038
7038
|
// on the player.
|
|
@@ -32,11 +32,12 @@ shaka.polyfill.MediaSource = class {
|
|
|
32
32
|
|
|
33
33
|
if (!window.MediaSource) {
|
|
34
34
|
shaka.log.info('No MSE implementation available.');
|
|
35
|
-
} else if (
|
|
36
|
-
cast.__platform__.canDisplayType) {
|
|
35
|
+
} else if (shaka.util.Platform.isChromecast()) {
|
|
37
36
|
shaka.log.info('Patching Chromecast MSE bugs.');
|
|
38
|
-
// Chromecast
|
|
39
|
-
|
|
37
|
+
// Chromecast fails on some TS content, even though it is supposed to
|
|
38
|
+
// support it. Better to transmux.
|
|
39
|
+
// See https://github.com/shaka-project/shaka-player/issues/5278
|
|
40
|
+
shaka.polyfill.MediaSource.rejectContainer_('mp2t');
|
|
40
41
|
} else if (safariVersion) {
|
|
41
42
|
// NOTE: shaka.Player.isBrowserSupported() has its own restrictions on
|
|
42
43
|
// Safari version.
|
|
@@ -161,38 +162,6 @@ shaka.polyfill.MediaSource = class {
|
|
|
161
162
|
};
|
|
162
163
|
}
|
|
163
164
|
|
|
164
|
-
/**
|
|
165
|
-
* Patch isTypeSupported() to chain to a private API on the Chromecast which
|
|
166
|
-
* can query for support of detailed content parameters.
|
|
167
|
-
*
|
|
168
|
-
* @private
|
|
169
|
-
*/
|
|
170
|
-
static patchCastIsTypeSupported_() {
|
|
171
|
-
const originalIsTypeSupported = MediaSource.isTypeSupported;
|
|
172
|
-
|
|
173
|
-
MediaSource.isTypeSupported = (mimeType) => {
|
|
174
|
-
// Parse the basic MIME type from its parameters.
|
|
175
|
-
const pieces = mimeType.split(/ *; */);
|
|
176
|
-
pieces.shift(); // Remove basic MIME type from pieces.
|
|
177
|
-
|
|
178
|
-
const hasCodecs = pieces.some((piece) => piece.startsWith('codecs='));
|
|
179
|
-
if (!hasCodecs) {
|
|
180
|
-
// Though the original reason for this special case was not documented,
|
|
181
|
-
// it is presumed to be because the platform won't accept a MIME type
|
|
182
|
-
// without codecs in canDisplayType. It is valid, however, in
|
|
183
|
-
// isTypeSupported.
|
|
184
|
-
return originalIsTypeSupported(mimeType);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Only canDisplayType can check extended MIME type parameters on this
|
|
188
|
-
// platform (such as frame rate, resolution, etc).
|
|
189
|
-
// In previous versions of this polyfill, the MIME type parameters were
|
|
190
|
-
// manipulated, filtered, or extended. This is no longer true, so we pass
|
|
191
|
-
// the full MIME type to the platform as we received it.
|
|
192
|
-
return cast.__platform__.canDisplayType(mimeType);
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
|
|
196
165
|
/**
|
|
197
166
|
* Patch isTypeSupported() to translate vp09 codec strings into vp9, to allow
|
|
198
167
|
* such content to play on older smart TVs.
|
|
@@ -673,13 +673,14 @@ shaka.text.VttTextParser = class {
|
|
|
673
673
|
refCue.fontFamily, cue.fontFamily);
|
|
674
674
|
cue.fontSize = VttTextParser.getOrDefault_(
|
|
675
675
|
refCue.fontSize, cue.fontSize);
|
|
676
|
+
cue.textShadow = VttTextParser.getOrDefault_(
|
|
677
|
+
refCue.textShadow, cue.textShadow);
|
|
676
678
|
|
|
677
679
|
// Overwrite with new values as unable to determine
|
|
678
680
|
// if new value is set or not
|
|
679
681
|
cue.fontWeight = refCue.fontWeight;
|
|
680
682
|
cue.fontStyle = refCue.fontStyle;
|
|
681
683
|
cue.opacity = refCue.opacity;
|
|
682
|
-
cue.textShadow = refCue.textShadow;
|
|
683
684
|
cue.wrapLine = refCue.wrapLine;
|
|
684
685
|
}
|
|
685
686
|
|
package/lib/util/error.js
CHANGED
|
@@ -506,6 +506,7 @@ shaka.util.Error.Code = {
|
|
|
506
506
|
* <li>Configure the server to accept a HEAD request for the manifest.
|
|
507
507
|
* </ul>
|
|
508
508
|
* <br> error.data[0] is the manifest URI.
|
|
509
|
+
* <br> error.data[1] is the detected or specified MIME type.
|
|
509
510
|
*/
|
|
510
511
|
'UNABLE_TO_GUESS_MANIFEST_TYPE': 4000,
|
|
511
512
|
|
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.3.
|
|
4
|
+
"version": "4.3.15",
|
|
5
5
|
"homepage": "https://github.com/shaka-project/shaka-player",
|
|
6
6
|
"author": "Google",
|
|
7
7
|
"maintainers": [
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"karma-spec-reporter": "^0.0.34",
|
|
49
49
|
"karma-webdriver-launcher": "^1.0.8",
|
|
50
50
|
"lcevc_dil.js": "^1.1.20",
|
|
51
|
-
"less": "
|
|
51
|
+
"less": "^4.2.0",
|
|
52
52
|
"less-plugin-clean-css": "github:austingardner/less-plugin-clean-css#4e9e77bf",
|
|
53
53
|
"material-design-lite": "^1.3.0",
|
|
54
54
|
"mux.js": "^6.2.0",
|
|
@@ -3743,6 +3743,34 @@ describe('HlsParser', () => {
|
|
|
3743
3743
|
await verifyError(master, media, error, /* onCreateSegmentIndex= */ true);
|
|
3744
3744
|
});
|
|
3745
3745
|
|
|
3746
|
+
it('if SAMPLE-AES encryption with MSE and mp2t content', async () => {
|
|
3747
|
+
const master = [
|
|
3748
|
+
'#EXTM3U\n',
|
|
3749
|
+
'#EXT-X-STREAM-INF:BANDWIDTH=200,CODECS="avc1",',
|
|
3750
|
+
'RESOLUTION=960x540,FRAME-RATE=60\n',
|
|
3751
|
+
'video\n',
|
|
3752
|
+
].join('');
|
|
3753
|
+
|
|
3754
|
+
const media = [
|
|
3755
|
+
'#EXTM3U\n',
|
|
3756
|
+
'#EXT-X-TARGETDURATION:6\n',
|
|
3757
|
+
'#EXT-X-PLAYLIST-TYPE:VOD\n',
|
|
3758
|
+
'#EXT-X-KEY:METHOD=SAMPLE-AES,',
|
|
3759
|
+
'URI="fake",\n',
|
|
3760
|
+
'#EXTINF:5,\n',
|
|
3761
|
+
'#EXT-X-BYTERANGE:121090@616\n',
|
|
3762
|
+
'main.ts',
|
|
3763
|
+
].join('');
|
|
3764
|
+
|
|
3765
|
+
const error = new shaka.util.Error(
|
|
3766
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
3767
|
+
shaka.util.Error.Category.MANIFEST,
|
|
3768
|
+
Code.HLS_MSE_ENCRYPTED_MP2T_NOT_SUPPORTED);
|
|
3769
|
+
|
|
3770
|
+
await verifyError(master, media, error, /* onCreateSegmentIndex= */ true);
|
|
3771
|
+
});
|
|
3772
|
+
|
|
3773
|
+
|
|
3746
3774
|
describe('if required tags are missing', () => {
|
|
3747
3775
|
/**
|
|
3748
3776
|
* @param {string} master
|
|
@@ -1197,13 +1197,21 @@ describe('Player', () => {
|
|
|
1197
1197
|
'com.widevine.alpha': bogusUrl,
|
|
1198
1198
|
'com.microsoft.playready': bogusUrl,
|
|
1199
1199
|
});
|
|
1200
|
-
|
|
1200
|
+
|
|
1201
|
+
// This load may be interrupted, so ignore errors and don't wait.
|
|
1202
|
+
const loadPromise =
|
|
1203
|
+
player.load('test:sintel-enc_compiled').catch(() => {});
|
|
1201
1204
|
|
|
1202
1205
|
await errorPromise;
|
|
1203
1206
|
expect(unloadPromise).not.toBeNull();
|
|
1207
|
+
|
|
1204
1208
|
if (unloadPromise) {
|
|
1205
1209
|
await unloadPromise;
|
|
1206
1210
|
}
|
|
1211
|
+
|
|
1212
|
+
// This should be done, and errors ignored. But don't leave any Promise
|
|
1213
|
+
// unresolved.
|
|
1214
|
+
await loadPromise;
|
|
1207
1215
|
});
|
|
1208
1216
|
}); // describe('unloading')
|
|
1209
1217
|
|
|
@@ -464,11 +464,11 @@ describe('Player Load Graph', () => {
|
|
|
464
464
|
|
|
465
465
|
// Make the two requests one-after-another so that we don't have any idle
|
|
466
466
|
// time between them.
|
|
467
|
-
const
|
|
468
|
-
const
|
|
467
|
+
const attach = player.attach(video);
|
|
468
|
+
const load = player.load('test:sintel');
|
|
469
469
|
|
|
470
|
-
await
|
|
471
|
-
await expectAsync(
|
|
470
|
+
await attach;
|
|
471
|
+
await expectAsync(load).toBeRejected();
|
|
472
472
|
|
|
473
473
|
// Wait a couple interrupter cycles to allow the player to enter idle
|
|
474
474
|
// state.
|
|
@@ -506,10 +506,12 @@ describe('Player Load Graph', () => {
|
|
|
506
506
|
// Normally the player would initialize media source after attaching to
|
|
507
507
|
// the media element, however since we don't support media source, it
|
|
508
508
|
// should stop at the attach state.
|
|
509
|
-
player.attach(video, /* initMediaSource= */ true);
|
|
509
|
+
const attach = player.attach(video, /* initMediaSource= */ true);
|
|
510
510
|
|
|
511
511
|
const event = await spyIsCalled(stateIdleSpy);
|
|
512
512
|
expect(event.state).toBe('attach');
|
|
513
|
+
|
|
514
|
+
await attach;
|
|
513
515
|
});
|
|
514
516
|
|
|
515
517
|
it('loading ignores media source path', async () => {
|
|
@@ -518,10 +520,12 @@ describe('Player Load Graph', () => {
|
|
|
518
520
|
// Normally the player would load content like this with the media source
|
|
519
521
|
// path, but since we don't have media source support, it should use the
|
|
520
522
|
// src= path.
|
|
521
|
-
player.load(SMALL_MP4_CONTENT_URI);
|
|
523
|
+
const load = player.load(SMALL_MP4_CONTENT_URI);
|
|
522
524
|
|
|
523
525
|
const event = await spyIsCalled(stateIdleSpy);
|
|
524
526
|
expect(event.state).toBe('src-equals');
|
|
527
|
+
|
|
528
|
+
await load;
|
|
525
529
|
});
|
|
526
530
|
|
|
527
531
|
it('unloading ignores init media source flag', async () => {
|
|
@@ -531,10 +535,12 @@ describe('Player Load Graph', () => {
|
|
|
531
535
|
// Normally the player would try to go to the media source state because
|
|
532
536
|
// we are saying to initialize media source after unloading, but since we
|
|
533
537
|
// don't have media source, it should stop at the attach state.
|
|
534
|
-
player.unload(/* initMediaSource= */ true);
|
|
538
|
+
const unload = player.unload(/* initMediaSource= */ true);
|
|
535
539
|
|
|
536
540
|
const event = await spyIsCalled(stateIdleSpy);
|
|
537
541
|
expect(event.state).toBe('attach');
|
|
542
|
+
|
|
543
|
+
await unload;
|
|
538
544
|
});
|
|
539
545
|
});
|
|
540
546
|
|
|
@@ -114,8 +114,8 @@ describe('Player Src Equals', () => {
|
|
|
114
114
|
expect(video.currentTime).toBeLessThan(2.0);
|
|
115
115
|
|
|
116
116
|
// Trigger a seek and then wait for the seek to take effect.
|
|
117
|
-
// This seek target is very close to the duration of the video.
|
|
118
|
-
video.currentTime =
|
|
117
|
+
// This seek target is very close to the duration of the video (10.01s).
|
|
118
|
+
video.currentTime = 9.5;
|
|
119
119
|
await waiter.waitForMovementOrFailOnTimeout(video, /* timeout= */10);
|
|
120
120
|
|
|
121
121
|
// Make sure the playhead is roughly where we expect it to be after
|
package/test/player_unit.js
CHANGED
|
@@ -559,15 +559,21 @@ describe('Player', () => {
|
|
|
559
559
|
});
|
|
560
560
|
|
|
561
561
|
describe('when config.streaming.preferNativeHls is set to true', () => {
|
|
562
|
-
|
|
562
|
+
beforeAll(() => {
|
|
563
563
|
shaka.media.ManifestParser.registerParserByMime(
|
|
564
564
|
'application/x-mpegurl',
|
|
565
565
|
() => new shaka.test.FakeManifestParser(manifest));
|
|
566
566
|
});
|
|
567
567
|
|
|
568
|
+
afterAll(() => {
|
|
569
|
+
// IMPORTANT: restore the ORIGINAL parser. DO NOT just unregister the
|
|
570
|
+
// fake!
|
|
571
|
+
shaka.media.ManifestParser.registerParserByMime(
|
|
572
|
+
'application/x-mpegurl',
|
|
573
|
+
() => new shaka.hls.HlsParser());
|
|
574
|
+
});
|
|
575
|
+
|
|
568
576
|
afterEach(() => {
|
|
569
|
-
shaka.media.ManifestParser.unregisterParserByMime(
|
|
570
|
-
'application/x-mpegurl');
|
|
571
577
|
video.canPlayType.calls.reset();
|
|
572
578
|
});
|
|
573
579
|
|
|
@@ -1072,6 +1072,37 @@ describe('VttTextParser', () => {
|
|
|
1072
1072
|
{periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
|
|
1073
1073
|
});
|
|
1074
1074
|
|
|
1075
|
+
it('passes text-shadow when multiple classes included', () => {
|
|
1076
|
+
verifyHelper(
|
|
1077
|
+
[
|
|
1078
|
+
{
|
|
1079
|
+
startTime: 20,
|
|
1080
|
+
endTime: 40,
|
|
1081
|
+
payload: '',
|
|
1082
|
+
nestedCues: [
|
|
1083
|
+
{
|
|
1084
|
+
startTime: 20,
|
|
1085
|
+
endTime: 40,
|
|
1086
|
+
payload: 'Test',
|
|
1087
|
+
fontStyle: Cue.fontStyle.ITALIC,
|
|
1088
|
+
textShadow: 'black 5%',
|
|
1089
|
+
},
|
|
1090
|
+
],
|
|
1091
|
+
},
|
|
1092
|
+
],
|
|
1093
|
+
'WEBVTT\n\n' +
|
|
1094
|
+
'STYLE\n' +
|
|
1095
|
+
'::cue(.shadow) {\n' +
|
|
1096
|
+
' text-shadow: black 5%;\n' +
|
|
1097
|
+
'}\n' +
|
|
1098
|
+
'::cue(.italic) {\n' +
|
|
1099
|
+
' font-style: italic;\n' +
|
|
1100
|
+
'}\n\n' +
|
|
1101
|
+
'00:00:20.000 --> 00:00:40.000\n' +
|
|
1102
|
+
'<c.shadow.italic>Test</c>',
|
|
1103
|
+
{periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
|
|
1104
|
+
});
|
|
1105
|
+
|
|
1075
1106
|
it('supports karaoke style text', () => {
|
|
1076
1107
|
verifyHelper(
|
|
1077
1108
|
[
|