shaka-player 4.10.13 → 4.11.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/README.md +5 -1
- package/dist/controls.css +3 -3
- package/dist/controls.css.map +1 -1
- package/dist/deps.js +11 -11
- package/dist/locales.js +38 -34
- package/dist/shaka-player.compiled.d.ts +68 -33
- package/dist/shaka-player.compiled.debug.d.ts +68 -33
- package/dist/shaka-player.compiled.debug.externs.js +584 -544
- package/dist/shaka-player.compiled.debug.js +715 -676
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +584 -544
- package/dist/shaka-player.compiled.js +1394 -1371
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +76 -34
- package/dist/shaka-player.ui.debug.d.ts +76 -34
- package/dist/shaka-player.ui.debug.externs.js +77 -26
- package/dist/shaka-player.ui.debug.js +774 -720
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +77 -26
- package/dist/shaka-player.ui.js +1649 -1617
- package/dist/shaka-player.ui.map +4 -4
- package/externs/mediasession.js +10 -1
- package/externs/shaka/ads.js +79 -2
- package/externs/shaka/manifest.js +6 -1
- package/externs/shaka/manifest_parser.js +6 -2
- package/externs/shaka/net.js +23 -2
- package/externs/shaka/player.js +414 -103
- package/externs/shaka/text.js +2 -1
- package/lib/abr/simple_abr_manager.js +5 -0
- package/lib/ads/ad_manager.js +45 -1
- package/lib/ads/ad_utils.js +124 -1
- package/lib/ads/interstitial_ad.js +9 -2
- package/lib/ads/interstitial_ad_manager.js +216 -101
- package/lib/ads/media_tailor_ad.js +1 -39
- package/lib/ads/media_tailor_ad_manager.js +32 -16
- package/lib/cea/cea608_data_channel.js +40 -8
- package/lib/cea/cea608_memory.js +28 -0
- package/lib/dash/dash_parser.js +162 -25
- package/lib/dash/segment_base.js +3 -2
- package/lib/dash/segment_list.js +6 -3
- package/lib/dash/segment_template.js +104 -20
- package/lib/hls/hls_parser.js +319 -215
- package/lib/media/drm_engine.js +11 -3
- package/lib/media/media_source_engine.js +0 -8
- package/lib/media/preload_manager.js +16 -4
- package/lib/media/segment_reference.js +3 -0
- package/lib/media/segment_utils.js +8 -1
- package/lib/media/streaming_engine.js +10 -6
- package/lib/mss/mss_parser.js +14 -2
- package/lib/net/http_fetch_plugin.js +12 -5
- package/lib/net/http_xhr_plugin.js +7 -3
- package/lib/net/networking_engine.js +21 -1
- package/lib/offline/manifest_converter.js +1 -0
- package/lib/offline/storage.js +1 -0
- package/lib/player.js +336 -121
- package/lib/text/cue.js +373 -0
- package/lib/text/mp4_ttml_parser.js +51 -1
- package/lib/text/mp4_vtt_parser.js +2 -5
- package/lib/text/sbv_text_parser.js +2 -31
- package/lib/text/srt_text_parser.js +1 -1
- package/lib/text/text_engine.js +1 -1
- package/lib/text/text_utils.js +1 -0
- package/lib/text/ttml_text_parser.js +14 -4
- package/lib/text/ui_text_displayer.js +0 -4
- package/lib/text/vtt_text_parser.js +10 -415
- package/lib/util/abortable_operation.js +8 -0
- package/lib/util/cmcd_manager.js +38 -0
- package/lib/util/error.js +16 -0
- package/lib/util/fake_event.js +1 -0
- package/lib/util/manifest_parser_utils.js +12 -3
- package/lib/util/player_configuration.js +4 -2
- package/lib/util/stream_utils.js +57 -2
- package/lib/util/tXml.js +2 -1
- package/lib/util/text_parser.js +46 -0
- package/lib/util/ts_parser.js +32 -3
- package/package.json +1 -1
- package/shaka-player.uncompiled.js +1 -1
- package/ui/chapter_selection.js +179 -0
- package/ui/controls.js +151 -0
- package/ui/enums.js +1 -0
- package/ui/externs/ui.js +7 -1
- package/ui/less/containers.less +3 -4
- package/ui/less/overflow_menu.less +5 -0
- package/ui/less/tooltip.less +1 -1
- package/ui/locales/en.json +1 -0
- package/ui/locales/es.json +1 -0
- package/ui/locales/fr.json +1 -0
- package/ui/locales/source.json +4 -0
- package/ui/seek_bar.js +3 -2
- package/ui/ui.js +2 -0
- package/lib/polyfill/abort_controller.js +0 -158
|
@@ -123,19 +123,26 @@ shaka.cea.Cea608DataChannel = class {
|
|
|
123
123
|
controlPac_(b1, b2) {
|
|
124
124
|
const row = this.pacToRow_(b1, b2);
|
|
125
125
|
|
|
126
|
-
// Get attribute bits (4 bits)
|
|
127
|
-
const attr = (b2 & 0x1E) >> 1;
|
|
128
|
-
|
|
129
126
|
// Set up the defaults.
|
|
130
127
|
let textColor = shaka.cea.CeaUtils.DEFAULT_TXT_COLOR;
|
|
131
128
|
let italics = false;
|
|
129
|
+
let indent = null;
|
|
130
|
+
|
|
131
|
+
// Get PAC index;
|
|
132
|
+
let pacIndex;
|
|
133
|
+
if (b2 > 0x5f) {
|
|
134
|
+
pacIndex = b2 - 0x60;
|
|
135
|
+
} else {
|
|
136
|
+
pacIndex = b2 - 0x40;
|
|
137
|
+
}
|
|
132
138
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
} else if (attr === 7) {
|
|
139
|
+
if (pacIndex <= 0xd) {
|
|
140
|
+
const colorIndex = Math.floor(pacIndex / 2);
|
|
141
|
+
textColor = shaka.cea.Cea608DataChannel.TEXT_COLORS[colorIndex];
|
|
142
|
+
} else if (pacIndex <= 0xf) {
|
|
138
143
|
italics = true; // color stays white
|
|
144
|
+
} else {
|
|
145
|
+
indent = Math.floor((pacIndex - 0x10) / 2);
|
|
139
146
|
}
|
|
140
147
|
|
|
141
148
|
// PACs toggle underline on the last bit of b2.
|
|
@@ -168,6 +175,7 @@ shaka.cea.Cea608DataChannel = class {
|
|
|
168
175
|
buf.setUnderline(underline);
|
|
169
176
|
buf.setItalics(italics);
|
|
170
177
|
buf.setTextColor(textColor);
|
|
178
|
+
buf.setIndent(indent);
|
|
171
179
|
|
|
172
180
|
// Clear the background color, since new row (PAC) should reset ALL styles.
|
|
173
181
|
buf.setBackgroundColor(shaka.cea.CeaUtils.DEFAULT_BG_COLOR);
|
|
@@ -507,6 +515,16 @@ shaka.cea.Cea608DataChannel = class {
|
|
|
507
515
|
this.curbuf_.addChar(charSet, b2);
|
|
508
516
|
}
|
|
509
517
|
|
|
518
|
+
/**
|
|
519
|
+
* Handles a tab offset.
|
|
520
|
+
*
|
|
521
|
+
* @param {number} offset
|
|
522
|
+
* @private
|
|
523
|
+
*/
|
|
524
|
+
handleOffset_(offset) {
|
|
525
|
+
this.curbuf_.setOffset(offset);
|
|
526
|
+
}
|
|
527
|
+
|
|
510
528
|
/**
|
|
511
529
|
* Decodes control code.
|
|
512
530
|
* Three types of control codes:
|
|
@@ -543,6 +561,9 @@ shaka.cea.Cea608DataChannel = class {
|
|
|
543
561
|
this.handleExtendedWesternEuropeanChar_(b1, b2);
|
|
544
562
|
} else if (this.isMiscellaneous_(b1, b2)) {
|
|
545
563
|
return this.controlMiscellaneous_(ccPacket);
|
|
564
|
+
} else if (this.isOffset_(b1, b2)) {
|
|
565
|
+
const offset = b2 - 0x20;
|
|
566
|
+
this.handleOffset_(offset);
|
|
546
567
|
}
|
|
547
568
|
return null;
|
|
548
569
|
}
|
|
@@ -561,6 +582,17 @@ shaka.cea.Cea608DataChannel = class {
|
|
|
561
582
|
return ((b1 & 0xf6) === 0x14) && ((b2 & 0xf0) === 0x20);
|
|
562
583
|
}
|
|
563
584
|
|
|
585
|
+
/**
|
|
586
|
+
* Checks if this is a offset control code.
|
|
587
|
+
* @param {number} b1 Byte 1.
|
|
588
|
+
* @param {number} b2 Byte 2.
|
|
589
|
+
* @return {boolean}
|
|
590
|
+
* @private
|
|
591
|
+
*/
|
|
592
|
+
isOffset_(b1, b2) {
|
|
593
|
+
return (b1 == 0x17 || b1 == 0x1f) && b2 >= 0x21 && b2 <= 0x23;
|
|
594
|
+
}
|
|
595
|
+
|
|
564
596
|
/**
|
|
565
597
|
* Checks if this is a PAC control code.
|
|
566
598
|
* @param {number} b1 Byte 1.
|
package/lib/cea/cea608_memory.js
CHANGED
|
@@ -69,6 +69,16 @@ shaka.cea.Cea608Memory = class {
|
|
|
69
69
|
*/
|
|
70
70
|
this.backgroundColor_ = shaka.cea.CeaUtils.DEFAULT_BG_COLOR;
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* @private {?number}
|
|
74
|
+
*/
|
|
75
|
+
this.offset_ = null;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @private {?number}
|
|
79
|
+
*/
|
|
80
|
+
this.indent_ = null;
|
|
81
|
+
|
|
72
82
|
this.reset();
|
|
73
83
|
}
|
|
74
84
|
|
|
@@ -89,6 +99,10 @@ shaka.cea.Cea608Memory = class {
|
|
|
89
99
|
if (line) {
|
|
90
100
|
topLevelCue.line = line;
|
|
91
101
|
}
|
|
102
|
+
if (this.indent_ != null && this.offset_ != null) {
|
|
103
|
+
topLevelCue.position = 10 + Math.min(70, this.indent_ * 10) +
|
|
104
|
+
this.offset_ * 2.5;
|
|
105
|
+
}
|
|
92
106
|
const ret = shaka.cea.CeaUtils.getParsedCaption(
|
|
93
107
|
topLevelCue, stream, this.rows_, startTime, endTime);
|
|
94
108
|
// If the text and its lines are larger than what we can show on the
|
|
@@ -270,6 +284,20 @@ shaka.cea.Cea608Memory = class {
|
|
|
270
284
|
setBackgroundColor(color) {
|
|
271
285
|
this.backgroundColor_ = color;
|
|
272
286
|
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* @param {number} offset
|
|
290
|
+
*/
|
|
291
|
+
setOffset(offset) {
|
|
292
|
+
this.offset_ = offset;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* @param {?number} indent
|
|
297
|
+
*/
|
|
298
|
+
setIndent(indent) {
|
|
299
|
+
this.indent_ = indent;
|
|
300
|
+
}
|
|
273
301
|
};
|
|
274
302
|
|
|
275
303
|
/**
|
package/lib/dash/dash_parser.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
goog.provide('shaka.dash.DashParser');
|
|
8
8
|
|
|
9
9
|
goog.require('goog.asserts');
|
|
10
|
+
goog.require('goog.Uri');
|
|
10
11
|
goog.require('shaka.Deprecate');
|
|
11
12
|
goog.require('shaka.abr.Ewma');
|
|
12
13
|
goog.require('shaka.dash.ContentProtection');
|
|
@@ -34,6 +35,7 @@ goog.require('shaka.util.ObjectUtils');
|
|
|
34
35
|
goog.require('shaka.util.OperationManager');
|
|
35
36
|
goog.require('shaka.util.PeriodCombiner');
|
|
36
37
|
goog.require('shaka.util.PlayerConfiguration');
|
|
38
|
+
goog.require('shaka.util.StreamUtils');
|
|
37
39
|
goog.require('shaka.util.StringUtils');
|
|
38
40
|
goog.require('shaka.util.Timer');
|
|
39
41
|
goog.require('shaka.util.TXml');
|
|
@@ -184,19 +186,30 @@ shaka.dash.DashParser = class {
|
|
|
184
186
|
|
|
185
187
|
/** @private {boolean} */
|
|
186
188
|
this.isTransitionFromDynamicToStatic_ = false;
|
|
189
|
+
|
|
190
|
+
/** @private {string} */
|
|
191
|
+
this.lastManifestQueryParams_ = '';
|
|
192
|
+
|
|
193
|
+
/** @private {function():boolean} */
|
|
194
|
+
this.isPreloadFn_ = () => false;
|
|
187
195
|
}
|
|
188
196
|
|
|
189
197
|
/**
|
|
198
|
+
* @param {shaka.extern.ManifestConfiguration} config
|
|
199
|
+
* @param {(function():boolean)=} isPreloadFn
|
|
190
200
|
* @override
|
|
191
201
|
* @exportInterface
|
|
192
202
|
*/
|
|
193
|
-
configure(config) {
|
|
203
|
+
configure(config, isPreloadFn) {
|
|
194
204
|
goog.asserts.assert(config.dash != null,
|
|
195
205
|
'DashManifestConfiguration should not be null!');
|
|
196
206
|
const needFireUpdate = this.playerInterface_ &&
|
|
197
207
|
config.dash.updatePeriod != this.config_.dash.updatePeriod &&
|
|
198
208
|
config.dash.updatePeriod >= 0;
|
|
199
209
|
this.config_ = config;
|
|
210
|
+
if (isPreloadFn) {
|
|
211
|
+
this.isPreloadFn_ = isPreloadFn;
|
|
212
|
+
}
|
|
200
213
|
if (needFireUpdate && this.manifest_ &&
|
|
201
214
|
this.manifest_.presentationTimeline.isLive()) {
|
|
202
215
|
this.updateNow_();
|
|
@@ -406,6 +419,9 @@ shaka.dash.DashParser = class {
|
|
|
406
419
|
this.manifestUris_.unshift(response.uri);
|
|
407
420
|
}
|
|
408
421
|
|
|
422
|
+
const uriObj = new goog.Uri(response.uri);
|
|
423
|
+
this.lastManifestQueryParams_ = uriObj.getQueryData().toString();
|
|
424
|
+
|
|
409
425
|
// This may throw, but it will result in a failed promise.
|
|
410
426
|
await this.parseManifest_(response.data, response.uri, rootElement);
|
|
411
427
|
// Keep track of how long the longest manifest update took.
|
|
@@ -740,6 +756,7 @@ shaka.dash.DashParser = class {
|
|
|
740
756
|
mediaPresentationDuration: null,
|
|
741
757
|
profiles: profiles.split(','),
|
|
742
758
|
roles: null,
|
|
759
|
+
urlParams: () => '',
|
|
743
760
|
};
|
|
744
761
|
|
|
745
762
|
this.gapCount_ = 0;
|
|
@@ -808,6 +825,7 @@ shaka.dash.DashParser = class {
|
|
|
808
825
|
periodCount: periods.length,
|
|
809
826
|
gapCount: this.gapCount_,
|
|
810
827
|
isLowLatency: this.isLowLatency_,
|
|
828
|
+
startTime: null,
|
|
811
829
|
};
|
|
812
830
|
|
|
813
831
|
// We only need to do clock sync when we're using presentation start
|
|
@@ -1020,6 +1038,7 @@ shaka.dash.DashParser = class {
|
|
|
1020
1038
|
mediaPresentationDuration:
|
|
1021
1039
|
this.manifestPatchContext_.mediaPresentationDuration,
|
|
1022
1040
|
roles: null,
|
|
1041
|
+
urlParams: () => '',
|
|
1023
1042
|
};
|
|
1024
1043
|
|
|
1025
1044
|
const periodsAndDuration = this.parsePeriods_(context,
|
|
@@ -1526,6 +1545,19 @@ shaka.dash.DashParser = class {
|
|
|
1526
1545
|
periodInfo.start, periodInfo.duration, node, availabilityStart);
|
|
1527
1546
|
}
|
|
1528
1547
|
|
|
1548
|
+
|
|
1549
|
+
const supplementalProperties =
|
|
1550
|
+
TXml.findChildren(periodInfo.node, 'SupplementalProperty');
|
|
1551
|
+
for (const prop of supplementalProperties) {
|
|
1552
|
+
const schemeId = prop.attributes['schemeIdUri'];
|
|
1553
|
+
if (schemeId == 'urn:mpeg:dash:urlparam:2014') {
|
|
1554
|
+
const urlParams = this.getURLParametersFunction_(prop);
|
|
1555
|
+
if (urlParams) {
|
|
1556
|
+
context.urlParams = urlParams;
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1529
1561
|
const adaptationSetNodes =
|
|
1530
1562
|
TXml.findChildren(periodInfo.node, 'AdaptationSet');
|
|
1531
1563
|
const adaptationSets = adaptationSetNodes
|
|
@@ -1565,12 +1597,8 @@ shaka.dash.DashParser = class {
|
|
|
1565
1597
|
for (const normalSet of normalAdaptationSets) {
|
|
1566
1598
|
if (targetIds.includes(normalSet.id)) {
|
|
1567
1599
|
for (const stream of normalSet.streams) {
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
// TODO: https://github.com/shaka-project/shaka-player/issues/1528
|
|
1571
|
-
stream.trickModeVideo = trickModeSet.streams.find((trickStream) =>
|
|
1572
|
-
shaka.util.MimeUtils.getNormalizedCodec(stream.codecs) ==
|
|
1573
|
-
shaka.util.MimeUtils.getNormalizedCodec(trickStream.codecs));
|
|
1600
|
+
shaka.util.StreamUtils.setBetterIFrameStream(
|
|
1601
|
+
stream, trickModeSet.streams);
|
|
1574
1602
|
}
|
|
1575
1603
|
}
|
|
1576
1604
|
}
|
|
@@ -1734,11 +1762,23 @@ shaka.dash.DashParser = class {
|
|
|
1734
1762
|
return undefined;
|
|
1735
1763
|
};
|
|
1736
1764
|
|
|
1765
|
+
const parseFont = (prop) => {
|
|
1766
|
+
const fontFamily = prop.attributes['dvb:fontFamily'];
|
|
1767
|
+
const fontUrl = prop.attributes['dvb:url'];
|
|
1768
|
+
if (fontFamily && fontUrl) {
|
|
1769
|
+
const uris = shaka.util.ManifestParserUtils.resolveUris(
|
|
1770
|
+
context.adaptationSet.getBaseUris(), [fontUrl],
|
|
1771
|
+
context.urlParams());
|
|
1772
|
+
this.playerInterface_.addFont(fontFamily, uris[0]);
|
|
1773
|
+
}
|
|
1774
|
+
};
|
|
1775
|
+
|
|
1737
1776
|
const essentialProperties =
|
|
1738
1777
|
TXml.findChildren(elem, 'EssentialProperty');
|
|
1739
1778
|
// ID of real AdaptationSet if this is a trick mode set:
|
|
1740
1779
|
let trickModeFor = null;
|
|
1741
1780
|
let isFastSwitching = false;
|
|
1781
|
+
let adaptationSetUrlParams = null;
|
|
1742
1782
|
let unrecognizedEssentialProperty = false;
|
|
1743
1783
|
for (const prop of essentialProperties) {
|
|
1744
1784
|
const schemeId = prop.attributes['schemeIdUri'];
|
|
@@ -1757,11 +1797,29 @@ shaka.dash.DashParser = class {
|
|
|
1757
1797
|
} else if (schemeId == 'urn:mpeg:dash:ssr:2023' &&
|
|
1758
1798
|
this.config_.dash.enableFastSwitching) {
|
|
1759
1799
|
isFastSwitching = true;
|
|
1800
|
+
} else if (schemeId == 'urn:dvb:dash:fontdownload:2014') {
|
|
1801
|
+
parseFont(prop);
|
|
1802
|
+
} else if (schemeId == 'urn:mpeg:dash:urlparam:2014') {
|
|
1803
|
+
adaptationSetUrlParams = this.getURLParametersFunction_(prop);
|
|
1804
|
+
if (!adaptationSetUrlParams) {
|
|
1805
|
+
unrecognizedEssentialProperty = true;
|
|
1806
|
+
}
|
|
1760
1807
|
} else {
|
|
1761
1808
|
unrecognizedEssentialProperty = true;
|
|
1762
1809
|
}
|
|
1763
1810
|
}
|
|
1764
1811
|
|
|
1812
|
+
// According to DASH spec (2014) section 5.8.4.8, "the successful processing
|
|
1813
|
+
// of the descriptor is essential to properly use the information in the
|
|
1814
|
+
// parent element". According to DASH IOP v3.3, section 3.3.4, "if the
|
|
1815
|
+
// scheme or the value" for EssentialProperty is not recognized, "the DASH
|
|
1816
|
+
// client shall ignore the parent element."
|
|
1817
|
+
if (unrecognizedEssentialProperty) {
|
|
1818
|
+
// Stop parsing this AdaptationSet and let the caller filter out the
|
|
1819
|
+
// nulls.
|
|
1820
|
+
return null;
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1765
1823
|
let lastSegmentNumber = null;
|
|
1766
1824
|
|
|
1767
1825
|
const supplementalProperties =
|
|
@@ -1778,9 +1836,17 @@ shaka.dash.DashParser = class {
|
|
|
1778
1836
|
colorGamut = getColorGamutFromColourPrimariesCICP(
|
|
1779
1837
|
parseInt(prop.attributes['value'], 10),
|
|
1780
1838
|
);
|
|
1839
|
+
} else if (schemeId == 'urn:dvb:dash:fontdownload:2014') {
|
|
1840
|
+
parseFont(prop);
|
|
1841
|
+
} else if (schemeId == 'urn:mpeg:dash:urlparam:2014') {
|
|
1842
|
+
adaptationSetUrlParams = this.getURLParametersFunction_(prop);
|
|
1781
1843
|
}
|
|
1782
1844
|
}
|
|
1783
1845
|
|
|
1846
|
+
if (adaptationSetUrlParams) {
|
|
1847
|
+
context.urlParams = adaptationSetUrlParams;
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1784
1850
|
const accessibilities = TXml.findChildren(elem, 'Accessibility');
|
|
1785
1851
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
1786
1852
|
const closedCaptions = new Map();
|
|
@@ -1882,17 +1948,6 @@ shaka.dash.DashParser = class {
|
|
|
1882
1948
|
}
|
|
1883
1949
|
}
|
|
1884
1950
|
|
|
1885
|
-
// According to DASH spec (2014) section 5.8.4.8, "the successful processing
|
|
1886
|
-
// of the descriptor is essential to properly use the information in the
|
|
1887
|
-
// parent element". According to DASH IOP v3.3, section 3.3.4, "if the
|
|
1888
|
-
// scheme or the value" for EssentialProperty is not recognized, "the DASH
|
|
1889
|
-
// client shall ignore the parent element."
|
|
1890
|
-
if (unrecognizedEssentialProperty) {
|
|
1891
|
-
// Stop parsing this AdaptationSet and let the caller filter out the
|
|
1892
|
-
// nulls.
|
|
1893
|
-
return null;
|
|
1894
|
-
}
|
|
1895
|
-
|
|
1896
1951
|
const contentProtectionElems =
|
|
1897
1952
|
TXml.findChildren(elem, 'ContentProtection');
|
|
1898
1953
|
const contentProtection = ContentProtection.parseFromAdaptationSet(
|
|
@@ -1984,6 +2039,48 @@ shaka.dash.DashParser = class {
|
|
|
1984
2039
|
};
|
|
1985
2040
|
}
|
|
1986
2041
|
|
|
2042
|
+
/**
|
|
2043
|
+
* @param {!shaka.extern.xml.Node} elem
|
|
2044
|
+
* @return {?function():string}
|
|
2045
|
+
* @private
|
|
2046
|
+
*/
|
|
2047
|
+
getURLParametersFunction_(elem) {
|
|
2048
|
+
const TXml = shaka.util.TXml;
|
|
2049
|
+
const urlQueryInfo = TXml.findChildNS(
|
|
2050
|
+
elem, shaka.dash.DashParser.UP_NAMESPACE_, 'UrlQueryInfo');
|
|
2051
|
+
if (urlQueryInfo && TXml.parseAttr(urlQueryInfo, 'useMPDUrlQuery',
|
|
2052
|
+
TXml.parseBoolean, /* defaultValue= */ false)) {
|
|
2053
|
+
const queryTemplate = urlQueryInfo.attributes['queryTemplate'];
|
|
2054
|
+
if (queryTemplate) {
|
|
2055
|
+
return () => {
|
|
2056
|
+
if (queryTemplate == '$querypart$') {
|
|
2057
|
+
return this.lastManifestQueryParams_;
|
|
2058
|
+
}
|
|
2059
|
+
const parameters = queryTemplate.split('&').map((param) => {
|
|
2060
|
+
if (param == '$querypart$') {
|
|
2061
|
+
return this.lastManifestQueryParams_;
|
|
2062
|
+
} else {
|
|
2063
|
+
const regex = /\$query:(.*?)\$/g;
|
|
2064
|
+
const parts = regex.exec(param);
|
|
2065
|
+
if (parts && parts.length == 2) {
|
|
2066
|
+
const paramName = parts[1];
|
|
2067
|
+
const queryData =
|
|
2068
|
+
new goog.Uri.QueryData(this.lastManifestQueryParams_);
|
|
2069
|
+
const value = queryData.get(paramName);
|
|
2070
|
+
if (value.length) {
|
|
2071
|
+
return paramName + '=' + value[0];
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
return param;
|
|
2075
|
+
}
|
|
2076
|
+
});
|
|
2077
|
+
return parameters.join('&');
|
|
2078
|
+
};
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
return null;
|
|
2082
|
+
}
|
|
2083
|
+
|
|
1987
2084
|
/**
|
|
1988
2085
|
* Parses a Representation XML element.
|
|
1989
2086
|
*
|
|
@@ -2037,6 +2134,34 @@ shaka.dash.DashParser = class {
|
|
|
2037
2134
|
|
|
2038
2135
|
context.roles = roles;
|
|
2039
2136
|
|
|
2137
|
+
const supplementalPropertyElems =
|
|
2138
|
+
TXml.findChildren(node, 'SupplementalProperty');
|
|
2139
|
+
const essentialPropertyElems =
|
|
2140
|
+
TXml.findChildren(node, 'EssentialProperty');
|
|
2141
|
+
|
|
2142
|
+
let representationUrlParams = null;
|
|
2143
|
+
let urlParamsElement = essentialPropertyElems.find((element) => {
|
|
2144
|
+
const schemeId = element.attributes['schemeIdUri'];
|
|
2145
|
+
return schemeId == 'urn:mpeg:dash:urlparam:2014';
|
|
2146
|
+
});
|
|
2147
|
+
if (urlParamsElement) {
|
|
2148
|
+
representationUrlParams =
|
|
2149
|
+
this.getURLParametersFunction_(urlParamsElement);
|
|
2150
|
+
} else {
|
|
2151
|
+
urlParamsElement = supplementalPropertyElems.find((element) => {
|
|
2152
|
+
const schemeId = element.attributes['schemeIdUri'];
|
|
2153
|
+
return schemeId == 'urn:mpeg:dash:urlparam:2014';
|
|
2154
|
+
});
|
|
2155
|
+
if (urlParamsElement) {
|
|
2156
|
+
representationUrlParams =
|
|
2157
|
+
this.getURLParametersFunction_(urlParamsElement);
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
if (representationUrlParams) {
|
|
2162
|
+
context.urlParams = representationUrlParams;
|
|
2163
|
+
}
|
|
2164
|
+
|
|
2040
2165
|
/** @type {?shaka.dash.DashParser.StreamInfo} */
|
|
2041
2166
|
let streamInfo;
|
|
2042
2167
|
|
|
@@ -2050,8 +2175,9 @@ shaka.dash.DashParser = class {
|
|
|
2050
2175
|
let aesKey = undefined;
|
|
2051
2176
|
if (contentProtection.aes128Info) {
|
|
2052
2177
|
const getBaseUris = context.representation.getBaseUris;
|
|
2178
|
+
const urlParams = context.urlParams;
|
|
2053
2179
|
const uris = shaka.util.ManifestParserUtils.resolveUris(
|
|
2054
|
-
getBaseUris(), [contentProtection.aes128Info.keyUri]);
|
|
2180
|
+
getBaseUris(), [contentProtection.aes128Info.keyUri], urlParams());
|
|
2055
2181
|
const requestType = shaka.net.NetworkingEngine.RequestType.KEY;
|
|
2056
2182
|
const request = shaka.net.NetworkingEngine.makeRequest(
|
|
2057
2183
|
uris, this.config_.retryParameters);
|
|
@@ -2146,8 +2272,6 @@ shaka.dash.DashParser = class {
|
|
|
2146
2272
|
|
|
2147
2273
|
// Detect the presence of E-AC3 JOC audio content, using DD+JOC signaling.
|
|
2148
2274
|
// See: ETSI TS 103 420 V1.2.1 (2018-10)
|
|
2149
|
-
const supplementalPropertyElems =
|
|
2150
|
-
TXml.findChildren(node, 'SupplementalProperty');
|
|
2151
2275
|
const hasJoc = supplementalPropertyElems.some((element) => {
|
|
2152
2276
|
const expectedUri = 'tag:dolby.com,2018:dash:EC3_ExtensionType:2018';
|
|
2153
2277
|
const expectedValue = 'JOC';
|
|
@@ -2169,8 +2293,6 @@ shaka.dash.DashParser = class {
|
|
|
2169
2293
|
|
|
2170
2294
|
let tilesLayout;
|
|
2171
2295
|
if (isImage) {
|
|
2172
|
-
const essentialPropertyElems =
|
|
2173
|
-
TXml.findChildren(node, 'EssentialProperty');
|
|
2174
2296
|
const thumbnailTileElem = essentialPropertyElems.find((element) => {
|
|
2175
2297
|
const expectedUris = [
|
|
2176
2298
|
'http://dashif.org/thumbnail_tile',
|
|
@@ -2745,7 +2867,8 @@ shaka.dash.DashParser = class {
|
|
|
2745
2867
|
const type = shaka.net.NetworkingEngine.RequestType.TIMING;
|
|
2746
2868
|
|
|
2747
2869
|
const operation =
|
|
2748
|
-
this.playerInterface_.networkingEngine.request(
|
|
2870
|
+
this.playerInterface_.networkingEngine.request(
|
|
2871
|
+
type, request, {isPreload: this.isPreloadFn_()});
|
|
2749
2872
|
this.operationManager_.manage(operation);
|
|
2750
2873
|
|
|
2751
2874
|
const response = await operation.promise;
|
|
@@ -2953,6 +3076,10 @@ shaka.dash.DashParser = class {
|
|
|
2953
3076
|
* @private
|
|
2954
3077
|
*/
|
|
2955
3078
|
makeNetworkRequest_(request, type, context) {
|
|
3079
|
+
if (!context) {
|
|
3080
|
+
context = {};
|
|
3081
|
+
}
|
|
3082
|
+
context.isPreload = this.isPreloadFn_();
|
|
2956
3083
|
const op = this.playerInterface_.networkingEngine.request(
|
|
2957
3084
|
type, request, context);
|
|
2958
3085
|
this.operationManager_.manage(op);
|
|
@@ -3032,6 +3159,13 @@ shaka.dash.DashParser.PatchContext;
|
|
|
3032
3159
|
shaka.dash.DashParser.SCTE214_ = 'urn:scte:dash:scte214-extensions';
|
|
3033
3160
|
|
|
3034
3161
|
|
|
3162
|
+
/**
|
|
3163
|
+
* @const {string}
|
|
3164
|
+
* @private
|
|
3165
|
+
*/
|
|
3166
|
+
shaka.dash.DashParser.UP_NAMESPACE_ = 'urn:mpeg:dash:schema:urlparam:2014';
|
|
3167
|
+
|
|
3168
|
+
|
|
3035
3169
|
/**
|
|
3036
3170
|
* @typedef {
|
|
3037
3171
|
* function(!Array.<string>, ?number, ?number, boolean):
|
|
@@ -3133,7 +3267,8 @@ shaka.dash.DashParser.InheritanceFrame;
|
|
|
3133
3267
|
* availabilityTimeOffset: number,
|
|
3134
3268
|
* mediaPresentationDuration: ?number,
|
|
3135
3269
|
* profiles: !Array.<string>,
|
|
3136
|
-
* roles: ?Array.<string
|
|
3270
|
+
* roles: ?Array.<string>,
|
|
3271
|
+
* urlParams: function():string
|
|
3137
3272
|
* }}
|
|
3138
3273
|
*
|
|
3139
3274
|
* @description
|
|
@@ -3164,6 +3299,8 @@ shaka.dash.DashParser.InheritanceFrame;
|
|
|
3164
3299
|
* of the use of features.
|
|
3165
3300
|
* @property {?number} mediaPresentationDuration
|
|
3166
3301
|
* Media presentation duration, or null if unknown.
|
|
3302
|
+
* @property {function():string} urlParams
|
|
3303
|
+
* The query params for the segments.
|
|
3167
3304
|
*/
|
|
3168
3305
|
shaka.dash.DashParser.Context;
|
|
3169
3306
|
|
package/lib/dash/segment_base.js
CHANGED
|
@@ -53,7 +53,7 @@ shaka.dash.SegmentBase = class {
|
|
|
53
53
|
if (uri) {
|
|
54
54
|
resolvedUris = ManifestParserUtils.resolveUris(resolvedUris, [
|
|
55
55
|
StringUtils.htmlUnescape(uri),
|
|
56
|
-
]);
|
|
56
|
+
], context.urlParams());
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
let startByte = 0;
|
|
@@ -194,6 +194,7 @@ shaka.dash.SegmentBase = class {
|
|
|
194
194
|
for (const ref of references) {
|
|
195
195
|
ref.codecs = context.representation.codecs;
|
|
196
196
|
ref.mimeType = context.representation.mimeType;
|
|
197
|
+
ref.bandwidth = context.bandwidth;
|
|
197
198
|
}
|
|
198
199
|
|
|
199
200
|
presentationTimeline.notifySegments(references);
|
|
@@ -266,7 +267,7 @@ shaka.dash.SegmentBase = class {
|
|
|
266
267
|
StringUtils.htmlUnescape(representationIndex.attributes['sourceURL']);
|
|
267
268
|
if (representationUri) {
|
|
268
269
|
indexUris = ManifestParserUtils.resolveUris(
|
|
269
|
-
indexUris, [representationUri]);
|
|
270
|
+
indexUris, [representationUri], context.urlParams());
|
|
270
271
|
}
|
|
271
272
|
}
|
|
272
273
|
|
package/lib/dash/segment_list.js
CHANGED
|
@@ -62,7 +62,7 @@ shaka.dash.SegmentList = class {
|
|
|
62
62
|
context.periodInfo.start, context.periodInfo.duration,
|
|
63
63
|
info.startNumber, context.representation.getBaseUris, info,
|
|
64
64
|
initSegmentReference, aesKey, context.representation.mimeType,
|
|
65
|
-
context.representation.codecs);
|
|
65
|
+
context.representation.codecs, context.bandwidth, context.urlParams);
|
|
66
66
|
|
|
67
67
|
const isNew = !segmentIndex;
|
|
68
68
|
if (segmentIndex) {
|
|
@@ -203,12 +203,14 @@ shaka.dash.SegmentList = class {
|
|
|
203
203
|
* @param {shaka.extern.aesKey|undefined} aesKey
|
|
204
204
|
* @param {string} mimeType
|
|
205
205
|
* @param {string} codecs
|
|
206
|
+
* @param {number} bandwidth
|
|
207
|
+
* @param {function():string} urlParams
|
|
206
208
|
* @return {!Array.<!shaka.media.SegmentReference>}
|
|
207
209
|
* @private
|
|
208
210
|
*/
|
|
209
211
|
static createSegmentReferences_(
|
|
210
212
|
periodStart, periodDuration, startNumber, getBaseUris, info,
|
|
211
|
-
initSegmentReference, aesKey, mimeType, codecs) {
|
|
213
|
+
initSegmentReference, aesKey, mimeType, codecs, bandwidth, urlParams) {
|
|
212
214
|
const ManifestParserUtils = shaka.util.ManifestParserUtils;
|
|
213
215
|
|
|
214
216
|
let max = info.mediaSegments.length;
|
|
@@ -251,7 +253,7 @@ shaka.dash.SegmentList = class {
|
|
|
251
253
|
const getUris = () => {
|
|
252
254
|
if (uris == null) {
|
|
253
255
|
uris = ManifestParserUtils.resolveUris(
|
|
254
|
-
getBaseUris(), [segment.mediaUri]);
|
|
256
|
+
getBaseUris(), [segment.mediaUri], urlParams());
|
|
255
257
|
}
|
|
256
258
|
return uris;
|
|
257
259
|
};
|
|
@@ -273,6 +275,7 @@ shaka.dash.SegmentList = class {
|
|
|
273
275
|
aesKey);
|
|
274
276
|
ref.codecs = codecs;
|
|
275
277
|
ref.mimeType = mimeType;
|
|
278
|
+
ref.bandwidth = bandwidth;
|
|
276
279
|
references.push(ref);
|
|
277
280
|
prevEndTime = endTime;
|
|
278
281
|
}
|