shaka-player 4.7.13 → 4.8.0
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 +1 -0
- package/CONTRIBUTORS +1 -0
- package/LICENSE +54 -0
- package/README.md +22 -1
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/deps.js +34 -23
- package/dist/locales.js +44 -34
- package/dist/shaka-player.compiled.d.ts +194 -44
- package/dist/shaka-player.compiled.debug.d.ts +194 -44
- package/dist/shaka-player.compiled.debug.externs.js +474 -337
- package/dist/shaka-player.compiled.debug.js +949 -832
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +474 -337
- package/dist/shaka-player.compiled.js +1237 -1171
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +257 -47
- package/dist/shaka-player.ui.debug.d.ts +257 -47
- package/dist/shaka-player.ui.debug.externs.js +591 -376
- package/dist/shaka-player.ui.debug.js +1165 -965
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +591 -376
- package/dist/shaka-player.ui.js +1521 -1404
- package/dist/shaka-player.ui.map +4 -4
- package/externs/device_sensor_event.js +18 -0
- package/externs/hisense.js +16 -0
- package/externs/playstation.js +31 -0
- package/externs/shaka/abr_manager.js +3 -1
- package/externs/shaka/ads.js +5 -0
- package/externs/shaka/codecs.js +13 -0
- package/externs/shaka/manifest.js +58 -6
- package/externs/shaka/net.js +13 -1
- package/externs/shaka/player.js +184 -13
- package/externs/shaka/text.js +19 -0
- package/externs/tizen.js +41 -0
- package/externs/webos.js +19 -0
- package/externs/xbox.js +43 -0
- package/lib/abr/simple_abr_manager.js +9 -1
- package/lib/ads/ad_manager.js +19 -2
- package/lib/ads/client_side_ad_manager.js +5 -3
- package/lib/ads/media_tailor_ad_manager.js +9 -0
- package/lib/cast/cast_receiver.js +0 -14
- package/lib/cast/cast_utils.js +1 -0
- package/lib/cea/mp4_cea_parser.js +6 -1
- package/lib/dash/content_protection.js +97 -53
- package/lib/dash/dash_parser.js +230 -176
- package/lib/dash/mpd_utils.js +72 -65
- package/lib/dash/segment_base.js +27 -21
- package/lib/dash/segment_list.js +18 -16
- package/lib/dash/segment_template.js +26 -21
- package/lib/hls/hls_parser.js +358 -164
- package/lib/media/buffering_observer.js +25 -1
- package/lib/media/drm_engine.js +91 -71
- package/lib/media/manifest_filterer.js +220 -0
- package/lib/media/media_source_engine.js +34 -5
- package/lib/media/preload_manager.js +827 -0
- package/lib/media/presentation_timeline.js +11 -0
- package/lib/media/segment_index.js +40 -30
- package/lib/media/segment_prefetch.js +140 -43
- package/lib/media/segment_reference.js +31 -8
- package/lib/media/segment_utils.js +208 -25
- package/lib/media/streaming_engine.js +319 -63
- package/lib/mss/content_protection.js +31 -25
- package/lib/mss/mss_parser.js +74 -55
- package/lib/net/networking_engine.js +49 -4
- package/lib/offline/storage.js +3 -3
- package/lib/player.js +882 -673
- package/lib/polyfill/media_capabilities.js +16 -1
- package/lib/text/simple_text_displayer.js +9 -0
- package/lib/text/stub_text_displayer.js +7 -0
- package/lib/text/text_engine.js +16 -3
- package/lib/text/ttml_text_parser.js +116 -114
- package/lib/text/ui_text_displayer.js +28 -11
- package/lib/text/vtt_text_parser.js +54 -115
- package/lib/transmuxer/opus.js +91 -0
- package/lib/transmuxer/ts_transmuxer.js +115 -0
- package/lib/util/cmcd_manager.js +152 -3
- package/lib/util/dom_utils.js +11 -0
- package/lib/util/error.js +5 -0
- package/lib/util/fake_event.js +2 -0
- package/lib/util/manifest_parser_utils.js +97 -3
- package/lib/util/mp4_box_parsers.js +346 -17
- package/lib/util/mp4_generator.js +23 -0
- package/lib/util/periods.js +19 -0
- package/lib/util/platform.js +161 -9
- package/lib/util/player_configuration.js +61 -3
- package/lib/util/stats.js +16 -0
- package/lib/util/stream_utils.js +16 -6
- package/lib/util/string_utils.js +36 -0
- package/lib/util/tXml.js +814 -0
- package/lib/util/ts_parser.js +50 -0
- package/lib/util/xml_utils.js +10 -338
- package/package.json +2 -2
- package/shaka-player.uncompiled.js +8 -0
- package/ui/controls.js +187 -5
- package/ui/enums.js +2 -0
- package/ui/externs/ui.js +30 -3
- package/ui/gl_matrix/matrix_4x4.js +568 -0
- package/ui/gl_matrix/matrix_quaternion.js +45 -0
- package/ui/less/containers.less +11 -0
- package/ui/locales/en-GB.json +2 -0
- package/ui/locales/en.json +2 -0
- package/ui/locales/es-419.json +2 -0
- package/ui/locales/es.json +2 -0
- package/ui/locales/source.json +8 -0
- package/ui/recenter_vr.js +126 -0
- package/ui/resolution_selection.js +25 -5
- package/ui/statistics_button.js +12 -0
- package/ui/text_selection.js +1 -1
- package/ui/toggle_stereoscopic.js +127 -0
- package/ui/ui.js +74 -38
- package/ui/vr_manager.js +557 -0
- package/ui/vr_utils.js +232 -0
- package/ui/vr_webgl.js +697 -0
package/lib/dash/mpd_utils.js
CHANGED
|
@@ -13,7 +13,7 @@ goog.require('shaka.util.AbortableOperation');
|
|
|
13
13
|
goog.require('shaka.util.Error');
|
|
14
14
|
goog.require('shaka.util.Functional');
|
|
15
15
|
goog.require('shaka.util.ManifestParserUtils');
|
|
16
|
-
goog.require('shaka.util.
|
|
16
|
+
goog.require('shaka.util.TXml');
|
|
17
17
|
goog.requireType('shaka.dash.DashParser');
|
|
18
18
|
goog.requireType('shaka.media.PresentationTimeline');
|
|
19
19
|
|
|
@@ -123,7 +123,7 @@ shaka.dash.MpdUtils = class {
|
|
|
123
123
|
* Expands a SegmentTimeline into an array-based timeline. The results are in
|
|
124
124
|
* seconds.
|
|
125
125
|
*
|
|
126
|
-
* @param {!
|
|
126
|
+
* @param {!shaka.extern.xml.Node} segmentTimeline
|
|
127
127
|
* @param {number} timescale
|
|
128
128
|
* @param {number} unscaledPresentationTimeOffset
|
|
129
129
|
* @param {number} periodDuration The Period's duration in seconds.
|
|
@@ -141,9 +141,9 @@ shaka.dash.MpdUtils = class {
|
|
|
141
141
|
periodDuration > 0, 'period duration must be a positive integer');
|
|
142
142
|
|
|
143
143
|
// Alias.
|
|
144
|
-
const
|
|
144
|
+
const TXml = shaka.util.TXml;
|
|
145
145
|
|
|
146
|
-
const timePoints =
|
|
146
|
+
const timePoints = TXml.findChildren(segmentTimeline, 'S');
|
|
147
147
|
|
|
148
148
|
/** @type {!Array.<shaka.media.PresentationTimeline.TimeRange>} */
|
|
149
149
|
const timeline = [];
|
|
@@ -152,12 +152,12 @@ shaka.dash.MpdUtils = class {
|
|
|
152
152
|
for (let i = 0; i < timePoints.length; ++i) {
|
|
153
153
|
const timePoint = timePoints[i];
|
|
154
154
|
const next = timePoints[i + 1];
|
|
155
|
-
let t =
|
|
155
|
+
let t = TXml.parseAttr(timePoint, 't', TXml.parseNonNegativeInt);
|
|
156
156
|
const d =
|
|
157
|
-
|
|
158
|
-
const r =
|
|
157
|
+
TXml.parseAttr(timePoint, 'd', TXml.parseNonNegativeInt);
|
|
158
|
+
const r = TXml.parseAttr(timePoint, 'r', TXml.parseInt);
|
|
159
159
|
|
|
160
|
-
const k =
|
|
160
|
+
const k = TXml.parseAttr(timePoint, 'k', TXml.parseInt);
|
|
161
161
|
|
|
162
162
|
const partialSegments = k || 0;
|
|
163
163
|
|
|
@@ -179,7 +179,7 @@ shaka.dash.MpdUtils = class {
|
|
|
179
179
|
if (repeat < 0) {
|
|
180
180
|
if (next) {
|
|
181
181
|
const nextStartTime =
|
|
182
|
-
|
|
182
|
+
TXml.parseAttr(next, 't', TXml.parseNonNegativeInt);
|
|
183
183
|
if (nextStartTime == null) {
|
|
184
184
|
shaka.log.warning(
|
|
185
185
|
'An "S" element cannot have a negative repeat',
|
|
@@ -260,7 +260,8 @@ shaka.dash.MpdUtils = class {
|
|
|
260
260
|
* Parses common segment info for SegmentList and SegmentTemplate.
|
|
261
261
|
*
|
|
262
262
|
* @param {shaka.dash.DashParser.Context} context
|
|
263
|
-
* @param {function(?shaka.dash.DashParser.InheritanceFrame):
|
|
263
|
+
* @param {function(?shaka.dash.DashParser.InheritanceFrame):
|
|
264
|
+
* ?shaka.extern.xml.Node} callback
|
|
264
265
|
* Gets the element that contains the segment info.
|
|
265
266
|
* @return {shaka.dash.MpdUtils.SegmentInfo}
|
|
266
267
|
*/
|
|
@@ -269,23 +270,23 @@ shaka.dash.MpdUtils = class {
|
|
|
269
270
|
callback(context.representation),
|
|
270
271
|
'There must be at least one element of the given type.');
|
|
271
272
|
const MpdUtils = shaka.dash.MpdUtils;
|
|
272
|
-
const
|
|
273
|
+
const TXml = shaka.util.TXml;
|
|
273
274
|
|
|
274
275
|
const timescaleStr =
|
|
275
276
|
MpdUtils.inheritAttribute(context, callback, 'timescale');
|
|
276
277
|
let timescale = 1;
|
|
277
278
|
if (timescaleStr) {
|
|
278
|
-
timescale =
|
|
279
|
+
timescale = TXml.parsePositiveInt(timescaleStr) || 1;
|
|
279
280
|
}
|
|
280
281
|
|
|
281
282
|
const durationStr =
|
|
282
283
|
MpdUtils.inheritAttribute(context, callback, 'duration');
|
|
283
|
-
let segmentDuration =
|
|
284
|
+
let segmentDuration = TXml.parsePositiveInt(durationStr || '');
|
|
284
285
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
285
286
|
// TODO: The specification is not clear, check this once it is resolved:
|
|
286
287
|
// https://github.com/Dash-Industry-Forum/DASH-IF-IOP/issues/404
|
|
287
288
|
if (context.representation.contentType == ContentType.IMAGE) {
|
|
288
|
-
segmentDuration =
|
|
289
|
+
segmentDuration = TXml.parseFloat(durationStr || '');
|
|
289
290
|
}
|
|
290
291
|
if (segmentDuration) {
|
|
291
292
|
segmentDuration /= timescale;
|
|
@@ -296,7 +297,7 @@ shaka.dash.MpdUtils = class {
|
|
|
296
297
|
const unscaledPresentationTimeOffset =
|
|
297
298
|
Number(MpdUtils.inheritAttribute(context, callback,
|
|
298
299
|
'presentationTimeOffset')) || 0;
|
|
299
|
-
let startNumber =
|
|
300
|
+
let startNumber = TXml.parseNonNegativeInt(startNumberStr || '');
|
|
300
301
|
if (startNumberStr == null || startNumber == null) {
|
|
301
302
|
startNumber = 1;
|
|
302
303
|
}
|
|
@@ -326,8 +327,9 @@ shaka.dash.MpdUtils = class {
|
|
|
326
327
|
/**
|
|
327
328
|
* Parses common attributes for Representation, AdaptationSet, and Period.
|
|
328
329
|
* @param {shaka.dash.DashParser.Context} context
|
|
329
|
-
* @param {function(?shaka.dash.DashParser.InheritanceFrame):
|
|
330
|
-
*
|
|
330
|
+
* @param {function(?shaka.dash.DashParser.InheritanceFrame):
|
|
331
|
+
* ?shaka.extern.xml.Node} callback
|
|
332
|
+
* @return {!Array.<!shaka.extern.xml.Node>}
|
|
331
333
|
*/
|
|
332
334
|
static getNodes(context, callback) {
|
|
333
335
|
const Functional = shaka.util.Functional;
|
|
@@ -347,7 +349,8 @@ shaka.dash.MpdUtils = class {
|
|
|
347
349
|
* Searches the inheritance for a Segment* with the given attribute.
|
|
348
350
|
*
|
|
349
351
|
* @param {shaka.dash.DashParser.Context} context
|
|
350
|
-
* @param {function(?shaka.dash.DashParser.InheritanceFrame):
|
|
352
|
+
* @param {function(?shaka.dash.DashParser.InheritanceFrame):
|
|
353
|
+
* ?shaka.extern.xml.Node} callback
|
|
351
354
|
* Gets the Element that contains the attribute to inherit.
|
|
352
355
|
* @param {string} attribute
|
|
353
356
|
* @return {?string}
|
|
@@ -358,7 +361,7 @@ shaka.dash.MpdUtils = class {
|
|
|
358
361
|
|
|
359
362
|
let result = null;
|
|
360
363
|
for (const node of nodes) {
|
|
361
|
-
result = node.
|
|
364
|
+
result = node.attributes[attribute];
|
|
362
365
|
if (result) {
|
|
363
366
|
break;
|
|
364
367
|
}
|
|
@@ -370,19 +373,20 @@ shaka.dash.MpdUtils = class {
|
|
|
370
373
|
* Searches the inheritance for a Segment* with the given child.
|
|
371
374
|
*
|
|
372
375
|
* @param {shaka.dash.DashParser.Context} context
|
|
373
|
-
* @param {function(?shaka.dash.DashParser.InheritanceFrame):
|
|
376
|
+
* @param {function(?shaka.dash.DashParser.InheritanceFrame):
|
|
377
|
+
* ?shaka.extern.xml.Node} callback
|
|
374
378
|
* Gets the Element that contains the child to inherit.
|
|
375
379
|
* @param {string} child
|
|
376
|
-
* @return {
|
|
380
|
+
* @return {?shaka.extern.xml.Node}
|
|
377
381
|
*/
|
|
378
382
|
static inheritChild(context, callback, child) {
|
|
379
383
|
const MpdUtils = shaka.dash.MpdUtils;
|
|
380
384
|
const nodes = MpdUtils.getNodes(context, callback);
|
|
381
385
|
|
|
382
|
-
const
|
|
386
|
+
const TXml = shaka.util.TXml;
|
|
383
387
|
let result = null;
|
|
384
388
|
for (const node of nodes) {
|
|
385
|
-
result =
|
|
389
|
+
result = TXml.findChild(node, child);
|
|
386
390
|
if (result) {
|
|
387
391
|
break;
|
|
388
392
|
}
|
|
@@ -395,33 +399,35 @@ shaka.dash.MpdUtils = class {
|
|
|
395
399
|
* It also strips the xlink properties off of the element,
|
|
396
400
|
* even if the process fails.
|
|
397
401
|
*
|
|
398
|
-
* @param {!
|
|
402
|
+
* @param {!shaka.extern.xml.Node} element
|
|
399
403
|
* @param {!shaka.extern.RetryParameters} retryParameters
|
|
400
404
|
* @param {boolean} failGracefully
|
|
401
405
|
* @param {string} baseUri
|
|
402
406
|
* @param {!shaka.net.NetworkingEngine} networkingEngine
|
|
403
407
|
* @param {number} linkDepth
|
|
404
|
-
* @return {!shaka.util.AbortableOperation.<!
|
|
408
|
+
* @return {!shaka.util.AbortableOperation.<!shaka.extern.xml.Node>}
|
|
405
409
|
* @private
|
|
406
410
|
*/
|
|
407
411
|
static handleXlinkInElement_(
|
|
408
412
|
element, retryParameters, failGracefully, baseUri, networkingEngine,
|
|
409
413
|
linkDepth) {
|
|
410
414
|
const MpdUtils = shaka.dash.MpdUtils;
|
|
411
|
-
const
|
|
415
|
+
const TXml = shaka.util.TXml;
|
|
412
416
|
const Error = shaka.util.Error;
|
|
413
417
|
const ManifestParserUtils = shaka.util.ManifestParserUtils;
|
|
414
418
|
const NS = MpdUtils.XlinkNamespaceUri_;
|
|
415
419
|
|
|
416
|
-
const xlinkHref =
|
|
420
|
+
const xlinkHref = TXml.getAttributeNS(element, NS, 'href');
|
|
417
421
|
const xlinkActuate =
|
|
418
|
-
|
|
422
|
+
TXml.getAttributeNS(element, NS, 'actuate') || 'onRequest';
|
|
419
423
|
|
|
420
424
|
// Remove the xlink properties, so it won't download again
|
|
421
425
|
// when re-processed.
|
|
422
|
-
for (const
|
|
423
|
-
|
|
424
|
-
|
|
426
|
+
for (const key of Object.keys(element.attributes)) {
|
|
427
|
+
const segs = key.split(':');
|
|
428
|
+
const namespace = shaka.util.TXml.getKnownNameSpace(NS);
|
|
429
|
+
if (segs[0] == namespace) {
|
|
430
|
+
delete element.attributes[key];
|
|
425
431
|
}
|
|
426
432
|
}
|
|
427
433
|
|
|
@@ -465,7 +471,7 @@ shaka.dash.MpdUtils = class {
|
|
|
465
471
|
// top-level element. If there are multiple roots, it will be
|
|
466
472
|
// rejected.
|
|
467
473
|
const rootElem =
|
|
468
|
-
|
|
474
|
+
TXml.parseXml(response.data, element.tagName);
|
|
469
475
|
if (!rootElem) {
|
|
470
476
|
// It was not valid XML.
|
|
471
477
|
return shaka.util.AbortableOperation.failed(new Error(
|
|
@@ -477,20 +483,20 @@ shaka.dash.MpdUtils = class {
|
|
|
477
483
|
// the element can be changed further.
|
|
478
484
|
|
|
479
485
|
// Remove the current contents of the node.
|
|
480
|
-
|
|
481
|
-
element.removeChild(element.childNodes[0]);
|
|
482
|
-
}
|
|
486
|
+
element.children = [];
|
|
483
487
|
|
|
484
488
|
// Move the children of the loaded xml into the current element.
|
|
485
|
-
while (rootElem.
|
|
486
|
-
const child = rootElem.
|
|
487
|
-
|
|
488
|
-
|
|
489
|
+
while (rootElem.children.length) {
|
|
490
|
+
const child = rootElem.children.shift();
|
|
491
|
+
if (TXml.isNode(child)) {
|
|
492
|
+
child.parent = element;
|
|
493
|
+
}
|
|
494
|
+
element.children.push(child);
|
|
489
495
|
}
|
|
490
496
|
|
|
491
497
|
// Move the attributes of the loaded xml into the current element.
|
|
492
|
-
for (const
|
|
493
|
-
element.
|
|
498
|
+
for (const key of Object.keys(rootElem.attributes)) {
|
|
499
|
+
element.attributes[key] = rootElem.attributes[key];
|
|
494
500
|
}
|
|
495
501
|
|
|
496
502
|
return shaka.dash.MpdUtils.processXlinks(
|
|
@@ -503,25 +509,26 @@ shaka.dash.MpdUtils = class {
|
|
|
503
509
|
* Filter the contents of a node recursively, replacing xlink links
|
|
504
510
|
* with their associated online data.
|
|
505
511
|
*
|
|
506
|
-
* @param {!
|
|
512
|
+
* @param {!shaka.extern.xml.Node} element
|
|
507
513
|
* @param {!shaka.extern.RetryParameters} retryParameters
|
|
508
514
|
* @param {boolean} failGracefully
|
|
509
515
|
* @param {string} baseUri
|
|
510
516
|
* @param {!shaka.net.NetworkingEngine} networkingEngine
|
|
511
517
|
* @param {number=} linkDepth, default set to 0
|
|
512
|
-
* @return {!shaka.util.AbortableOperation.<!
|
|
518
|
+
* @return {!shaka.util.AbortableOperation.<!shaka.extern.xml.Node>}
|
|
513
519
|
*/
|
|
514
520
|
static processXlinks(
|
|
515
|
-
element, retryParameters,
|
|
521
|
+
element, retryParameters,
|
|
522
|
+
failGracefully, baseUri, networkingEngine,
|
|
516
523
|
linkDepth = 0) {
|
|
517
524
|
const MpdUtils = shaka.dash.MpdUtils;
|
|
518
|
-
const
|
|
525
|
+
const TXml = shaka.util.TXml;
|
|
519
526
|
const NS = MpdUtils.XlinkNamespaceUri_;
|
|
520
527
|
|
|
521
|
-
if (
|
|
528
|
+
if (TXml.getAttributeNS(element, NS, 'href')) {
|
|
522
529
|
let handled = MpdUtils.handleXlinkInElement_(
|
|
523
|
-
element, retryParameters, failGracefully,
|
|
524
|
-
linkDepth);
|
|
530
|
+
element, retryParameters, failGracefully,
|
|
531
|
+
baseUri, networkingEngine, linkDepth);
|
|
525
532
|
if (failGracefully) {
|
|
526
533
|
// Catch any error and go on.
|
|
527
534
|
handled = handled.chain(undefined, (error) => {
|
|
@@ -537,23 +544,23 @@ shaka.dash.MpdUtils = class {
|
|
|
537
544
|
}
|
|
538
545
|
|
|
539
546
|
const childOperations = [];
|
|
540
|
-
for (const child of
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
547
|
+
for (const child of shaka.util.TXml.getChildNodes(element)) {
|
|
548
|
+
const resolveToZeroString = 'urn:mpeg:dash:resolve-to-zero:2013';
|
|
549
|
+
if (TXml.getAttributeNS(child, NS, 'href') == resolveToZeroString) {
|
|
550
|
+
// This is a 'resolve to zero' code; it means the element should
|
|
551
|
+
// be removed, as specified by the mpeg-dash rules for xlink.
|
|
552
|
+
element.children = element.children.filter(
|
|
553
|
+
(elem) => elem !== child);
|
|
554
|
+
} else if (child.tagName != 'SegmentTimeline') {
|
|
555
|
+
// Don't recurse into a SegmentTimeline since xlink attributes
|
|
556
|
+
// aren't valid in there and looking at each segment can take a long
|
|
557
|
+
// time with larger manifests.
|
|
558
|
+
|
|
559
|
+
// Replace the child with its processed form.
|
|
560
|
+
childOperations.push(shaka.dash.MpdUtils.processXlinks(
|
|
561
|
+
/** @type {!shaka.extern.xml.Node} */ (child),
|
|
562
|
+
retryParameters, failGracefully,
|
|
563
|
+
baseUri, networkingEngine, linkDepth));
|
|
557
564
|
}
|
|
558
565
|
}
|
|
559
566
|
|
package/lib/dash/segment_base.js
CHANGED
|
@@ -16,7 +16,8 @@ goog.require('shaka.media.WebmSegmentIndexParser');
|
|
|
16
16
|
goog.require('shaka.util.Error');
|
|
17
17
|
goog.require('shaka.util.ManifestParserUtils');
|
|
18
18
|
goog.require('shaka.util.ObjectUtils');
|
|
19
|
-
goog.require('shaka.util.
|
|
19
|
+
goog.require('shaka.util.StringUtils');
|
|
20
|
+
goog.require('shaka.util.TXml');
|
|
20
21
|
goog.requireType('shaka.dash.DashParser');
|
|
21
22
|
goog.requireType('shaka.media.PresentationTimeline');
|
|
22
23
|
goog.requireType('shaka.media.SegmentReference');
|
|
@@ -30,14 +31,16 @@ shaka.dash.SegmentBase = class {
|
|
|
30
31
|
* Creates an init segment reference from a Context object.
|
|
31
32
|
*
|
|
32
33
|
* @param {shaka.dash.DashParser.Context} context
|
|
33
|
-
* @param {function(?shaka.dash.DashParser.InheritanceFrame):
|
|
34
|
-
*
|
|
34
|
+
* @param {function(?shaka.dash.DashParser.InheritanceFrame):
|
|
35
|
+
* ?shaka.extern.xml.Node} callback
|
|
36
|
+
* @param {shaka.extern.aesKey|undefined} aesKey
|
|
35
37
|
* @return {shaka.media.InitSegmentReference}
|
|
36
38
|
*/
|
|
37
|
-
static createInitSegment(context, callback,
|
|
39
|
+
static createInitSegment(context, callback, aesKey) {
|
|
38
40
|
const MpdUtils = shaka.dash.MpdUtils;
|
|
39
|
-
const
|
|
41
|
+
const TXml = shaka.util.TXml;
|
|
40
42
|
const ManifestParserUtils = shaka.util.ManifestParserUtils;
|
|
43
|
+
const StringUtils = shaka.util.StringUtils;
|
|
41
44
|
|
|
42
45
|
const initialization =
|
|
43
46
|
MpdUtils.inheritChild(context, callback, 'Initialization');
|
|
@@ -46,15 +49,16 @@ shaka.dash.SegmentBase = class {
|
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
let resolvedUris = context.representation.getBaseUris();
|
|
49
|
-
const uri = initialization.
|
|
52
|
+
const uri = initialization.attributes['sourceURL'];
|
|
50
53
|
if (uri) {
|
|
51
|
-
resolvedUris = ManifestParserUtils.resolveUris(resolvedUris, [
|
|
54
|
+
resolvedUris = ManifestParserUtils.resolveUris(resolvedUris, [
|
|
55
|
+
StringUtils.htmlUnescape(uri),
|
|
56
|
+
]);
|
|
52
57
|
}
|
|
53
58
|
|
|
54
59
|
let startByte = 0;
|
|
55
60
|
let endByte = null;
|
|
56
|
-
const range =
|
|
57
|
-
XmlUtils.parseAttr(initialization, 'range', XmlUtils.parseRange);
|
|
61
|
+
const range = TXml.parseAttr(initialization, 'range', TXml.parseRange);
|
|
58
62
|
if (range) {
|
|
59
63
|
startByte = range.start;
|
|
60
64
|
endByte = range.end;
|
|
@@ -69,7 +73,7 @@ shaka.dash.SegmentBase = class {
|
|
|
69
73
|
qualityInfo,
|
|
70
74
|
/* timescale= */ null,
|
|
71
75
|
/* segmentData= */ null,
|
|
72
|
-
|
|
76
|
+
aesKey);
|
|
73
77
|
ref.codecs = context.representation.codecs;
|
|
74
78
|
ref.mimeType = context.representation.mimeType;
|
|
75
79
|
return ref;
|
|
@@ -80,17 +84,17 @@ shaka.dash.SegmentBase = class {
|
|
|
80
84
|
*
|
|
81
85
|
* @param {shaka.dash.DashParser.Context} context
|
|
82
86
|
* @param {shaka.dash.DashParser.RequestSegmentCallback} requestSegment
|
|
83
|
-
* @param {shaka.extern.
|
|
87
|
+
* @param {shaka.extern.aesKey|undefined} aesKey
|
|
84
88
|
* @return {shaka.dash.DashParser.StreamInfo}
|
|
85
89
|
*/
|
|
86
|
-
static createStreamInfo(context, requestSegment,
|
|
90
|
+
static createStreamInfo(context, requestSegment, aesKey) {
|
|
87
91
|
goog.asserts.assert(context.representation.segmentBase,
|
|
88
92
|
'Should only be called with SegmentBase');
|
|
89
93
|
// Since SegmentBase does not need updates, simply treat any call as
|
|
90
94
|
// the initial parse.
|
|
91
95
|
const MpdUtils = shaka.dash.MpdUtils;
|
|
92
96
|
const SegmentBase = shaka.dash.SegmentBase;
|
|
93
|
-
const
|
|
97
|
+
const TXml = shaka.util.TXml;
|
|
94
98
|
|
|
95
99
|
const unscaledPresentationTimeOffset = Number(MpdUtils.inheritAttribute(
|
|
96
100
|
context, SegmentBase.fromInheritance_, 'presentationTimeOffset')) || 0;
|
|
@@ -99,14 +103,14 @@ shaka.dash.SegmentBase = class {
|
|
|
99
103
|
context, SegmentBase.fromInheritance_, 'timescale');
|
|
100
104
|
let timescale = 1;
|
|
101
105
|
if (timescaleStr) {
|
|
102
|
-
timescale =
|
|
106
|
+
timescale = TXml.parsePositiveInt(timescaleStr) || 1;
|
|
103
107
|
}
|
|
104
108
|
|
|
105
109
|
const scaledPresentationTimeOffset =
|
|
106
110
|
(unscaledPresentationTimeOffset / timescale) || 0;
|
|
107
111
|
|
|
108
112
|
const initSegmentReference = SegmentBase.createInitSegment(
|
|
109
|
-
context, SegmentBase.fromInheritance_,
|
|
113
|
+
context, SegmentBase.fromInheritance_, aesKey);
|
|
110
114
|
|
|
111
115
|
// Throws an immediate error if the format is unsupported.
|
|
112
116
|
SegmentBase.checkSegmentIndexRangeSupport_(context, initSegmentReference);
|
|
@@ -208,7 +212,7 @@ shaka.dash.SegmentBase = class {
|
|
|
208
212
|
|
|
209
213
|
/**
|
|
210
214
|
* @param {?shaka.dash.DashParser.InheritanceFrame} frame
|
|
211
|
-
* @return {
|
|
215
|
+
* @return {?shaka.extern.xml.Node}
|
|
212
216
|
* @private
|
|
213
217
|
*/
|
|
214
218
|
static fromInheritance_(frame) {
|
|
@@ -225,17 +229,17 @@ shaka.dash.SegmentBase = class {
|
|
|
225
229
|
static computeIndexRange_(context) {
|
|
226
230
|
const MpdUtils = shaka.dash.MpdUtils;
|
|
227
231
|
const SegmentBase = shaka.dash.SegmentBase;
|
|
228
|
-
const
|
|
232
|
+
const TXml = shaka.util.TXml;
|
|
229
233
|
|
|
230
234
|
const representationIndex = MpdUtils.inheritChild(
|
|
231
235
|
context, SegmentBase.fromInheritance_, 'RepresentationIndex');
|
|
232
236
|
const indexRangeElem = MpdUtils.inheritAttribute(
|
|
233
237
|
context, SegmentBase.fromInheritance_, 'indexRange');
|
|
234
238
|
|
|
235
|
-
let indexRange =
|
|
239
|
+
let indexRange = TXml.parseRange(indexRangeElem || '');
|
|
236
240
|
if (representationIndex) {
|
|
237
|
-
indexRange =
|
|
238
|
-
representationIndex, 'range',
|
|
241
|
+
indexRange = TXml.parseAttr(
|
|
242
|
+
representationIndex, 'range', TXml.parseRange, indexRange);
|
|
239
243
|
}
|
|
240
244
|
return indexRange;
|
|
241
245
|
}
|
|
@@ -251,13 +255,15 @@ shaka.dash.SegmentBase = class {
|
|
|
251
255
|
const ManifestParserUtils = shaka.util.ManifestParserUtils;
|
|
252
256
|
const MpdUtils = shaka.dash.MpdUtils;
|
|
253
257
|
const SegmentBase = shaka.dash.SegmentBase;
|
|
258
|
+
const StringUtils = shaka.util.StringUtils;
|
|
254
259
|
|
|
255
260
|
const representationIndex = MpdUtils.inheritChild(
|
|
256
261
|
context, SegmentBase.fromInheritance_, 'RepresentationIndex');
|
|
257
262
|
|
|
258
263
|
let indexUris = context.representation.getBaseUris();
|
|
259
264
|
if (representationIndex) {
|
|
260
|
-
const representationUri =
|
|
265
|
+
const representationUri =
|
|
266
|
+
StringUtils.htmlUnescape(representationIndex.attributes['sourceURL']);
|
|
261
267
|
if (representationUri) {
|
|
262
268
|
indexUris = ManifestParserUtils.resolveUris(
|
|
263
269
|
indexUris, [representationUri]);
|
package/lib/dash/segment_list.js
CHANGED
|
@@ -16,7 +16,8 @@ goog.require('shaka.media.SegmentReference');
|
|
|
16
16
|
goog.require('shaka.util.Error');
|
|
17
17
|
goog.require('shaka.util.Functional');
|
|
18
18
|
goog.require('shaka.util.ManifestParserUtils');
|
|
19
|
-
goog.require('shaka.util.
|
|
19
|
+
goog.require('shaka.util.StringUtils');
|
|
20
|
+
goog.require('shaka.util.TXml');
|
|
20
21
|
goog.requireType('shaka.dash.DashParser');
|
|
21
22
|
goog.requireType('shaka.media.PresentationTimeline');
|
|
22
23
|
|
|
@@ -31,16 +32,16 @@ shaka.dash.SegmentList = class {
|
|
|
31
32
|
*
|
|
32
33
|
* @param {shaka.dash.DashParser.Context} context
|
|
33
34
|
* @param {!Object.<string, !shaka.extern.Stream>} streamMap
|
|
34
|
-
* @param {shaka.extern.
|
|
35
|
+
* @param {shaka.extern.aesKey|undefined} aesKey
|
|
35
36
|
* @return {shaka.dash.DashParser.StreamInfo}
|
|
36
37
|
*/
|
|
37
|
-
static createStreamInfo(context, streamMap,
|
|
38
|
+
static createStreamInfo(context, streamMap, aesKey) {
|
|
38
39
|
goog.asserts.assert(context.representation.segmentList,
|
|
39
40
|
'Should only be called with SegmentList');
|
|
40
41
|
const SegmentList = shaka.dash.SegmentList;
|
|
41
42
|
|
|
42
43
|
const initSegmentReference = shaka.dash.SegmentBase.createInitSegment(
|
|
43
|
-
context, SegmentList.fromInheritance_,
|
|
44
|
+
context, SegmentList.fromInheritance_, aesKey);
|
|
44
45
|
const info = SegmentList.parseSegmentListInfo_(context);
|
|
45
46
|
|
|
46
47
|
SegmentList.checkSegmentListInfo_(context, info);
|
|
@@ -60,7 +61,7 @@ shaka.dash.SegmentList = class {
|
|
|
60
61
|
const references = SegmentList.createSegmentReferences_(
|
|
61
62
|
context.periodInfo.start, context.periodInfo.duration,
|
|
62
63
|
info.startNumber, context.representation.getBaseUris, info,
|
|
63
|
-
initSegmentReference,
|
|
64
|
+
initSegmentReference, aesKey, context.representation.mimeType,
|
|
64
65
|
context.representation.codecs);
|
|
65
66
|
|
|
66
67
|
const isNew = !segmentIndex;
|
|
@@ -95,7 +96,7 @@ shaka.dash.SegmentList = class {
|
|
|
95
96
|
|
|
96
97
|
/**
|
|
97
98
|
* @param {?shaka.dash.DashParser.InheritanceFrame} frame
|
|
98
|
-
* @return {
|
|
99
|
+
* @return {?shaka.extern.xml.Node}
|
|
99
100
|
* @private
|
|
100
101
|
*/
|
|
101
102
|
static fromInheritance_(frame) {
|
|
@@ -199,7 +200,7 @@ shaka.dash.SegmentList = class {
|
|
|
199
200
|
* @param {function():!Array.<string>} getBaseUris
|
|
200
201
|
* @param {shaka.dash.SegmentList.SegmentListInfo} info
|
|
201
202
|
* @param {shaka.media.InitSegmentReference} initSegmentReference
|
|
202
|
-
* @param {shaka.extern.
|
|
203
|
+
* @param {shaka.extern.aesKey|undefined} aesKey
|
|
203
204
|
* @param {string} mimeType
|
|
204
205
|
* @param {string} codecs
|
|
205
206
|
* @return {!Array.<!shaka.media.SegmentReference>}
|
|
@@ -207,7 +208,7 @@ shaka.dash.SegmentList = class {
|
|
|
207
208
|
*/
|
|
208
209
|
static createSegmentReferences_(
|
|
209
210
|
periodStart, periodDuration, startNumber, getBaseUris, info,
|
|
210
|
-
initSegmentReference,
|
|
211
|
+
initSegmentReference, aesKey, mimeType, codecs) {
|
|
211
212
|
const ManifestParserUtils = shaka.util.ManifestParserUtils;
|
|
212
213
|
|
|
213
214
|
let max = info.mediaSegments.length;
|
|
@@ -269,7 +270,7 @@ shaka.dash.SegmentList = class {
|
|
|
269
270
|
/* tileDuration= */ null,
|
|
270
271
|
/* syncTime= */ null,
|
|
271
272
|
shaka.media.SegmentReference.Status.AVAILABLE,
|
|
272
|
-
|
|
273
|
+
aesKey);
|
|
273
274
|
ref.codecs = codecs;
|
|
274
275
|
ref.mimeType = mimeType;
|
|
275
276
|
references.push(ref);
|
|
@@ -288,21 +289,22 @@ shaka.dash.SegmentList = class {
|
|
|
288
289
|
*/
|
|
289
290
|
static parseMediaSegments_(context) {
|
|
290
291
|
const Functional = shaka.util.Functional;
|
|
291
|
-
/** @type {!Array.<!
|
|
292
|
+
/** @type {!Array.<!shaka.extern.xml.Node>} */
|
|
292
293
|
const segmentLists = [
|
|
293
294
|
context.representation.segmentList,
|
|
294
295
|
context.adaptationSet.segmentList,
|
|
295
296
|
context.period.segmentList,
|
|
296
297
|
].filter(Functional.isNotNull);
|
|
297
298
|
|
|
298
|
-
const
|
|
299
|
+
const TXml = shaka.util.TXml;
|
|
300
|
+
const StringUtils = shaka.util.StringUtils;
|
|
299
301
|
// Search each SegmentList for one with at least one SegmentURL element,
|
|
300
302
|
// select the first one, and convert each SegmentURL element to a tuple.
|
|
301
303
|
return segmentLists
|
|
302
|
-
.map((node) => { return
|
|
304
|
+
.map((node) => { return TXml.findChildren(node, 'SegmentURL'); })
|
|
303
305
|
.reduce((all, part) => { return all.length > 0 ? all : part; })
|
|
304
306
|
.map((urlNode) => {
|
|
305
|
-
if (urlNode.
|
|
307
|
+
if (urlNode.attributes['indexRange'] &&
|
|
306
308
|
!context.indexRangeWarningGiven) {
|
|
307
309
|
context.indexRangeWarningGiven = true;
|
|
308
310
|
shaka.log.warning(
|
|
@@ -311,9 +313,9 @@ shaka.dash.SegmentList = class {
|
|
|
311
313
|
'attribute or SegmentTimeline, which must be accurate.');
|
|
312
314
|
}
|
|
313
315
|
|
|
314
|
-
const uri = urlNode.
|
|
315
|
-
const range =
|
|
316
|
-
urlNode, 'mediaRange',
|
|
316
|
+
const uri = StringUtils.htmlUnescape(urlNode.attributes['media']);
|
|
317
|
+
const range = TXml.parseAttr(
|
|
318
|
+
urlNode, 'mediaRange', TXml.parseRange,
|
|
317
319
|
{start: 0, end: null});
|
|
318
320
|
return {mediaUri: uri, start: range.start, end: range.end};
|
|
319
321
|
});
|