shaka-player 4.10.2 → 4.10.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/dist/deps.js +5 -4
- package/dist/locales.js +36 -36
- package/dist/shaka-player.compiled.debug.externs.js +83 -83
- package/dist/shaka-player.compiled.debug.js +399 -396
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +83 -83
- package/dist/shaka-player.compiled.js +1100 -1097
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.debug.externs.js +83 -83
- package/dist/shaka-player.ui.debug.js +410 -407
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +83 -83
- package/dist/shaka-player.ui.js +1219 -1217
- package/dist/shaka-player.ui.map +4 -4
- package/lib/ads/interstitial_ad_manager.js +5 -4
- package/lib/hls/hls_parser.js +24 -14
- package/lib/media/media_source_engine.js +40 -1
- package/lib/media/playhead.js +15 -6
- package/lib/media/segment_utils.js +48 -10
- package/lib/media/streaming_engine.js +12 -62
- package/lib/player.js +12 -8
- package/lib/text/cue.js +1 -117
- package/lib/text/cue_region.js +123 -0
- package/lib/text/ui_text_displayer.js +20 -3
- package/lib/util/mp4_box_parsers.js +42 -0
- package/lib/util/platform.js +35 -16
- package/lib/util/stream_utils.js +4 -2
- package/package.json +1 -1
- package/ui/seek_bar.js +5 -6
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
goog.provide('shaka.text.CueRegion');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @export
|
|
12
|
+
*/
|
|
13
|
+
shaka.text.CueRegion = class {
|
|
14
|
+
/** */
|
|
15
|
+
constructor() {
|
|
16
|
+
const CueRegion = shaka.text.CueRegion;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Region identifier.
|
|
20
|
+
* @type {string}
|
|
21
|
+
* @export
|
|
22
|
+
*/
|
|
23
|
+
this.id = '';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The X offset to start the rendering area in viewportAnchorUnits of the
|
|
27
|
+
* video width.
|
|
28
|
+
* @type {number}
|
|
29
|
+
* @export
|
|
30
|
+
*/
|
|
31
|
+
this.viewportAnchorX = 0;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The X offset to start the rendering area in viewportAnchorUnits of the
|
|
35
|
+
* video height.
|
|
36
|
+
* @type {number}
|
|
37
|
+
* @export
|
|
38
|
+
*/
|
|
39
|
+
this.viewportAnchorY = 0;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The X offset to start the rendering area in percentage (0-100) of this
|
|
43
|
+
* region width.
|
|
44
|
+
* @type {number}
|
|
45
|
+
* @export
|
|
46
|
+
*/
|
|
47
|
+
this.regionAnchorX = 0;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The Y offset to start the rendering area in percentage (0-100) of the
|
|
51
|
+
* region height.
|
|
52
|
+
* @type {number}
|
|
53
|
+
* @export
|
|
54
|
+
*/
|
|
55
|
+
this.regionAnchorY = 0;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The width of the rendering area in widthUnits.
|
|
59
|
+
* @type {number}
|
|
60
|
+
* @export
|
|
61
|
+
*/
|
|
62
|
+
this.width = 100;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The width of the rendering area in heightUnits.
|
|
66
|
+
* @type {number}
|
|
67
|
+
* @export
|
|
68
|
+
*/
|
|
69
|
+
this.height = 100;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The units (percentage, pixels or lines) the region height is in.
|
|
73
|
+
* @type {shaka.text.CueRegion.units}
|
|
74
|
+
* @export
|
|
75
|
+
*/
|
|
76
|
+
this.heightUnits = CueRegion.units.PERCENTAGE;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The units (percentage or pixels) the region width is in.
|
|
80
|
+
* @type {shaka.text.CueRegion.units}
|
|
81
|
+
* @export
|
|
82
|
+
*/
|
|
83
|
+
this.widthUnits = CueRegion.units.PERCENTAGE;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The units (percentage or pixels) the region viewportAnchors are in.
|
|
87
|
+
* @type {shaka.text.CueRegion.units}
|
|
88
|
+
* @export
|
|
89
|
+
*/
|
|
90
|
+
this.viewportAnchorUnits = CueRegion.units.PERCENTAGE;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* If scroll=UP, it means that cues in the region will be added to the
|
|
94
|
+
* bottom of the region and will push any already displayed cues in the
|
|
95
|
+
* region up. Otherwise (scroll=NONE) cues will stay fixed at the location
|
|
96
|
+
* they were first painted in.
|
|
97
|
+
* @type {shaka.text.CueRegion.scrollMode}
|
|
98
|
+
* @export
|
|
99
|
+
*/
|
|
100
|
+
this.scroll = CueRegion.scrollMode.NONE;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @enum {number}
|
|
107
|
+
* @export
|
|
108
|
+
*/
|
|
109
|
+
shaka.text.CueRegion.units = {
|
|
110
|
+
'PX': 0,
|
|
111
|
+
'PERCENTAGE': 1,
|
|
112
|
+
'LINES': 2,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @enum {string}
|
|
118
|
+
* @export
|
|
119
|
+
*/
|
|
120
|
+
shaka.text.CueRegion.scrollMode = {
|
|
121
|
+
'NONE': '',
|
|
122
|
+
'UP': 'up',
|
|
123
|
+
};
|
|
@@ -468,7 +468,9 @@ shaka.text.UITextDisplayer = class {
|
|
|
468
468
|
|
|
469
469
|
const regionElement = shaka.util.Dom.createHTMLElement('span');
|
|
470
470
|
|
|
471
|
+
const linesUnit = shaka.text.CueRegion.units.LINES;
|
|
471
472
|
const percentageUnit = shaka.text.CueRegion.units.PERCENTAGE;
|
|
473
|
+
const pixelUnit = shaka.text.CueRegion.units.PX;
|
|
472
474
|
const heightUnit = region.heightUnits == percentageUnit ? '%' : 'px';
|
|
473
475
|
const widthUnit = region.widthUnits == percentageUnit ? '%' : 'px';
|
|
474
476
|
const viewportAnchorUnit =
|
|
@@ -479,12 +481,14 @@ shaka.text.UITextDisplayer = class {
|
|
|
479
481
|
|
|
480
482
|
regionElement.style.position = 'absolute';
|
|
481
483
|
|
|
482
|
-
|
|
483
|
-
if (region.heightUnits === linesUnit && region.widthUnits === linesUnit) {
|
|
484
|
+
if (region.heightUnits === linesUnit) {
|
|
484
485
|
regionElement.style.height = region.height * lineHeightMultiple + '%';
|
|
485
|
-
regionElement.style.width = region.width * lineWidthMultiple + '%';
|
|
486
486
|
} else {
|
|
487
487
|
regionElement.style.height = region.height + heightUnit;
|
|
488
|
+
}
|
|
489
|
+
if (region.widthUnits === linesUnit) {
|
|
490
|
+
regionElement.style.width = region.width * lineWidthMultiple + '%';
|
|
491
|
+
} else {
|
|
488
492
|
regionElement.style.width = region.width + widthUnit;
|
|
489
493
|
}
|
|
490
494
|
|
|
@@ -504,6 +508,19 @@ shaka.text.UITextDisplayer = class {
|
|
|
504
508
|
regionElement.style.left = region.viewportAnchorX -
|
|
505
509
|
region.regionAnchorX * region.width / 100 + viewportAnchorUnit;
|
|
506
510
|
}
|
|
511
|
+
if (region.heightUnits !== pixelUnit &&
|
|
512
|
+
region.widthUnits !== pixelUnit &&
|
|
513
|
+
region.viewportAnchorUnits !== pixelUnit) {
|
|
514
|
+
// Clip region
|
|
515
|
+
const top = parseInt(regionElement.style.top.slice(0, -1), 10) || 0;
|
|
516
|
+
const left = parseInt(regionElement.style.left.slice(0, -1), 10) || 0;
|
|
517
|
+
const height = parseInt(regionElement.style.height.slice(0, -1), 10) || 0;
|
|
518
|
+
const width = parseInt(regionElement.style.width.slice(0, -1), 10) || 0;
|
|
519
|
+
const realTop = Math.max(0, Math.min(100 - height, top));
|
|
520
|
+
const realLeft = Math.max(0, Math.min(100 - width, left));
|
|
521
|
+
regionElement.style.top = realTop + '%';
|
|
522
|
+
regionElement.style.left = realLeft + '%';
|
|
523
|
+
}
|
|
507
524
|
|
|
508
525
|
regionElement.style.display = 'flex';
|
|
509
526
|
regionElement.style.flexDirection = 'column';
|
|
@@ -274,6 +274,35 @@ shaka.util.Mp4BoxParsers = class {
|
|
|
274
274
|
};
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Parses an visual sample entry box.
|
|
280
|
+
* @param {!shaka.util.DataViewReader} reader
|
|
281
|
+
* @return {!shaka.util.ParsedVisualSampleEntryBox}
|
|
282
|
+
*/
|
|
283
|
+
static visualSampleEntry(reader) {
|
|
284
|
+
// Skip 6 reserved bytes.
|
|
285
|
+
// Skip 2-byte data reference index.
|
|
286
|
+
// Skip 16 more reserved bytes.
|
|
287
|
+
reader.skip(24);
|
|
288
|
+
// 4 bytes for width/height.
|
|
289
|
+
const width = reader.readUint16();
|
|
290
|
+
const height = reader.readUint16();
|
|
291
|
+
// Skip 8 bytes for horizontal/vertical resolution.
|
|
292
|
+
// Skip 4 more reserved bytes (0)
|
|
293
|
+
// Skip 2-byte frame count.
|
|
294
|
+
// Skip 32-byte compressor name (length byte, then name, then 0-padding).
|
|
295
|
+
// Skip 2-byte depth.
|
|
296
|
+
// Skip 2 more reserved bytes (0xff)
|
|
297
|
+
reader.skip(50);
|
|
298
|
+
|
|
299
|
+
return {
|
|
300
|
+
width: width,
|
|
301
|
+
height: height,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
|
|
277
306
|
/**
|
|
278
307
|
* Parses an audio sample entry box.
|
|
279
308
|
* @param {!shaka.util.DataViewReader} reader
|
|
@@ -866,6 +895,19 @@ shaka.util.ParsedFRMABox;
|
|
|
866
895
|
*/
|
|
867
896
|
shaka.util.ParsedTENCBox;
|
|
868
897
|
|
|
898
|
+
/**
|
|
899
|
+
* @typedef {{
|
|
900
|
+
* width: number,
|
|
901
|
+
* height: number
|
|
902
|
+
* }}
|
|
903
|
+
*
|
|
904
|
+
* @property {number} width
|
|
905
|
+
* @property {number} height
|
|
906
|
+
*
|
|
907
|
+
* @exportDoc
|
|
908
|
+
*/
|
|
909
|
+
shaka.util.ParsedVisualSampleEntryBox;
|
|
910
|
+
|
|
869
911
|
/**
|
|
870
912
|
* @typedef {{
|
|
871
913
|
* channelCount: number,
|
package/lib/util/platform.js
CHANGED
|
@@ -645,6 +645,25 @@ shaka.util.Platform = class {
|
|
|
645
645
|
return true;
|
|
646
646
|
}
|
|
647
647
|
|
|
648
|
+
/**
|
|
649
|
+
* On some platforms, such as v1 Chromecasts, the act of seeking can take a
|
|
650
|
+
* significant amount of time.
|
|
651
|
+
*
|
|
652
|
+
* @return {boolean}
|
|
653
|
+
*/
|
|
654
|
+
static isSeekingSlow() {
|
|
655
|
+
const Platform = shaka.util.Platform;
|
|
656
|
+
if (Platform.isChromecast()) {
|
|
657
|
+
if (Platform.isAndroidCastDevice()) {
|
|
658
|
+
// Android-based Chromecasts are new enough to not be a problem.
|
|
659
|
+
return false;
|
|
660
|
+
} else {
|
|
661
|
+
return true;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
return false;
|
|
665
|
+
}
|
|
666
|
+
|
|
648
667
|
/**
|
|
649
668
|
* Returns true if MediaKeys is polyfilled
|
|
650
669
|
*
|
|
@@ -727,15 +746,17 @@ shaka.util.Platform = class {
|
|
|
727
746
|
'screen size 1920x1080.');
|
|
728
747
|
}
|
|
729
748
|
} else if (Platform.isXboxOne()) {
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
const protectionResult =
|
|
733
|
-
Windows.Media.Protection.ProtectionCapabilityResult;
|
|
734
|
-
// isTypeSupported may return "maybe", which means the operation is not
|
|
735
|
-
// completed. This means we need to retry
|
|
736
|
-
// https://learn.microsoft.com/en-us/uwp/api/windows.media.protection.protectioncapabilityresult?view=winrt-22621
|
|
737
|
-
let result = null;
|
|
749
|
+
maxResolution.width = 1920;
|
|
750
|
+
maxResolution.height = 1080;
|
|
738
751
|
try {
|
|
752
|
+
const protectionCapabilities =
|
|
753
|
+
new Windows.Media.Protection.ProtectionCapabilities();
|
|
754
|
+
const protectionResult =
|
|
755
|
+
Windows.Media.Protection.ProtectionCapabilityResult;
|
|
756
|
+
// isTypeSupported may return "maybe", which means the operation is not
|
|
757
|
+
// completed. This means we need to retry
|
|
758
|
+
// https://learn.microsoft.com/en-us/uwp/api/windows.media.protection.protectioncapabilityresult?view=winrt-22621
|
|
759
|
+
let result = null;
|
|
739
760
|
const type =
|
|
740
761
|
'video/mp4;codecs="hvc1,mp4a";features="decode-res-x=3840,' +
|
|
741
762
|
'decode-res-y=2160,decode-bitrate=20000,decode-fps=30,' +
|
|
@@ -745,15 +766,13 @@ shaka.util.Platform = class {
|
|
|
745
766
|
do {
|
|
746
767
|
result = protectionCapabilities.isTypeSupported(type, keySystem);
|
|
747
768
|
} while (result === protectionResult.maybe);
|
|
769
|
+
if (result === protectionResult.probably) {
|
|
770
|
+
maxResolution.width = 3840;
|
|
771
|
+
maxResolution.height = 2160;
|
|
772
|
+
}
|
|
748
773
|
} catch (e) {
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
if (result === protectionResult.probably) {
|
|
752
|
-
maxResolution.width = 3840;
|
|
753
|
-
maxResolution.height = 2160;
|
|
754
|
-
} else {
|
|
755
|
-
maxResolution.width = 1920;
|
|
756
|
-
maxResolution.height = 1080;
|
|
774
|
+
shaka.log.alwaysWarn('Xbox: Error detecting screen size, default ' +
|
|
775
|
+
'screen size 1920x1080.');
|
|
757
776
|
}
|
|
758
777
|
} else if (Platform.isWebOS()) {
|
|
759
778
|
try {
|
package/lib/util/stream_utils.js
CHANGED
|
@@ -108,7 +108,8 @@ shaka.util.StreamUtils = class {
|
|
|
108
108
|
const currentCodec =
|
|
109
109
|
MimeUtils.getNormalizedCodec(stream.codecs);
|
|
110
110
|
if (previousCodec == currentCodec) {
|
|
111
|
-
if (stream.bandwidth
|
|
111
|
+
if (!stream.bandwidth || !previousStream.bandwidth ||
|
|
112
|
+
stream.bandwidth > previousStream.bandwidth) {
|
|
112
113
|
validAudioStreams.push(stream);
|
|
113
114
|
validAudioIds.push(stream.id);
|
|
114
115
|
}
|
|
@@ -162,7 +163,8 @@ shaka.util.StreamUtils = class {
|
|
|
162
163
|
const currentCodec =
|
|
163
164
|
MimeUtils.getNormalizedCodec(stream.codecs);
|
|
164
165
|
if (previousCodec == currentCodec) {
|
|
165
|
-
if (stream.bandwidth
|
|
166
|
+
if (!stream.bandwidth || !previousStream.bandwidth ||
|
|
167
|
+
stream.bandwidth > previousStream.bandwidth) {
|
|
166
168
|
validVideoStreams.push(stream);
|
|
167
169
|
validVideoIds.push(stream.id);
|
|
168
170
|
}
|
package/package.json
CHANGED
package/ui/seek_bar.js
CHANGED
|
@@ -396,15 +396,14 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement {
|
|
|
396
396
|
// Post-roll ads are marked as starting at -1 in CS IMA ads.
|
|
397
397
|
if (point.start == -1 && !point.end) {
|
|
398
398
|
postRollAd = true;
|
|
399
|
+
continue;
|
|
399
400
|
}
|
|
400
401
|
// Filter point within the seek range. For points with no endpoint
|
|
401
402
|
// (client side ads) check that the start point is within range.
|
|
402
|
-
if (point.
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
const startDist = point.start - seekRange.start;
|
|
403
|
+
if ((!point.end && point.start >= seekRange.start) ||
|
|
404
|
+
(typeof point.end == 'number' && point.end > seekRange.start)) {
|
|
405
|
+
const startDist =
|
|
406
|
+
Math.max(point.start, seekRange.start) - seekRange.start;
|
|
408
407
|
const startFrac = (startDist / seekRangeSize) || 0;
|
|
409
408
|
// For points with no endpoint assume a 1% length: not too much,
|
|
410
409
|
// but enough to be visible on the timeline.
|