shaka-player 3.1.0 → 3.1.4
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/AUTHORS +8 -2
- package/CHANGELOG.md +209 -0
- package/CONTRIBUTORS +10 -3
- package/README.md +3 -0
- package/build/apps.py +2 -2
- package/build/check.py +2 -2
- package/build/conformance.textproto +0 -9
- package/build/generateExterns.js +1 -1
- package/build/misspellings.txt +1 -0
- package/build/shakaBuildHelpers.py +6 -5
- package/build/subprocessWindowsPatch.py +103 -0
- package/demo/common/asset.js +11 -0
- package/demo/common/assets.js +1 -1
- package/demo/common/message_ids.js +5 -0
- package/demo/config.js +2 -1
- package/demo/custom.js +84 -3
- package/demo/demo.less +13 -1
- package/demo/demo_utils.js +1 -0
- package/demo/input.js +31 -12
- package/demo/input_container.js +24 -1
- package/demo/locales/en.json +6 -1
- package/demo/locales/source.json +20 -0
- package/demo/main.js +5 -1
- package/dist/controls.css +2 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +99 -91
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +99 -91
- package/dist/demo.compiled.map +3 -3
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +9 -9
- package/dist/locales.js +36 -34
- package/dist/receiver.compiled.debug.js +74 -70
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +74 -70
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +165 -9
- package/dist/shaka-player.compiled.debug.d.ts +165 -9
- package/dist/shaka-player.compiled.debug.externs.js +179 -11
- package/dist/shaka-player.compiled.debug.js +367 -339
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +179 -11
- package/dist/shaka-player.compiled.js +818 -807
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +165 -9
- package/dist/shaka-player.ui.debug.d.ts +165 -9
- package/dist/shaka-player.ui.debug.externs.js +181 -13
- package/dist/shaka-player.ui.debug.js +459 -429
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +181 -13
- package/dist/shaka-player.ui.js +973 -961
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/fairplay.md +1 -1
- package/docs/tutorials/faq.md +25 -0
- package/docs/tutorials/index.json +2 -2
- package/docs/tutorials/upgrade-v3.md +38 -0
- package/docs/tutorials/upgrade.md +3 -3
- package/externs/ima.js +4 -0
- package/externs/media_capabilities.js +16 -0
- package/externs/shaka/ads.js +2 -0
- package/externs/shaka/net.js +2 -2
- package/externs/shaka/player.js +6 -0
- package/karma.conf.js +1 -0
- package/lib/abr/simple_abr_manager.js +1 -1
- package/lib/ads/ad_manager.js +29 -11
- package/lib/ads/client_side_ad_manager.js +76 -86
- package/lib/ads/server_side_ad_manager.js +26 -11
- package/lib/cast/cast_proxy.js +3 -2
- package/lib/cast/cast_receiver.js +2 -1
- package/lib/cast/cast_sender.js +2 -2
- package/lib/cea/sei_processor.js +24 -17
- package/lib/dash/dash_parser.js +107 -4
- package/lib/dash/segment_list.js +1 -1
- package/lib/dash/segment_template.js +45 -15
- package/lib/dependencies/all.js +15 -15
- package/lib/hls/hls_parser.js +46 -18
- package/lib/media/closed_caption_parser.js +3 -1
- package/lib/media/content_workarounds.js +18 -0
- package/lib/media/drm_engine.js +20 -1
- package/lib/media/gap_jumping_controller.js +8 -4
- package/lib/media/media_source_engine.js +1 -2
- package/lib/media/playhead.js +1 -1
- package/lib/media/presentation_timeline.js +3 -1
- package/lib/media/segment_index.js +38 -12
- package/lib/media/segment_reference.js +8 -0
- package/lib/media/streaming_engine.js +30 -21
- package/lib/net/http_fetch_plugin.js +2 -2
- package/lib/net/networking_engine.js +3 -2
- package/lib/offline/storage.js +4 -0
- package/lib/player.js +113 -56
- package/lib/polyfill/encryption_scheme.js +2 -0
- package/lib/polyfill/fullscreen.js +2 -0
- package/lib/polyfill/mathround.js +2 -0
- package/lib/polyfill/media_capabilities.js +62 -23
- package/lib/polyfill/mediasource.js +8 -0
- package/lib/polyfill/orientation.js +3 -1
- package/lib/polyfill/patchedmediakeys_apple.js +6 -4
- package/lib/polyfill/patchedmediakeys_ms.js +6 -4
- package/lib/polyfill/patchedmediakeys_nop.js +2 -0
- package/lib/polyfill/patchedmediakeys_webkit.js +6 -4
- package/lib/polyfill/pip_webkit.js +2 -0
- package/lib/polyfill/storage_estimate.js +2 -0
- package/lib/polyfill/video_play_promise.js +2 -0
- package/lib/polyfill/videoplaybackquality.js +2 -0
- package/lib/polyfill/vttcue.js +2 -0
- package/lib/text/cue.js +11 -0
- package/lib/text/mp4_ttml_parser.js +3 -0
- package/lib/text/text_engine.js +14 -2
- package/lib/text/ttml_text_parser.js +52 -30
- package/lib/text/ui_text_displayer.js +255 -82
- package/lib/text/vtt_text_parser.js +4 -2
- package/lib/util/error.js +1 -4
- package/lib/util/fake_event.js +53 -7
- package/lib/util/mime_utils.js +33 -0
- package/lib/util/mp4_box_parsers.js +1 -1
- package/lib/util/mp4_parser.js +14 -0
- package/lib/util/networking.js +1 -1
- package/lib/util/periods.js +132 -37
- package/lib/util/platform.js +13 -1
- package/lib/util/stream_utils.js +46 -7
- package/package.json +3 -3
- package/test/cast/cast_proxy_unit.js +12 -6
- package/test/cast/cast_receiver_integration.js +1 -1
- package/test/cast/cast_utils_unit.js +1 -1
- package/test/cea/mp4_cea_parser_unit.js +26 -0
- package/test/dash/dash_parser_live_unit.js +1 -0
- package/test/dash/dash_parser_manifest_unit.js +187 -1
- package/test/dash/dash_parser_segment_template_unit.js +3 -3
- package/test/demo/demo_unit.js +0 -1
- package/test/hls/hls_parser_unit.js +45 -1
- package/test/media/closed_caption_parser_unit.js +20 -0
- package/test/media/drm_engine_unit.js +59 -3
- package/test/media/playhead_unit.js +27 -1
- package/test/media/presentation_timeline_unit.js +19 -0
- package/test/media/segment_index_unit.js +76 -3
- package/test/media/streaming_engine_unit.js +3 -3
- package/test/player_integration.js +38 -0
- package/test/player_unit.js +125 -6
- package/test/test/assets/3675/chunk-stream0-00001.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00002.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00003.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00004.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00005.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00006.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00007.m4s +0 -0
- package/test/test/assets/3675/dash_0.mpd +30 -0
- package/test/test/assets/3675/dash_1.mpd +30 -0
- package/test/test/assets/3675/dash_2.mpd +30 -0
- package/test/test/assets/3675/dash_3.mpd +30 -0
- package/test/test/assets/3675/dash_4.mpd +30 -0
- package/test/test/assets/3675/dash_5.mpd +26 -0
- package/test/test/assets/3675/init-stream0.m4s +0 -0
- package/test/test/assets/empty_caption_video_init.mp4 +0 -0
- package/test/test/assets/empty_caption_video_segment.mp4 +0 -0
- package/test/test/util/fake_ad_manager.js +4 -1
- package/test/test/util/simple_fakes.js +5 -3
- package/test/test/util/waiter.js +36 -2
- package/test/text/ttml_text_parser_unit.js +55 -0
- package/test/text/ui_text_displayer_unit.js +95 -18
- package/test/text/vtt_text_parser_unit.js +17 -1
- package/test/ui/localization_unit.js +15 -14
- package/test/ui/text_displayer_layout_unit.js +52 -1
- package/test/ui/ui_unit.js +4 -0
- package/test/util/mp4_box_parsers_unit.js +28 -0
- package/test/util/periods_unit.js +190 -2
- package/test/util/stream_utils_unit.js +56 -5
- package/ui/airplay_button.js +5 -0
- package/ui/big_play_button.js +10 -0
- package/ui/cast_button.js +2 -3
- package/ui/controls.js +9 -7
- package/ui/less/containers.less +10 -5
- package/ui/locales/en.json +1 -0
- package/ui/locales/ru.json +6 -6
- package/ui/locales/source.json +4 -0
- package/ui/localization.js +28 -51
- package/ui/pip_button.js +2 -3
- package/ui/play_button.js +10 -10
- package/ui/small_play_button.js +12 -0
- package/ui/ui.js +1 -1
- package/docs/tutorials/upgrade-v2-4.md +0 -481
|
@@ -12,10 +12,12 @@ goog.require('shaka.polyfill');
|
|
|
12
12
|
/**
|
|
13
13
|
* @summary A polyfill to provide PiP support in Safari.
|
|
14
14
|
* Note that Safari only supports PiP on video elements, not audio.
|
|
15
|
+
* @export
|
|
15
16
|
*/
|
|
16
17
|
shaka.polyfill.PiPWebkit = class {
|
|
17
18
|
/**
|
|
18
19
|
* Install the polyfill if needed.
|
|
20
|
+
* @export
|
|
19
21
|
*/
|
|
20
22
|
static install() {
|
|
21
23
|
if (!window.HTMLVideoElement) {
|
|
@@ -13,10 +13,12 @@ goog.require('shaka.polyfill');
|
|
|
13
13
|
* @summary A polyfill to provide navigator.storage.estimate in old
|
|
14
14
|
* webkit browsers.
|
|
15
15
|
* See: https://developers.google.com/web/updates/2017/08/estimating-available-storage-space#the-present
|
|
16
|
+
* @export
|
|
16
17
|
*/
|
|
17
18
|
shaka.polyfill.StorageEstimate = class {
|
|
18
19
|
/**
|
|
19
20
|
* Install the polyfill if needed.
|
|
21
|
+
* @export
|
|
20
22
|
*/
|
|
21
23
|
static install() {
|
|
22
24
|
if (navigator.storage && navigator.storage.estimate) {
|
|
@@ -12,10 +12,12 @@ goog.require('shaka.polyfill');
|
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* @summary A polyfill to silence the play() Promise in HTML5 video.
|
|
15
|
+
* @export
|
|
15
16
|
*/
|
|
16
17
|
shaka.polyfill.VideoPlayPromise = class {
|
|
17
18
|
/**
|
|
18
19
|
* Install the polyfill if needed.
|
|
20
|
+
* @export
|
|
19
21
|
*/
|
|
20
22
|
static install() {
|
|
21
23
|
shaka.log.debug('VideoPlayPromise.install');
|
|
@@ -13,10 +13,12 @@ goog.require('shaka.polyfill');
|
|
|
13
13
|
* @summary A polyfill to provide MSE VideoPlaybackQuality metrics.
|
|
14
14
|
* Many browsers do not yet provide this API, and Chrome currently provides
|
|
15
15
|
* similar data through individual prefixed attributes on HTMLVideoElement.
|
|
16
|
+
* @export
|
|
16
17
|
*/
|
|
17
18
|
shaka.polyfill.VideoPlaybackQuality = class {
|
|
18
19
|
/**
|
|
19
20
|
* Install the polyfill if needed.
|
|
21
|
+
* @export
|
|
20
22
|
*/
|
|
21
23
|
static install() {
|
|
22
24
|
if (!window.HTMLVideoElement) {
|
package/lib/polyfill/vttcue.js
CHANGED
|
@@ -12,10 +12,12 @@ goog.require('shaka.polyfill');
|
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* @summary A polyfill to provide VTTCue.
|
|
15
|
+
* @export
|
|
15
16
|
*/
|
|
16
17
|
shaka.polyfill.VTTCue = class {
|
|
17
18
|
/**
|
|
18
19
|
* Install the polyfill if needed.
|
|
20
|
+
* @export
|
|
19
21
|
*/
|
|
20
22
|
static install() {
|
|
21
23
|
if (window.VTTCue) {
|
package/lib/text/cue.js
CHANGED
|
@@ -232,6 +232,17 @@ shaka.text.Cue = class {
|
|
|
232
232
|
};
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
+
/**
|
|
236
|
+
* @param {number} start
|
|
237
|
+
* @param {number} end
|
|
238
|
+
* @return {!shaka.text.Cue}
|
|
239
|
+
*/
|
|
240
|
+
static lineBreak(start, end) {
|
|
241
|
+
const cue = new shaka.text.Cue(start, end, '');
|
|
242
|
+
cue.lineBreak = true;
|
|
243
|
+
return cue;
|
|
244
|
+
}
|
|
245
|
+
|
|
235
246
|
/**
|
|
236
247
|
* Create a copy of the cue with the same properties.
|
|
237
248
|
* @return {!shaka.text.Cue}
|
|
@@ -88,6 +88,9 @@ shaka.text.Mp4TtmlParser = class {
|
|
|
88
88
|
|
|
89
89
|
shaka.text.TextEngine.registerParser(
|
|
90
90
|
'application/mp4; codecs="stpp"', () => new shaka.text.Mp4TtmlParser());
|
|
91
|
+
shaka.text.TextEngine.registerParser(
|
|
92
|
+
'application/mp4; codecs="stpp.ttml"',
|
|
93
|
+
() => new shaka.text.Mp4TtmlParser());
|
|
91
94
|
shaka.text.TextEngine.registerParser(
|
|
92
95
|
'application/mp4; codecs="stpp.ttml.im1t"',
|
|
93
96
|
() => new shaka.text.Mp4TtmlParser());
|
package/lib/text/text_engine.js
CHANGED
|
@@ -345,6 +345,19 @@ shaka.text.TextEngine = class {
|
|
|
345
345
|
return cues;
|
|
346
346
|
}
|
|
347
347
|
|
|
348
|
+
/**
|
|
349
|
+
* @param {!shaka.text.Cue} cue the cue to apply the timestamp to recursively
|
|
350
|
+
* @param {number} videoTimestampOffset the timestamp offset of the video
|
|
351
|
+
* @private
|
|
352
|
+
*/
|
|
353
|
+
applyVideoTimestampOffsetRecursive_(cue, videoTimestampOffset) {
|
|
354
|
+
cue.startTime += videoTimestampOffset;
|
|
355
|
+
cue.endTime += videoTimestampOffset;
|
|
356
|
+
for (const nested of cue.nestedCues) {
|
|
357
|
+
this.applyVideoTimestampOffsetRecursive_(nested, videoTimestampOffset);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
348
361
|
/**
|
|
349
362
|
* Store the closed captions in the text engine, and append the cues to the
|
|
350
363
|
* text displayer. This is a side-channel used for embedded text only.
|
|
@@ -373,8 +386,7 @@ shaka.text.TextEngine = class {
|
|
|
373
386
|
|
|
374
387
|
// Adjust CEA captions with respect to the timestamp offset of the video
|
|
375
388
|
// stream in which they were embedded.
|
|
376
|
-
cue
|
|
377
|
-
cue.endTime += videoTimestampOffset;
|
|
389
|
+
this.applyVideoTimestampOffsetRecursive_(cue, videoTimestampOffset);
|
|
378
390
|
|
|
379
391
|
const keepThisCue =
|
|
380
392
|
cue.startTime >= this.appendWindowStart_ &&
|
|
@@ -199,6 +199,11 @@ shaka.text.TtmlTextParser = class {
|
|
|
199
199
|
/** @type {Element} */
|
|
200
200
|
let parentElement = /** @type {Element} */(cueNode.parentNode);
|
|
201
201
|
|
|
202
|
+
if (cueNode.nodeType == Node.COMMENT_NODE) {
|
|
203
|
+
// The comments do not contain information that interests us here.
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
|
|
202
207
|
if (cueNode.nodeType == Node.TEXT_NODE) {
|
|
203
208
|
// This should generate an "anonymous span" according to the TTML spec.
|
|
204
209
|
// So pretend the element was a <span>. parentElement was set above, so
|
|
@@ -219,6 +224,36 @@ shaka.text.TtmlTextParser = class {
|
|
|
219
224
|
|
|
220
225
|
const localWhitespaceTrim = spaceStyle == 'default';
|
|
221
226
|
|
|
227
|
+
// Parse any nested cues first.
|
|
228
|
+
const isTextNode = (node) => {
|
|
229
|
+
return node.nodeType == Node.TEXT_NODE;
|
|
230
|
+
};
|
|
231
|
+
const isLeafNode = Array.from(cueElement.childNodes).every(isTextNode);
|
|
232
|
+
const nestedCues = [];
|
|
233
|
+
if (!isLeafNode) {
|
|
234
|
+
// Otherwise, recurse into the children. Text nodes will convert into
|
|
235
|
+
// anonymous spans, which will then be leaf nodes.
|
|
236
|
+
for (const childNode of cueElement.childNodes) {
|
|
237
|
+
const nestedCue = shaka.text.TtmlTextParser.parseCue_(
|
|
238
|
+
childNode,
|
|
239
|
+
offset,
|
|
240
|
+
rateInfo,
|
|
241
|
+
metadataElements,
|
|
242
|
+
styles,
|
|
243
|
+
regionElements,
|
|
244
|
+
cueRegions,
|
|
245
|
+
localWhitespaceTrim,
|
|
246
|
+
/* isNested= */ true,
|
|
247
|
+
cellResolution,
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
// This node may or may not generate a nested cue.
|
|
251
|
+
if (nestedCue) {
|
|
252
|
+
nestedCues.push(nestedCue);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
222
257
|
// In this regex, "\S" means "non-whitespace character".
|
|
223
258
|
const hasTextContent = /\S/.test(cueElement.textContent);
|
|
224
259
|
const hasTimeAttributes =
|
|
@@ -226,7 +261,8 @@ shaka.text.TtmlTextParser = class {
|
|
|
226
261
|
cueElement.hasAttribute('end') ||
|
|
227
262
|
cueElement.hasAttribute('dur');
|
|
228
263
|
|
|
229
|
-
if (!hasTimeAttributes && !hasTextContent && cueElement.tagName != 'br'
|
|
264
|
+
if (!hasTimeAttributes && !hasTextContent && cueElement.tagName != 'br' &&
|
|
265
|
+
nestedCues.length == 0) {
|
|
230
266
|
if (!isNested) {
|
|
231
267
|
// Disregards empty <p> elements without time attributes nor content.
|
|
232
268
|
// <p begin="..." smpte:backgroundImage="..." /> will go through,
|
|
@@ -263,6 +299,20 @@ shaka.text.TtmlTextParser = class {
|
|
|
263
299
|
end += offset;
|
|
264
300
|
}
|
|
265
301
|
|
|
302
|
+
if (!hasTimeAttributes && nestedCues.length > 0) {
|
|
303
|
+
// If no time is defined for this cue, base the timing information on
|
|
304
|
+
// the time of the nested cues. In the case of multiple nested cues with
|
|
305
|
+
// different start times, it is the text displayer's responsibility to
|
|
306
|
+
// make sure that only the appropriate nested cue is drawn at any given
|
|
307
|
+
// time.
|
|
308
|
+
start = Infinity;
|
|
309
|
+
end = 0;
|
|
310
|
+
for (const cue of nestedCues) {
|
|
311
|
+
start = Math.min(start, cue.startTime);
|
|
312
|
+
end = Math.max(end, cue.endTime);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
266
316
|
if (cueElement.tagName == 'br') {
|
|
267
317
|
const cue = new shaka.text.Cue(start, end, '');
|
|
268
318
|
cue.lineBreak = true;
|
|
@@ -270,13 +320,7 @@ shaka.text.TtmlTextParser = class {
|
|
|
270
320
|
}
|
|
271
321
|
|
|
272
322
|
let payload = '';
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
const isTextNode = (node) => {
|
|
276
|
-
return node.nodeType == Node.TEXT_NODE;
|
|
277
|
-
};
|
|
278
|
-
|
|
279
|
-
if (Array.from(cueElement.childNodes).every(isTextNode)) {
|
|
323
|
+
if (isLeafNode) {
|
|
280
324
|
// If the childNodes are all text, this is a leaf node. Get the payload.
|
|
281
325
|
payload = cueElement.textContent;
|
|
282
326
|
if (localWhitespaceTrim) {
|
|
@@ -285,28 +329,6 @@ shaka.text.TtmlTextParser = class {
|
|
|
285
329
|
// Collapse multiple spaces into one.
|
|
286
330
|
payload = payload.replace(/\s+/g, ' ');
|
|
287
331
|
}
|
|
288
|
-
} else {
|
|
289
|
-
// Otherwise, recurse into the children. Text nodes will convert into
|
|
290
|
-
// anonymous spans, which will then be leaf nodes.
|
|
291
|
-
for (const childNode of cueElement.childNodes) {
|
|
292
|
-
const nestedCue = shaka.text.TtmlTextParser.parseCue_(
|
|
293
|
-
childNode,
|
|
294
|
-
offset,
|
|
295
|
-
rateInfo,
|
|
296
|
-
metadataElements,
|
|
297
|
-
styles,
|
|
298
|
-
regionElements,
|
|
299
|
-
cueRegions,
|
|
300
|
-
localWhitespaceTrim,
|
|
301
|
-
/* isNested= */ true,
|
|
302
|
-
cellResolution,
|
|
303
|
-
);
|
|
304
|
-
|
|
305
|
-
// This node may or may not generate a nested cue.
|
|
306
|
-
if (nestedCue) {
|
|
307
|
-
nestedCues.push(nestedCue);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
332
|
}
|
|
311
333
|
|
|
312
334
|
const cue = new shaka.text.Cue(start, end, payload);
|