shaka-player 4.9.29 → 4.9.30
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 +1 -1
- package/dist/locales.js +35 -35
- package/dist/shaka-player.compiled.debug.js +23 -23
- package/dist/shaka-player.compiled.debug.map +2 -2
- package/dist/shaka-player.compiled.js +206 -205
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.debug.js +37 -37
- package/dist/shaka-player.ui.debug.map +2 -2
- package/dist/shaka-player.ui.js +189 -188
- package/dist/shaka-player.ui.map +3 -3
- package/lib/dash/dash_parser.js +39 -11
- package/lib/dash/segment_template.js +1 -1
- package/lib/media/drm_engine.js +11 -0
- package/lib/media/media_source_engine.js +19 -30
- package/lib/media/playhead.js +3 -1
- package/lib/player.js +6 -1
- package/lib/util/platform.js +3 -2
- package/lib/util/player_configuration.js +3 -1
- package/package.json +1 -1
- package/ui/externs/ui.js +2 -1
- package/ui/remote_button.js +3 -2
- package/ui/ui.js +6 -3
package/lib/dash/dash_parser.js
CHANGED
|
@@ -1285,11 +1285,13 @@ shaka.dash.DashParser = class {
|
|
|
1285
1285
|
for (let i = 0; i < periodNodes.length; i++) {
|
|
1286
1286
|
const elem = periodNodes[i];
|
|
1287
1287
|
const next = periodNodes[i + 1];
|
|
1288
|
-
|
|
1288
|
+
let start = /** @type {number} */ (
|
|
1289
1289
|
TXml.parseAttr(elem, 'start', TXml.parseDuration, prevEnd));
|
|
1290
1290
|
const periodId = elem.attributes['id'];
|
|
1291
1291
|
const givenDuration =
|
|
1292
1292
|
TXml.parseAttr(elem, 'duration', TXml.parseDuration);
|
|
1293
|
+
start = (i == 0 && start == 0 && this.isTransitionFromDynamicToStatic_) ?
|
|
1294
|
+
seekRangeStart : start;
|
|
1293
1295
|
|
|
1294
1296
|
let periodDuration = null;
|
|
1295
1297
|
if (next) {
|
|
@@ -1299,7 +1301,7 @@ shaka.dash.DashParser = class {
|
|
|
1299
1301
|
const nextStart =
|
|
1300
1302
|
TXml.parseAttr(next, 'start', TXml.parseDuration);
|
|
1301
1303
|
if (nextStart != null) {
|
|
1302
|
-
periodDuration = nextStart - start;
|
|
1304
|
+
periodDuration = nextStart - start + seekRangeStart;
|
|
1303
1305
|
}
|
|
1304
1306
|
} else if (presentationDuration != null) {
|
|
1305
1307
|
// "The Period extends until the Period.start of the next Period, or
|
|
@@ -2575,25 +2577,51 @@ shaka.dash.DashParser = class {
|
|
|
2575
2577
|
return intValue;
|
|
2576
2578
|
}
|
|
2577
2579
|
|
|
2580
|
+
case 'tag:dolby.com,2015:dash:audio_channel_configuration:2015': {
|
|
2581
|
+
// ETSI TS 103 190-2 v1.2.1, Annex G.3
|
|
2582
|
+
// LSB-to-MSB order
|
|
2583
|
+
const channelCountMapping =
|
|
2584
|
+
[2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2];
|
|
2585
|
+
const hexValue = parseInt(value, 16);
|
|
2586
|
+
if (!hexValue) { // 0 or NaN
|
|
2587
|
+
shaka.log.warning('Channel parsing failure! ' +
|
|
2588
|
+
'Ignoring scheme and value', scheme, value);
|
|
2589
|
+
continue;
|
|
2590
|
+
}
|
|
2591
|
+
let numBits = 0;
|
|
2592
|
+
for (let i = 0; i < channelCountMapping.length; i++) {
|
|
2593
|
+
if (hexValue & (1<<i)) {
|
|
2594
|
+
numBits += channelCountMapping[i];
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
if (numBits) {
|
|
2598
|
+
return numBits;
|
|
2599
|
+
}
|
|
2600
|
+
continue;
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2578
2603
|
case 'tag:dolby.com,2014:dash:audio_channel_configuration:2011':
|
|
2579
2604
|
case 'urn:dolby:dash:audio_channel_configuration:2011': {
|
|
2580
|
-
//
|
|
2581
|
-
//
|
|
2582
|
-
|
|
2605
|
+
// Defined by https://ott.dolby.com/OnDelKits/DDP/Dolby_Digital_Plus_Online_Delivery_Kit_v1.5/Documentation/Content_Creation/SDM/help_files/topics/ddp_mpeg_dash_c_mpd_auchlconfig.html
|
|
2606
|
+
// keep list in order of the spec; reverse for LSB-to-MSB order
|
|
2607
|
+
const channelCountMapping =
|
|
2608
|
+
[1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 2, 1, 1].reverse();
|
|
2609
|
+
const hexValue = parseInt(value, 16);
|
|
2583
2610
|
if (!hexValue) { // 0 or NaN
|
|
2584
2611
|
shaka.log.warning('Channel parsing failure! ' +
|
|
2585
2612
|
'Ignoring scheme and value', scheme, value);
|
|
2586
2613
|
continue;
|
|
2587
2614
|
}
|
|
2588
|
-
// Count the 1-bits in hexValue.
|
|
2589
2615
|
let numBits = 0;
|
|
2590
|
-
|
|
2591
|
-
if (hexValue & 1) {
|
|
2592
|
-
|
|
2616
|
+
for (let i = 0; i < channelCountMapping.length; i++) {
|
|
2617
|
+
if (hexValue & (1<<i)) {
|
|
2618
|
+
numBits += channelCountMapping[i];
|
|
2593
2619
|
}
|
|
2594
|
-
hexValue >>= 1;
|
|
2595
2620
|
}
|
|
2596
|
-
|
|
2621
|
+
if (numBits) {
|
|
2622
|
+
return numBits;
|
|
2623
|
+
}
|
|
2624
|
+
continue;
|
|
2597
2625
|
}
|
|
2598
2626
|
|
|
2599
2627
|
// Defined by https://dashif.org/identifiers/audio_source_metadata/ and clause 8.2, in ISO/IEC 23001-8.
|
|
@@ -778,7 +778,7 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
778
778
|
if (currentTimeline.length) {
|
|
779
779
|
const lastCurrentEntry = currentTimeline[currentTimeline.length - 1];
|
|
780
780
|
newEntries = info.timeline.filter((entry) => {
|
|
781
|
-
return entry.
|
|
781
|
+
return entry.end > lastCurrentEntry.end;
|
|
782
782
|
});
|
|
783
783
|
} else {
|
|
784
784
|
newEntries = info.timeline.slice();
|
package/lib/media/drm_engine.js
CHANGED
|
@@ -743,6 +743,17 @@ shaka.media.DrmEngine = class {
|
|
|
743
743
|
return;
|
|
744
744
|
}
|
|
745
745
|
}
|
|
746
|
+
let duplicate = false;
|
|
747
|
+
this.storedPersistentSessions_.forEach((metadata, sessionId) => {
|
|
748
|
+
if (!duplicate &&
|
|
749
|
+
shaka.util.BufferUtils.equal(initData, metadata.initData)) {
|
|
750
|
+
duplicate = true;
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
if (duplicate) {
|
|
754
|
+
shaka.log.debug('Ignoring duplicate init data.');
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
746
757
|
}
|
|
747
758
|
|
|
748
759
|
// If there are pre-existing sessions that have all been loaded
|
|
@@ -116,7 +116,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
116
116
|
/** @private {boolean} */
|
|
117
117
|
this.playbackHasBegun_ = false;
|
|
118
118
|
|
|
119
|
-
/** @private {
|
|
119
|
+
/** @private {MediaSource} */
|
|
120
120
|
this.mediaSource_ = this.createMediaSource(this.mediaSourceOpen_);
|
|
121
121
|
|
|
122
122
|
/** @private {boolean} */
|
|
@@ -175,13 +175,16 @@ shaka.media.MediaSourceEngine = class {
|
|
|
175
175
|
* Replaced by unit tests.
|
|
176
176
|
*
|
|
177
177
|
* @param {!shaka.util.PublicPromise} p
|
|
178
|
-
* @return {!
|
|
178
|
+
* @return {!MediaSource}
|
|
179
179
|
*/
|
|
180
180
|
createMediaSource(p) {
|
|
181
|
+
/** @type {!MediaSource} */
|
|
182
|
+
let mediaSource;
|
|
183
|
+
|
|
181
184
|
if (window.ManagedMediaSource) {
|
|
182
185
|
this.video_.disableRemotePlayback = true;
|
|
183
186
|
|
|
184
|
-
|
|
187
|
+
mediaSource = new ManagedMediaSource();
|
|
185
188
|
|
|
186
189
|
this.eventManager_.listen(
|
|
187
190
|
mediaSource, 'startstreaming', () => {
|
|
@@ -192,39 +195,25 @@ shaka.media.MediaSourceEngine = class {
|
|
|
192
195
|
mediaSource, 'endstreaming', () => {
|
|
193
196
|
this.streamingAllowed_ = false;
|
|
194
197
|
});
|
|
195
|
-
|
|
196
|
-
this.eventManager_.listenOnce(
|
|
197
|
-
mediaSource, 'sourceopen', () => this.onSourceOpen_(p));
|
|
198
|
-
|
|
199
|
-
// Correctly set when playback has begun.
|
|
200
|
-
this.eventManager_.listenOnce(this.video_, 'playing', () => {
|
|
201
|
-
this.playbackHasBegun_ = true;
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
this.url_ = shaka.media.MediaSourceEngine.createObjectURL(mediaSource);
|
|
205
|
-
|
|
206
|
-
this.video_.src = this.url_;
|
|
207
|
-
|
|
208
|
-
return mediaSource;
|
|
209
198
|
} else {
|
|
210
|
-
|
|
199
|
+
mediaSource = new MediaSource();
|
|
200
|
+
}
|
|
211
201
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
202
|
+
// Set up MediaSource on the video element.
|
|
203
|
+
this.eventManager_.listenOnce(
|
|
204
|
+
mediaSource, 'sourceopen', () => this.onSourceOpen_(p));
|
|
215
205
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
206
|
+
// Correctly set when playback has begun.
|
|
207
|
+
this.eventManager_.listenOnce(this.video_, 'playing', () => {
|
|
208
|
+
this.playbackHasBegun_ = true;
|
|
209
|
+
});
|
|
220
210
|
|
|
221
|
-
|
|
222
|
-
|
|
211
|
+
// Store the object URL for releasing it later.
|
|
212
|
+
this.url_ = shaka.media.MediaSourceEngine.createObjectURL(mediaSource);
|
|
223
213
|
|
|
224
|
-
|
|
214
|
+
this.video_.src = this.url_;
|
|
225
215
|
|
|
226
|
-
|
|
227
|
-
}
|
|
216
|
+
return mediaSource;
|
|
228
217
|
}
|
|
229
218
|
|
|
230
219
|
/**
|
package/lib/media/playhead.js
CHANGED
|
@@ -427,7 +427,9 @@ shaka.media.MediaSourcePlayhead = class {
|
|
|
427
427
|
// infinite loop on systems where changing currentTime takes a
|
|
428
428
|
// significant amount of time (e.g. Chromecast).
|
|
429
429
|
const time = Date.now() / 1000;
|
|
430
|
-
|
|
430
|
+
const seekDelay = shaka.util.Platform.isFuchsiaCastDevice() ? 3 : 1;
|
|
431
|
+
if (!this.lastCorrectiveSeek_ ||
|
|
432
|
+
this.lastCorrectiveSeek_ < time - seekDelay) {
|
|
431
433
|
this.lastCorrectiveSeek_ = time;
|
|
432
434
|
canCorrectiveSeek = true;
|
|
433
435
|
}
|
package/lib/player.js
CHANGED
|
@@ -2803,6 +2803,11 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2803
2803
|
}
|
|
2804
2804
|
}
|
|
2805
2805
|
mediaElement.src = playbackUri;
|
|
2806
|
+
// If ManagedMediaSource exists, we've disabled remote playback on our own.
|
|
2807
|
+
// Reenable it so AirPlay can be used via RemotePlayback API.
|
|
2808
|
+
if (this.mediaSourceEngine_ && window.ManagedMediaSource) {
|
|
2809
|
+
mediaElement.disableRemotePlayback = false;
|
|
2810
|
+
}
|
|
2806
2811
|
|
|
2807
2812
|
// Tizen 3 / WebOS won't load anything unless you call load() explicitly,
|
|
2808
2813
|
// no matter the value of the preload attribute. This is harmful on some
|
|
@@ -7530,7 +7535,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
7530
7535
|
* @export
|
|
7531
7536
|
*/
|
|
7532
7537
|
// eslint-disable-next-line no-useless-concat, max-len
|
|
7533
|
-
shaka.Player.version = 'v4.9.
|
|
7538
|
+
shaka.Player.version = 'v4.9.30' + '-uncompiled'; // x-release-please-version
|
|
7534
7539
|
|
|
7535
7540
|
// Initialize the deprecation system using the version string we just set
|
|
7536
7541
|
// on the player.
|
package/lib/util/platform.js
CHANGED
|
@@ -629,7 +629,7 @@ shaka.util.Platform = class {
|
|
|
629
629
|
*
|
|
630
630
|
* Some devices are known not to support `MediaSource.changeType`
|
|
631
631
|
* well. These devices should use the reload strategy. If a device
|
|
632
|
-
* reports that it supports `changeType` but support it
|
|
632
|
+
* reports that it supports `changeType` but support it unreliably
|
|
633
633
|
* it should be added to this list.
|
|
634
634
|
*
|
|
635
635
|
* @return {boolean}
|
|
@@ -638,7 +638,8 @@ shaka.util.Platform = class {
|
|
|
638
638
|
const Platform = shaka.util.Platform;
|
|
639
639
|
if (Platform.isTizen2() || Platform.isTizen3() || Platform.isTizen4() ||
|
|
640
640
|
Platform.isTizen5() || Platform.isTizen6() || Platform.isWebOS3() ||
|
|
641
|
-
Platform.isWebOS4() || Platform.isWebOS5())
|
|
641
|
+
Platform.isWebOS4() || Platform.isWebOS5() || Platform.isPS4() ||
|
|
642
|
+
Platform.isPS5()) {
|
|
642
643
|
return false;
|
|
643
644
|
}
|
|
644
645
|
// Older chromecasts without GoogleTV seem to not support SMOOTH properly.
|
|
@@ -11,6 +11,7 @@ goog.require('shaka.abr.SimpleAbrManager');
|
|
|
11
11
|
goog.require('shaka.config.AutoShowText');
|
|
12
12
|
goog.require('shaka.config.CodecSwitchingStrategy');
|
|
13
13
|
goog.require('shaka.log');
|
|
14
|
+
goog.require('shaka.media.Capabilities');
|
|
14
15
|
goog.require('shaka.net.NetworkingEngine');
|
|
15
16
|
goog.require('shaka.util.ConfigUtils');
|
|
16
17
|
goog.require('shaka.util.FairPlayUtils');
|
|
@@ -103,7 +104,8 @@ shaka.util.PlayerConfiguration = class {
|
|
|
103
104
|
|
|
104
105
|
let codecSwitchingStrategy = shaka.config.CodecSwitchingStrategy.RELOAD;
|
|
105
106
|
let multiTypeVariantsAllowed = false;
|
|
106
|
-
if (shaka.
|
|
107
|
+
if (shaka.media.Capabilities.isChangeTypeSupported() &&
|
|
108
|
+
shaka.util.Platform.supportsSmoothCodecSwitching()) {
|
|
107
109
|
codecSwitchingStrategy = shaka.config.CodecSwitchingStrategy.SMOOTH;
|
|
108
110
|
multiTypeVariantsAllowed = true;
|
|
109
111
|
}
|
package/package.json
CHANGED
package/ui/externs/ui.js
CHANGED
|
@@ -226,7 +226,8 @@ shaka.extern.UIVolumeBarColors;
|
|
|
226
226
|
* @property {boolean} seekOnTaps
|
|
227
227
|
* Indicates whether or not a fast-forward and rewind tap button that seeks
|
|
228
228
|
* video some seconds.
|
|
229
|
-
* Defaults to true.
|
|
229
|
+
* Defaults to true if the browser <code>navigator.maxTouchPoints > 0</code>
|
|
230
|
+
* is true.
|
|
230
231
|
* @property {number} tapSeekDistance
|
|
231
232
|
* The time interval, in seconds, to seek when the user presses the left or
|
|
232
233
|
* right part of the video. If less than or equal to 0,
|
package/ui/remote_button.js
CHANGED
|
@@ -72,7 +72,7 @@ shaka.ui.RemoteButton = class extends shaka.ui.Element {
|
|
|
72
72
|
|
|
73
73
|
shaka.ui.Utils.setDisplay(this.remoteButton_, false);
|
|
74
74
|
|
|
75
|
-
if (!this.video.remote
|
|
75
|
+
if (!this.video.remote) {
|
|
76
76
|
this.remoteButton_.classList.add('shaka-hidden');
|
|
77
77
|
} else {
|
|
78
78
|
this.eventManager.listen(
|
|
@@ -138,10 +138,11 @@ shaka.ui.RemoteButton = class extends shaka.ui.Element {
|
|
|
138
138
|
} else if (this.video.remote.state == 'disconnected') {
|
|
139
139
|
const handleAvailabilityChange = (availability) => {
|
|
140
140
|
if (this.player) {
|
|
141
|
+
const disableRemote = this.video.disableRemotePlayback;
|
|
141
142
|
const loadMode = this.player.getLoadMode();
|
|
142
143
|
const srcMode = loadMode == shaka.Player.LoadMode.SRC_EQUALS;
|
|
143
144
|
shaka.ui.Utils.setDisplay(
|
|
144
|
-
this.remoteButton_, srcMode && availability);
|
|
145
|
+
this.remoteButton_, srcMode && availability && !disableRemote);
|
|
145
146
|
} else {
|
|
146
147
|
shaka.ui.Utils.setDisplay(this.remoteButton_, false);
|
|
147
148
|
}
|
package/ui/ui.js
CHANGED
|
@@ -252,7 +252,7 @@ shaka.ui.Overlay = class {
|
|
|
252
252
|
fullScreenElement: this.videoContainer_,
|
|
253
253
|
preferDocumentPictureInPicture: true,
|
|
254
254
|
showAudioChannelCountVariants: true,
|
|
255
|
-
seekOnTaps:
|
|
255
|
+
seekOnTaps: navigator.maxTouchPoints > 0,
|
|
256
256
|
tapSeekDistance: 10,
|
|
257
257
|
refreshTickInSeconds: 0.125,
|
|
258
258
|
displayInVrMode: false,
|
|
@@ -275,6 +275,9 @@ shaka.ui.Overlay = class {
|
|
|
275
275
|
(name) => name != 'play_pause' && name != 'volume');
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
// Set this button here to push it at the end.
|
|
279
|
+
config.overflowMenuButtons.push('save_video_frame');
|
|
280
|
+
|
|
278
281
|
return config;
|
|
279
282
|
}
|
|
280
283
|
|
|
@@ -476,6 +479,8 @@ shaka.ui.Overlay = class {
|
|
|
476
479
|
video.removeAttribute('src');
|
|
477
480
|
}
|
|
478
481
|
|
|
482
|
+
await player.attach(shaka.util.Dom.asHTMLMediaElement(video));
|
|
483
|
+
|
|
479
484
|
for (const elem of video.querySelectorAll('source')) {
|
|
480
485
|
try { // eslint-disable-next-line no-await-in-loop
|
|
481
486
|
await ui.getControls().getPlayer().load(elem.getAttribute('src'));
|
|
@@ -484,8 +489,6 @@ shaka.ui.Overlay = class {
|
|
|
484
489
|
shaka.log.error('Error auto-loading asset', e);
|
|
485
490
|
}
|
|
486
491
|
}
|
|
487
|
-
|
|
488
|
-
await player.attach(shaka.util.Dom.asHTMLMediaElement(video));
|
|
489
492
|
}
|
|
490
493
|
|
|
491
494
|
|