shaka-player 3.3.0 → 3.3.1
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/CHANGELOG.md +54 -0
- package/build/conformance.textproto +183 -169
- package/dist/controls.css +1 -1
- package/dist/deps.js +1 -1
- package/dist/locales.js +30 -30
- package/dist/shaka-player.compiled.d.ts +25 -2
- package/dist/shaka-player.compiled.debug.d.ts +25 -2
- package/dist/shaka-player.compiled.debug.externs.js +22 -1
- package/dist/shaka-player.compiled.debug.js +226 -222
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.externs.js +22 -1
- package/dist/shaka-player.compiled.js +814 -812
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +25 -2
- package/dist/shaka-player.ui.debug.d.ts +25 -2
- package/dist/shaka-player.ui.debug.externs.js +22 -1
- package/dist/shaka-player.ui.debug.js +244 -240
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.externs.js +22 -1
- package/dist/shaka-player.ui.js +995 -992
- package/dist/shaka-player.ui.map +4 -4
- package/externs/cmcd.js +186 -0
- package/externs/shaka/player.js +8 -0
- package/externs/shaka/text.js +10 -0
- package/lib/hls/hls_parser.js +30 -0
- package/lib/media/segment_index.js +2 -1
- package/lib/media/segment_reference.js +19 -1
- package/lib/media/streaming_engine.js +5 -2
- package/lib/player.js +23 -17
- package/lib/polyfill/media_capabilities.js +30 -15
- package/lib/text/cue.js +6 -0
- package/lib/text/ttml_text_parser.js +84 -58
- package/lib/text/ui_text_displayer.js +17 -11
- package/lib/util/cmcd_manager.js +47 -201
- package/lib/util/stream_utils.js +86 -10
- package/lib/util/xml_utils.js +19 -0
- package/package.json +2 -2
- package/test/media/drm_engine_unit.js +3 -3
- package/test/media/streaming_engine_integration.js +2 -1
- package/test/media/streaming_engine_unit.js +145 -0
- package/test/player_integration.js +41 -8
- package/test/player_src_equals_integration.js +41 -8
- package/test/player_unit.js +19 -9
- package/test/test/assets/chapters.vtt +2 -2
- package/test/test/assets/chapters2.vtt +10 -0
- package/test/test/util/ttml_utils.js +81 -0
- package/test/text/mp4_ttml_parser_unit.js +11 -18
- package/test/text/ttml_text_parser_unit.js +499 -230
- package/test/util/cmcd_manager_unit.js +29 -15
- package/test/util/stream_utils_unit.js +36 -30
- package/third_party/closure-uri/uri.js +21 -0
- package/ui/text_selection.js +1 -0
- package/externs/media_capabilities.js +0 -16
package/externs/cmcd.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @fileoverview Externs for CMCD data.
|
|
9
|
+
* @see https://github.com/google/shaka-player/issues/3619
|
|
10
|
+
* @see https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf
|
|
11
|
+
*
|
|
12
|
+
* @externs
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {{
|
|
17
|
+
* br: (number|undefined),
|
|
18
|
+
* d: (number|undefined),
|
|
19
|
+
* ot: (string|undefined),
|
|
20
|
+
* tb: (number|undefined),
|
|
21
|
+
* bl: (number|undefined),
|
|
22
|
+
* dl: (number|undefined),
|
|
23
|
+
* mtp: (number|undefined),
|
|
24
|
+
* nor: (string|undefined),
|
|
25
|
+
* nrr: (string|undefined),
|
|
26
|
+
* su: (boolean|undefined),
|
|
27
|
+
* cid: (string|undefined),
|
|
28
|
+
* pr: (number|undefined),
|
|
29
|
+
* sf: (string|undefined),
|
|
30
|
+
* sid: (string|undefined),
|
|
31
|
+
* st: (string|undefined),
|
|
32
|
+
* v: (number|undefined),
|
|
33
|
+
* bs: (boolean|undefined),
|
|
34
|
+
* rtp: (number|undefined)
|
|
35
|
+
* }}
|
|
36
|
+
*
|
|
37
|
+
* @description
|
|
38
|
+
* Client Media Common Data (CMCD) data.
|
|
39
|
+
*
|
|
40
|
+
* @property {number} br
|
|
41
|
+
* The encoded bitrate of the audio or video object being requested. This may
|
|
42
|
+
* not be known precisely by the player; however, it MAY be estimated based
|
|
43
|
+
* upon playlist/manifest declarations. If the playlist declares both peak and
|
|
44
|
+
* average bitrate values, the peak value should be transmitted.
|
|
45
|
+
*
|
|
46
|
+
* @property {number} d
|
|
47
|
+
* The playback duration in milliseconds of the object being requested. If a
|
|
48
|
+
* partial segment is being requested, then this value MUST indicate the
|
|
49
|
+
* playback duration of that part and not that of its parent segment. This
|
|
50
|
+
* value can be an approximation of the estimated duration if the explicit
|
|
51
|
+
* value is not known.
|
|
52
|
+
*
|
|
53
|
+
* @property {string} ot
|
|
54
|
+
* The media type of the current object being requested:
|
|
55
|
+
* - `m` = text file, such as a manifest or playlist
|
|
56
|
+
* - `a` = audio only
|
|
57
|
+
* - `v` = video only
|
|
58
|
+
* - `av` = muxed audio and video
|
|
59
|
+
* - `i` = init segment
|
|
60
|
+
* - `c` = caption or subtitle
|
|
61
|
+
* - `tt` = ISOBMFF timed text track
|
|
62
|
+
* - `k` = cryptographic key, license or certificate.
|
|
63
|
+
* - `o` = other
|
|
64
|
+
*
|
|
65
|
+
* If the object type being requested is unknown, then this key MUST NOT be
|
|
66
|
+
* used.
|
|
67
|
+
*
|
|
68
|
+
* @property {number} tb
|
|
69
|
+
* The highest bitrate rendition in the manifest or playlist that the client
|
|
70
|
+
* is allowed to play, given current codec, licensing and sizing constraints.
|
|
71
|
+
*
|
|
72
|
+
* @property {number} bl
|
|
73
|
+
* The buffer length associated with the media object being requested. This
|
|
74
|
+
* value MUST be rounded to the nearest 100 ms. This key SHOULD only be sent
|
|
75
|
+
* with an object type of ‘a’, ‘v’ or ‘av’.
|
|
76
|
+
*
|
|
77
|
+
* @property {number} dl
|
|
78
|
+
* Deadline from the request time until the first sample of this
|
|
79
|
+
* Segment/Object needs to be available in order to not create a buffer
|
|
80
|
+
* underrun or any other playback problems. This value MUST be rounded to the
|
|
81
|
+
* nearest 100ms. For a playback rate of 1, this may be equivalent to the
|
|
82
|
+
* player’s remaining buffer length.
|
|
83
|
+
*
|
|
84
|
+
* @property {number} mtp
|
|
85
|
+
* The throughput between client and server, as measured by the client and
|
|
86
|
+
* MUST be rounded to the nearest 100 kbps. This value, however derived,
|
|
87
|
+
* SHOULD be the value that the client is using to make its next Adaptive
|
|
88
|
+
* Bitrate switching decision. If the client is connected to multiple
|
|
89
|
+
* servers concurrently, it must take care to report only the throughput
|
|
90
|
+
* measured against the receiving server. If the client has multiple
|
|
91
|
+
* concurrent connections to the server, then the intent is that this value
|
|
92
|
+
* communicates the aggregate throughput the client sees across all those
|
|
93
|
+
* connections.
|
|
94
|
+
*
|
|
95
|
+
* @property {string} nor
|
|
96
|
+
* Relative path of the next object to be requested. This can be used to
|
|
97
|
+
* trigger pre-fetching by the CDN. This MUST be a path relative to the
|
|
98
|
+
* current request. This string MUST be URLEncoded. The client SHOULD NOT
|
|
99
|
+
* depend upon any pre-fetch action being taken - it is merely a request for
|
|
100
|
+
* such a pre-fetch to take place.
|
|
101
|
+
*
|
|
102
|
+
* @property {string} nrr
|
|
103
|
+
* If the next request will be a partial object request, then this string
|
|
104
|
+
* denotes the byte range to be requested. If the ‘nor’ field is not set, then
|
|
105
|
+
* the object is assumed to match the object currently being requested. The
|
|
106
|
+
* client SHOULD NOT depend upon any pre-fetch action being taken – it is
|
|
107
|
+
* merely a request for such a pre-fetch to take place. Formatting is similar
|
|
108
|
+
* to the HTTP Range header, except that the unit MUST be ‘byte’, the ‘Range:’
|
|
109
|
+
* prefix is NOT required and specifying multiple ranges is NOT allowed. Valid
|
|
110
|
+
* combinations are:
|
|
111
|
+
*
|
|
112
|
+
* - `"\<range-start\>-"`
|
|
113
|
+
* - `"\<range-start\>-\<range-end\>"`
|
|
114
|
+
* - `"-\<suffix-length\>"`
|
|
115
|
+
*
|
|
116
|
+
* @property {boolean} su
|
|
117
|
+
* Key is included without a value if the object is needed urgently due to
|
|
118
|
+
* startup, seeking or recovery after a buffer-empty event. The media SHOULD
|
|
119
|
+
* not be rendering when this request is made. This key MUST not be sent if it
|
|
120
|
+
* is FALSE.
|
|
121
|
+
*
|
|
122
|
+
* @property {string} cid
|
|
123
|
+
* A unique string identifying the current content. Maximum length is 64
|
|
124
|
+
* characters. This value is consistent across multiple different sessions and
|
|
125
|
+
* devices and is defined and updated at the discretion of the service
|
|
126
|
+
* provider.
|
|
127
|
+
*
|
|
128
|
+
* @property {number} pr
|
|
129
|
+
* The playback rate. `1` if real-time, `2` if double speed, `0` if not
|
|
130
|
+
* playing. SHOULD only be sent if not equal to `1`.
|
|
131
|
+
*
|
|
132
|
+
* @property {string} sf
|
|
133
|
+
* The streaming format that defines the current request.
|
|
134
|
+
*
|
|
135
|
+
* - `d` = MPEG DASH
|
|
136
|
+
* - `h` = HTTP Live Streaming (HLS)
|
|
137
|
+
* - `s` = Smooth Streaming
|
|
138
|
+
* - `o` = other
|
|
139
|
+
*
|
|
140
|
+
* If the streaming format being requested is unknown, then this key MUST NOT
|
|
141
|
+
* be used.
|
|
142
|
+
*
|
|
143
|
+
* @property {string} sid
|
|
144
|
+
* A GUID identifying the current playback session. A playback session
|
|
145
|
+
* typically ties together segments belonging to a single media asset. Maximum
|
|
146
|
+
* length is 64 characters. It is RECOMMENDED to conform to the UUID
|
|
147
|
+
* specification.
|
|
148
|
+
*
|
|
149
|
+
* @property {string} st
|
|
150
|
+
* Stream type
|
|
151
|
+
* - `v` = all segments are available – e.g., VOD
|
|
152
|
+
* - `l` = segments become available over time – e.g., LIVE
|
|
153
|
+
*
|
|
154
|
+
* @property {number} v
|
|
155
|
+
* The version of this specification used for interpreting the defined key
|
|
156
|
+
* names and values. If this key is omitted, the client and server MUST
|
|
157
|
+
* interpret the values as being defined by version 1. Client SHOULD omit this
|
|
158
|
+
* field if the version is 1.
|
|
159
|
+
*
|
|
160
|
+
* @property {boolean} bs
|
|
161
|
+
* Buffer starvation key is included without a value if the buffer was starved
|
|
162
|
+
* at some point between the prior request and this object request, resulting
|
|
163
|
+
* in the player being in a rebuffering state and the video or audio playback
|
|
164
|
+
* being stalled. This key MUST NOT be sent if the buffer was not starved
|
|
165
|
+
* since the prior request.
|
|
166
|
+
*
|
|
167
|
+
* If the object type `ot` key is sent along with this key, then the `bs` key
|
|
168
|
+
* refers to the buffer associated with the particular object type. If no
|
|
169
|
+
* object type is communicated, then the buffer state applies to the current
|
|
170
|
+
* session.
|
|
171
|
+
*
|
|
172
|
+
* @property {number} rtp
|
|
173
|
+
* Requested maximum throughput
|
|
174
|
+
*
|
|
175
|
+
* The requested maximum throughput that the client considers sufficient for
|
|
176
|
+
* delivery of the asset. Values MUST be rounded to the nearest 100kbps. For
|
|
177
|
+
* example, a client would indicate that the current segment, encoded at
|
|
178
|
+
* 2Mbps, is to be delivered at no more than 10Mbps, by using rtp=10000.
|
|
179
|
+
*
|
|
180
|
+
* Note: This can benefit clients by preventing buffer saturation through
|
|
181
|
+
* over-delivery and can also deliver a community benefit through fair-share
|
|
182
|
+
* delivery. The concept is that each client receives the throughput necessary
|
|
183
|
+
* for great performance, but no more. The CDN may not support the rtp
|
|
184
|
+
* feature.
|
|
185
|
+
*/
|
|
186
|
+
var CmcdData;
|
package/externs/shaka/player.js
CHANGED
|
@@ -1207,6 +1207,8 @@ shaka.extern.LanguageRole;
|
|
|
1207
1207
|
|
|
1208
1208
|
/**
|
|
1209
1209
|
* @typedef {{
|
|
1210
|
+
* imageHeight: number,
|
|
1211
|
+
* imageWidth: number,
|
|
1210
1212
|
* height: number,
|
|
1211
1213
|
* positionX: number,
|
|
1212
1214
|
* positionY: number,
|
|
@@ -1216,6 +1218,12 @@ shaka.extern.LanguageRole;
|
|
|
1216
1218
|
* width: number
|
|
1217
1219
|
* }}
|
|
1218
1220
|
*
|
|
1221
|
+
* @property {number} imageHeight
|
|
1222
|
+
* The image height in px. The image height could be different to height if
|
|
1223
|
+
* the layout is different to 1x1.
|
|
1224
|
+
* @property {number} imageWidth
|
|
1225
|
+
* The image width in px. The image width could be different to width if
|
|
1226
|
+
* the layout is different to 1x1.
|
|
1219
1227
|
* @property {number} height
|
|
1220
1228
|
* The thumbnail height in px.
|
|
1221
1229
|
* @property {number} positionX
|
package/externs/shaka/text.js
CHANGED
|
@@ -363,6 +363,16 @@ shaka.extern.Cue = class {
|
|
|
363
363
|
*/
|
|
364
364
|
this.nestedCues;
|
|
365
365
|
|
|
366
|
+
/**
|
|
367
|
+
* If true, this represents a container element that is "above" the main
|
|
368
|
+
* cues. For example, the <body> and <div> tags that contain the <p> tags
|
|
369
|
+
* in a TTML file. This controls the flow of the final cues; any nested cues
|
|
370
|
+
* within an "isContainer" cue will be laid out as separate lines.
|
|
371
|
+
* @type {boolean}
|
|
372
|
+
* @exportDoc
|
|
373
|
+
*/
|
|
374
|
+
this.isContainer;
|
|
375
|
+
|
|
366
376
|
/**
|
|
367
377
|
* Whether or not the cue only acts as a line break between two nested cues.
|
|
368
378
|
* Should only appear in nested cues.
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -1281,6 +1281,30 @@ shaka.hls.HlsParser = class {
|
|
|
1281
1281
|
if (this.uriToStreamInfosMap_.has(verbatimImagePlaylistUri)) {
|
|
1282
1282
|
return this.uriToStreamInfosMap_.get(verbatimImagePlaylistUri);
|
|
1283
1283
|
}
|
|
1284
|
+
|
|
1285
|
+
// Parse misc attributes.
|
|
1286
|
+
const resolution = tag.getAttributeValue('RESOLUTION');
|
|
1287
|
+
if (resolution) {
|
|
1288
|
+
// The RESOLUTION tag represents the resolution of a single thumbnail, not
|
|
1289
|
+
// of the entire sheet at once (like we expect in the output).
|
|
1290
|
+
// So multiply by the layout size.
|
|
1291
|
+
|
|
1292
|
+
const reference = streamInfo.stream.segmentIndex.get(0);
|
|
1293
|
+
const layout = reference.getTilesLayout();
|
|
1294
|
+
if (layout) {
|
|
1295
|
+
streamInfo.stream.width =
|
|
1296
|
+
Number(resolution.split('x')[0]) * Number(layout.split('x')[0]);
|
|
1297
|
+
streamInfo.stream.height =
|
|
1298
|
+
Number(resolution.split('x')[1]) * Number(layout.split('x')[1]);
|
|
1299
|
+
// TODO: What happens if there are multiple grids, with different
|
|
1300
|
+
// layout sizes, inside this image stream?
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
const bandwidth = tag.getAttributeValue('BANDWIDTH');
|
|
1304
|
+
if (bandwidth) {
|
|
1305
|
+
streamInfo.stream.bandwidth = Number(bandwidth);
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1284
1308
|
this.uriToStreamInfosMap_.set(verbatimImagePlaylistUri, streamInfo);
|
|
1285
1309
|
return streamInfo;
|
|
1286
1310
|
}
|
|
@@ -1814,6 +1838,7 @@ shaka.hls.HlsParser = class {
|
|
|
1814
1838
|
}
|
|
1815
1839
|
|
|
1816
1840
|
let tilesLayout = '';
|
|
1841
|
+
let tileDuration = null;
|
|
1817
1842
|
if (type == shaka.util.ManifestParserUtils.ContentType.IMAGE) {
|
|
1818
1843
|
// By default in HLS the tilesLayout is 1x1
|
|
1819
1844
|
tilesLayout = '1x1';
|
|
@@ -1821,6 +1846,10 @@ shaka.hls.HlsParser = class {
|
|
|
1821
1846
|
shaka.hls.Utils.getFirstTagWithName(tags, 'EXT-X-TILES');
|
|
1822
1847
|
if (tilesTag) {
|
|
1823
1848
|
tilesLayout = tilesTag.getRequiredAttrValue('LAYOUT');
|
|
1849
|
+
const duration = tilesTag.getAttributeValue('DURATION');
|
|
1850
|
+
if (duration) {
|
|
1851
|
+
tileDuration = Number(duration);
|
|
1852
|
+
}
|
|
1824
1853
|
}
|
|
1825
1854
|
}
|
|
1826
1855
|
|
|
@@ -1836,6 +1865,7 @@ shaka.hls.HlsParser = class {
|
|
|
1836
1865
|
/* appendWindowEnd= */ Infinity,
|
|
1837
1866
|
partialSegmentRefs,
|
|
1838
1867
|
tilesLayout,
|
|
1868
|
+
tileDuration,
|
|
1839
1869
|
);
|
|
1840
1870
|
}
|
|
1841
1871
|
|
|
@@ -347,7 +347,8 @@ shaka.media.SegmentIndex = class {
|
|
|
347
347
|
lastReference.appendWindowStart,
|
|
348
348
|
lastReference.appendWindowEnd,
|
|
349
349
|
lastReference.partialReferences,
|
|
350
|
-
lastReference.tilesLayout
|
|
350
|
+
lastReference.tilesLayout,
|
|
351
|
+
lastReference.tileDuration);
|
|
351
352
|
}
|
|
352
353
|
|
|
353
354
|
|
|
@@ -155,11 +155,15 @@ shaka.media.SegmentReference = class {
|
|
|
155
155
|
* The value is a grid-item-dimension consisting of two positive decimal
|
|
156
156
|
* integers in the format: column-x-row ('4x3'). It describes the
|
|
157
157
|
* arrangement of Images in a Grid. The minimum valid LAYOUT is '1x1'.
|
|
158
|
+
* @param {?number=} tileDuration
|
|
159
|
+
* The explicit duration of an individual tile within the tiles grid.
|
|
160
|
+
* If not provided, the duration should be automatically calculated based on
|
|
161
|
+
* the duration of the reference.
|
|
158
162
|
*/
|
|
159
163
|
constructor(
|
|
160
164
|
startTime, endTime, uris, startByte, endByte, initSegmentReference,
|
|
161
165
|
timestampOffset, appendWindowStart, appendWindowEnd,
|
|
162
|
-
partialReferences = [], tilesLayout = '') {
|
|
166
|
+
partialReferences = [], tilesLayout = '', tileDuration = null) {
|
|
163
167
|
// A preload hinted Partial Segment has the same startTime and endTime.
|
|
164
168
|
goog.asserts.assert(startTime <= endTime,
|
|
165
169
|
'startTime must be less than or equal to endTime');
|
|
@@ -206,6 +210,9 @@ shaka.media.SegmentReference = class {
|
|
|
206
210
|
|
|
207
211
|
/** @type {?string} */
|
|
208
212
|
this.tilesLayout = tilesLayout;
|
|
213
|
+
|
|
214
|
+
/** @type {?number} */
|
|
215
|
+
this.tileDuration = tileDuration;
|
|
209
216
|
}
|
|
210
217
|
|
|
211
218
|
/**
|
|
@@ -290,6 +297,17 @@ shaka.media.SegmentReference = class {
|
|
|
290
297
|
getTilesLayout() {
|
|
291
298
|
return this.tilesLayout;
|
|
292
299
|
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Returns the segment's explicit tile duration.
|
|
303
|
+
* Only defined in image segments.
|
|
304
|
+
*
|
|
305
|
+
* @return {?number}
|
|
306
|
+
* @export
|
|
307
|
+
*/
|
|
308
|
+
getTileDuration() {
|
|
309
|
+
return this.tileDuration;
|
|
310
|
+
}
|
|
293
311
|
};
|
|
294
312
|
|
|
295
313
|
|
|
@@ -628,7 +628,7 @@ shaka.media.StreamingEngine = class {
|
|
|
628
628
|
|
|
629
629
|
// Don't clear the buffer unless something is buffered. This extra
|
|
630
630
|
// check prevents extra, useless calls to clear the buffer.
|
|
631
|
-
if (somethingBuffered) {
|
|
631
|
+
if (somethingBuffered || mediaState.performingUpdate) {
|
|
632
632
|
this.forceClearBuffer_(mediaState);
|
|
633
633
|
streamCleared = true;
|
|
634
634
|
}
|
|
@@ -988,7 +988,10 @@ shaka.media.StreamingEngine = class {
|
|
|
988
988
|
unscaledBufferingGoal * this.bufferingGoalScale_;
|
|
989
989
|
|
|
990
990
|
// Check if we've buffered to the end of the presentation.
|
|
991
|
-
|
|
991
|
+
const timeUntilEnd =
|
|
992
|
+
this.manifest_.presentationTimeline.getDuration() - timeNeeded;
|
|
993
|
+
const oneMicrosecond = 1e-6;
|
|
994
|
+
if (timeUntilEnd < oneMicrosecond) {
|
|
992
995
|
// We shouldn't rebuffer if the playhead is close to the end of the
|
|
993
996
|
// presentation.
|
|
994
997
|
shaka.log.debug(logPrefix, 'buffered to end of presentation');
|
package/lib/player.js
CHANGED
|
@@ -2817,14 +2817,13 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2817
2817
|
* @private
|
|
2818
2818
|
*/
|
|
2819
2819
|
createCmcd_() {
|
|
2820
|
-
const abr = this.abrManager_;
|
|
2821
|
-
|
|
2822
2820
|
/** @type {shaka.util.CmcdManager.PlayerInterface} */
|
|
2823
2821
|
const playerInterface = {
|
|
2824
|
-
getBandwidthEstimate: () =>
|
|
2822
|
+
getBandwidthEstimate: () => this.abrManager_ ?
|
|
2823
|
+
this.abrManager_.getBandwidthEstimate() : NaN,
|
|
2825
2824
|
getBufferedInfo: () => this.getBufferedInfo(),
|
|
2826
2825
|
getCurrentTime: () => this.video_ ? this.video_.currentTime : 0,
|
|
2827
|
-
|
|
2826
|
+
getVariantTracks: () => this.getVariantTracks(),
|
|
2828
2827
|
getPlaybackRate: () => this.getPlaybackRate(),
|
|
2829
2828
|
isLive: () => this.isLive(),
|
|
2830
2829
|
};
|
|
@@ -3613,7 +3612,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3613
3612
|
const height = fullImageHeight / rows;
|
|
3614
3613
|
const totalImages = columns * rows;
|
|
3615
3614
|
const segmentDuration = reference.trueEndTime - reference.startTime;
|
|
3616
|
-
const thumbnailDuration =
|
|
3615
|
+
const thumbnailDuration =
|
|
3616
|
+
reference.getTileDuration() || (segmentDuration / totalImages);
|
|
3617
3617
|
let thumbnailTime = reference.startTime;
|
|
3618
3618
|
let positionX = 0;
|
|
3619
3619
|
let positionY = 0;
|
|
@@ -3636,6 +3636,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3636
3636
|
positionY = Math.floor(thumbnailPosition / columns) * height;
|
|
3637
3637
|
}
|
|
3638
3638
|
return {
|
|
3639
|
+
imageHeight: fullImageHeight,
|
|
3640
|
+
imageWidth: fullImageWidth,
|
|
3639
3641
|
height: height,
|
|
3640
3642
|
positionX: positionX,
|
|
3641
3643
|
positionY: positionY,
|
|
@@ -4037,20 +4039,24 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4037
4039
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
4038
4040
|
const inputlanguage = LanguageUtils.normalize(language);
|
|
4039
4041
|
const chaptersTracks = this.getChaptersTracks_();
|
|
4040
|
-
const
|
|
4041
|
-
.
|
|
4042
|
-
if (!
|
|
4042
|
+
const chaptersTracksWithLanguage = chaptersTracks
|
|
4043
|
+
.filter((t) => LanguageUtils.normalize(t.language) == inputlanguage);
|
|
4044
|
+
if (!chaptersTracksWithLanguage || !chaptersTracksWithLanguage.length) {
|
|
4043
4045
|
return [];
|
|
4044
4046
|
}
|
|
4045
4047
|
const chapters = [];
|
|
4046
|
-
for (const
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4048
|
+
for (const chaptersTrack of chaptersTracksWithLanguage) {
|
|
4049
|
+
if (chaptersTrack && chaptersTrack.cues) {
|
|
4050
|
+
for (const cue of chaptersTrack.cues) {
|
|
4051
|
+
/** @type {shaka.extern.Chapter} */
|
|
4052
|
+
const chapter = {
|
|
4053
|
+
title: cue.text,
|
|
4054
|
+
startTime: cue.startTime,
|
|
4055
|
+
endTime: cue.endTime,
|
|
4056
|
+
};
|
|
4057
|
+
chapters.push(chapter);
|
|
4058
|
+
}
|
|
4059
|
+
}
|
|
4054
4060
|
}
|
|
4055
4061
|
return chapters;
|
|
4056
4062
|
}
|
|
@@ -6530,7 +6536,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
6530
6536
|
* @define {string} A version number taken from git at compile time.
|
|
6531
6537
|
* @export
|
|
6532
6538
|
*/
|
|
6533
|
-
shaka.Player.version = 'v3.3.
|
|
6539
|
+
shaka.Player.version = 'v3.3.1-uncompiled';
|
|
6534
6540
|
|
|
6535
6541
|
// Initialize the deprecation system using the version string we just set
|
|
6536
6542
|
// on the player.
|
|
@@ -24,8 +24,6 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
24
24
|
* @export
|
|
25
25
|
*/
|
|
26
26
|
static install() {
|
|
27
|
-
shaka.log.debug('MediaCapabilities: install');
|
|
28
|
-
|
|
29
27
|
// Since MediaCapabilities is not fully supported on Chromecast yet, we
|
|
30
28
|
// should always install polyfill for Chromecast.
|
|
31
29
|
// TODO: re-evaluate MediaCapabilities in the future versions of Chromecast.
|
|
@@ -40,21 +38,28 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
40
38
|
// TODO: re-evaluate MediaCapabilities in the future versions of PS5
|
|
41
39
|
// Browsers.
|
|
42
40
|
if (!shaka.util.Platform.isChromecast() &&
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
shaka.log.
|
|
41
|
+
!shaka.util.Platform.isApple() &&
|
|
42
|
+
!shaka.util.Platform.isPS5() &&
|
|
43
|
+
navigator.mediaCapabilities) {
|
|
44
|
+
shaka.log.info(
|
|
47
45
|
'MediaCapabilities: Native mediaCapabilities support found.');
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
shaka.log.info('MediaCapabilities: install');
|
|
50
|
+
|
|
51
|
+
if (!navigator.mediaCapabilities) {
|
|
52
|
+
navigator.mediaCapabilities = /** @type {!MediaCapabilities} */ ({});
|
|
54
53
|
}
|
|
55
|
-
|
|
56
|
-
// MediaCapabilities
|
|
57
|
-
|
|
54
|
+
|
|
55
|
+
// Keep the patched MediaCapabilities object from being garbage-collected in
|
|
56
|
+
// Safari.
|
|
57
|
+
// See https://github.com/google/shaka-player/issues/3696#issuecomment-1009472718
|
|
58
|
+
shaka.polyfill.MediaCapabilities.originalMcap =
|
|
59
|
+
navigator.mediaCapabilities;
|
|
60
|
+
|
|
61
|
+
navigator.mediaCapabilities.decodingInfo =
|
|
62
|
+
shaka.polyfill.MediaCapabilities.decodingInfo_;
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
/**
|
|
@@ -182,6 +187,16 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
182
187
|
}
|
|
183
188
|
};
|
|
184
189
|
|
|
190
|
+
/**
|
|
191
|
+
* A copy of the MediaCapabilities instance, to prevent Safari from
|
|
192
|
+
* garbage-collecting the polyfilled method on it. We make it public and export
|
|
193
|
+
* it to ensure that it is not stripped out by the compiler.
|
|
194
|
+
*
|
|
195
|
+
* @type {MediaCapabilities}
|
|
196
|
+
* @export
|
|
197
|
+
*/
|
|
198
|
+
shaka.polyfill.MediaCapabilities.originalMcap = null;
|
|
199
|
+
|
|
185
200
|
// Install at a lower priority than MediaSource polyfill, so that we have
|
|
186
201
|
// MediaSource available first.
|
|
187
202
|
shaka.polyfill.register(shaka.polyfill.MediaCapabilities.install, -1);
|