shaka-player 4.7.1 → 4.7.2

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.
@@ -13,27 +13,35 @@
13
13
  /**
14
14
  * @typedef {{
15
15
  * Utils: !ISOBoxerUtils,
16
- * parseBuffer: function(!(ArrayBuffer|ArrayBufferView)):!ISOBoxer,
16
+ * parseBuffer: function(!(ArrayBuffer|ArrayBufferView)):!ISOFile,
17
17
  * createBox: function(string, !ISOBoxer, boolean=):!ISOBoxer,
18
18
  * createFullBox: function(string, !ISOBoxer, ?ISOBoxer=):!ISOBoxer,
19
19
  * addBoxProcessor: function(string, function()):!ISOBoxer,
20
- * createFile: function():!ISOBoxer,
21
- * write: function():!ArrayBuffer,
22
- * fetch: function(!ArrayBuffer):!ISOBoxer
20
+ * createFile: function():!ISOFile,
23
21
  * }}
24
22
  * @property {!ISOBoxerUtils} Utils
25
- * @property {function(!(ArrayBuffer|ArrayBufferView)):!ISOBoxer} parseBuffer
23
+ * @property {function(!(ArrayBuffer|ArrayBufferView)):!ISOFile} parseBuffer
26
24
  * @property {function(string, !ISOBoxer, boolean=):!ISOBoxer} createBox
27
25
  * @property {function(string, !ISOBoxer, ?ISOBoxer=):!ISOBoxer} createFullBox
28
26
  * @property {function(string, function()):!ISOBoxer} addBoxProcessor
29
- * @property {function():!ISOBoxer} createFile
30
- * @property {function():!ArrayBuffer} write
31
- * @property {function(!ArrayBuffer):!ISOBoxer} fetch
27
+ * @property {function():!ISOFile} createFile
32
28
  * @const
33
29
  */
34
30
  var ISOBoxer;
35
31
 
36
32
 
33
+ /**
34
+ * @typedef {{
35
+ * write: function():!ArrayBuffer,
36
+ * fetch: function(string):!ISOBox
37
+ * }}
38
+ * @property {function():!ArrayBuffer} write
39
+ * @property {function(string):!ISOBox} fetch
40
+ * @const
41
+ */
42
+ var ISOFile;
43
+
44
+
37
45
  /**
38
46
  * @typedef {{
39
47
  * appendBox: function(!ISOBoxer, !ISOBoxer):!ISOBox
@@ -91,7 +99,7 @@ var ISOBoxerUtils;
91
99
  * graphicsmode: number,
92
100
  * opcolor: Array.<number>,
93
101
  * balance: number,
94
- * entries: Array.<!ISOBox>,
102
+ * entries: Array.<!ISOEntry>,
95
103
  * location: string,
96
104
  * data_reference_index: number,
97
105
  * pre_defined1: number,
@@ -119,7 +127,7 @@ var ISOBoxerUtils;
119
127
  * default_sample_size: number,
120
128
  * default_sample_flags: number,
121
129
  * baseMediaDecodeTime: number,
122
- * usertype: ?string,
130
+ * usertype: (string|null|undefined),
123
131
  * offset: Array.<number>,
124
132
  * sample_info_size: Array.<number>,
125
133
  * data_offset: number
@@ -170,7 +178,7 @@ var ISOBoxerUtils;
170
178
  * @property {number} graphicsmode
171
179
  * @property {Array.<number>} opcolor
172
180
  * @property {number} balance
173
- * @property {Array.<!ISOBox} entries
181
+ * @property {Array.<!ISOEntry>} entries
174
182
  * @property {string} location
175
183
  * @property {number} data_reference_index
176
184
  * @property {number} pre_defined1
@@ -198,7 +206,7 @@ var ISOBoxerUtils;
198
206
  * @property {number} default_sample_size
199
207
  * @property {number} default_sample_flags
200
208
  * @property {number} baseMediaDecodeTime
201
- * @property {?string} usertype
209
+ * @property {string|null|undefined} usertype
202
210
  * @property {Array.<number} offset
203
211
  * @property {Array.<number} sample_info_size
204
212
  * @property {number} data_offset
@@ -4,6 +4,10 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
+ /**
8
+ * @externs
9
+ */
10
+
7
11
  /**
8
12
  * @typedef {{
9
13
  * data: !Uint8Array,
@@ -576,8 +576,9 @@ shaka.ads.MediaTailorAdManager = class {
576
576
  if (!app.data.source.length) {
577
577
  continue;
578
578
  }
579
- const imageElement = document.createElement('img');
580
- imageElement.setAttribute('src', app.data.source[0].url);
579
+ const imageElement = /** @type {!HTMLImageElement} */ (
580
+ document.createElement('img'));
581
+ imageElement.src = app.data.source[0].url;
581
582
  imageElement.style.top = (app.placeholder.top || 0) + '%';
582
583
  imageElement.style.height = (100 - (app.placeholder.top || 0)) + '%';
583
584
  imageElement.style.left = (app.placeholder.left || 0) + '%';
@@ -136,9 +136,11 @@ shaka.dash.DashParser = class {
136
136
  this.contentSteeringManager_.configure(this.config_);
137
137
  }
138
138
 
139
- this.periodCombiner_.setAllowMultiTypeVariants(
140
- this.config_.dash.multiTypeVariantsAllowed &&
141
- shaka.media.Capabilities.isChangeTypeSupported());
139
+ if (this.periodCombiner_) {
140
+ this.periodCombiner_.setAllowMultiTypeVariants(
141
+ this.config_.dash.multiTypeVariantsAllowed &&
142
+ shaka.media.Capabilities.isChangeTypeSupported());
143
+ }
142
144
  }
143
145
 
144
146
  /**
@@ -295,6 +295,7 @@ shaka.hls.HlsParser = class {
295
295
  this.groupIdToStreamInfosMap_.clear();
296
296
  this.groupIdToCodecsMap_.clear();
297
297
  this.globalVariables_.clear();
298
+ this.mapTagToInitSegmentRefMap_.clear();
298
299
 
299
300
  if (this.contentSteeringManager_) {
300
301
  this.contentSteeringManager_.destroy();
@@ -905,6 +906,7 @@ shaka.hls.HlsParser = class {
905
906
  let initData = null;
906
907
  const initSegmentRef = this.getInitSegmentReference_(
907
908
  playlist, middleSegment.tags, getUris);
909
+ this.mapTagToInitSegmentRefMap_.clear();
908
910
  if (initSegmentRef) {
909
911
  const initSegmentRequest = shaka.net.NetworkingEngine.makeRequest(
910
912
  initSegmentRef.getUris(), this.config_.retryParameters);
@@ -165,12 +165,12 @@ shaka.media.SegmentPrefetch = class {
165
165
  if (reference instanceof shaka.media.SegmentReference) {
166
166
  shaka.log.debug(
167
167
  logPrefix,
168
- 'reused prefetched segment at time:', reference.startTime,
168
+ 'missed segment at time:', reference.startTime,
169
169
  'mapSize', this.segmentPrefetchMap_.size);
170
170
  } else {
171
171
  shaka.log.debug(
172
172
  logPrefix,
173
- 'reused prefetched init segment at time, mapSize',
173
+ 'missed init segment at time, mapSize',
174
174
  this.segmentPrefetchMap_.size);
175
175
  }
176
176
  return null;
package/lib/player.js CHANGED
@@ -6865,7 +6865,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
6865
6865
  * @export
6866
6866
  */
6867
6867
  // eslint-disable-next-line no-useless-concat
6868
- shaka.Player.version = 'v4.7.1' + '-uncompiled'; // x-release-please-version
6868
+ shaka.Player.version = 'v4.7.2' + '-uncompiled'; // x-release-please-version
6869
6869
 
6870
6870
  // Initialize the deprecation system using the version string we just set
6871
6871
  // on the player.
@@ -154,6 +154,11 @@ shaka.text.UITextDisplayer = class {
154
154
  * @export
155
155
  */
156
156
  destroy() {
157
+ // Return resolved promise if destroy() has been called.
158
+ if (!this.textContainer_) {
159
+ return Promise.resolve();
160
+ }
161
+
157
162
  // Remove the text container element from the UI.
158
163
  this.videoContainer_.removeChild(this.textContainer_);
159
164
  this.textContainer_ = null;
@@ -176,6 +181,8 @@ shaka.text.UITextDisplayer = class {
176
181
  this.resizeObserver_.disconnect();
177
182
  this.resizeObserver_ = null;
178
183
  }
184
+
185
+ return Promise.resolve();
179
186
  }
180
187
 
181
188
 
@@ -253,6 +253,7 @@ shaka.transmuxer.MssTransmuxer = class {
253
253
  */
254
254
  processMediaSegment_(data, stream, reference) {
255
255
  let i;
256
+ /** @type {!ISOFile} */
256
257
  const isoFile = this.isoBoxer_.parseBuffer(data);
257
258
  // Update track_Id in tfhd box
258
259
  const tfhd = isoFile.fetch('tfhd');
@@ -313,8 +314,8 @@ shaka.transmuxer.MssTransmuxer = class {
313
314
  // (subsample_count field size)
314
315
  // 6 = 2 (BytesOfClearData field size) + 4
315
316
  // (BytesOfEncryptedData field size)
316
- saiz.sample_info_size[i] =
317
- 10 + (6 * sepiff.entry[i].NumberOfEntries);
317
+ const entry = /** @type {!ISOEntry} */ (sepiff.entry[i]);
318
+ saiz.sample_info_size[i] = 10 + (6 * entry.NumberOfEntries);
318
319
  }
319
320
  } else {
320
321
  // No sub-sample encryption => set default
@@ -705,7 +705,7 @@ shaka.transmuxer.TsTransmuxer = class {
705
705
  /** @type {?number} */
706
706
  let baseMediaDecodeTime = null;
707
707
 
708
- let nalus = [];
708
+ const nalus = [];
709
709
  const videoData = tsParser.getVideoData();
710
710
  if (!videoData.length) {
711
711
  throw new shaka.util.Error(
@@ -716,7 +716,7 @@ shaka.transmuxer.TsTransmuxer = class {
716
716
  for (let i = 0; i < videoData.length; i++) {
717
717
  const pes = videoData[i];
718
718
  const dataNalus = pes.nalus;
719
- nalus = nalus.concat(dataNalus);
719
+ nalus.push(...dataNalus);
720
720
  const frame = H264.parseFrame(dataNalus);
721
721
  if (!frame) {
722
722
  continue;
@@ -797,7 +797,7 @@ shaka.transmuxer.TsTransmuxer = class {
797
797
  /** @type {?number} */
798
798
  let baseMediaDecodeTime = null;
799
799
 
800
- let nalus = [];
800
+ const nalus = [];
801
801
  const videoData = tsParser.getVideoData();
802
802
  if (!videoData.length) {
803
803
  throw new shaka.util.Error(
@@ -808,7 +808,7 @@ shaka.transmuxer.TsTransmuxer = class {
808
808
  for (let i = 0; i < videoData.length; i++) {
809
809
  const pes = videoData[i];
810
810
  const dataNalus = pes.nalus;
811
- nalus = nalus.concat(dataNalus);
811
+ nalus.push(...dataNalus);
812
812
  const frame = H265.parseFrame(dataNalus);
813
813
  if (!frame) {
814
814
  continue;
@@ -47,10 +47,11 @@ shaka.util.Mp4Generator = class {
47
47
  goog.asserts.assert(this.streamInfos_.length > 0,
48
48
  'StreamInfos must have elements');
49
49
  const Mp4Generator = shaka.util.Mp4Generator;
50
- let traks = new Uint8Array([]);
50
+ const trakArrays = [];
51
51
  for (const streamInfo of this.streamInfos_) {
52
- traks = shaka.util.Uint8ArrayUtils.concat(traks, this.trak_(streamInfo));
52
+ trakArrays.push(this.trak_(streamInfo));
53
53
  }
54
+ const traks = shaka.util.Uint8ArrayUtils.concat(...trakArrays);
54
55
  const firstStreamInfo = this.streamInfos_[0];
55
56
  return Mp4Generator.box('moov',
56
57
  this.mvhd_(firstStreamInfo),
@@ -693,10 +694,11 @@ shaka.util.Mp4Generator = class {
693
694
  */
694
695
  mvex_() {
695
696
  const Mp4Generator = shaka.util.Mp4Generator;
696
- let trexs = new Uint8Array([]);
697
+ const trexArrays = [];
697
698
  for (const streamInfo of this.streamInfos_) {
698
- trexs = shaka.util.Uint8ArrayUtils.concat(trexs, this.trex_(streamInfo));
699
+ trexArrays.push(this.trex_(streamInfo));
699
700
  }
701
+ const trexs = shaka.util.Uint8ArrayUtils.concat(...trexArrays);
700
702
  return Mp4Generator.box('mvex', trexs);
701
703
  }
702
704
 
@@ -730,9 +732,9 @@ shaka.util.Mp4Generator = class {
730
732
  * @private
731
733
  */
732
734
  pssh_(streamInfo) {
733
- let boxes = new Uint8Array([]);
735
+ const initDatas = [];
734
736
  if (!streamInfo.encrypted) {
735
- return boxes;
737
+ return new Uint8Array([]);
736
738
  }
737
739
 
738
740
  for (const drmInfo of streamInfo.stream.drmInfos) {
@@ -740,9 +742,10 @@ shaka.util.Mp4Generator = class {
740
742
  continue;
741
743
  }
742
744
  for (const initData of drmInfo.initData) {
743
- boxes = shaka.util.Uint8ArrayUtils.concat(boxes, initData.initData);
745
+ initDatas.push(initData.initData);
744
746
  }
745
747
  }
748
+ const boxes = shaka.util.Uint8ArrayUtils.concat(...initDatas);
746
749
  return boxes;
747
750
  }
748
751
 
@@ -845,11 +848,12 @@ shaka.util.Mp4Generator = class {
845
848
  * @return {!Uint8Array}
846
849
  */
847
850
  segmentData() {
848
- let result = new Uint8Array([]);
851
+ const segmentDataArray = [];
849
852
  for (const streamInfo of this.streamInfos_) {
850
- result = shaka.util.Uint8ArrayUtils.concat(result,
851
- this.moof_(streamInfo), this.mdat_(streamInfo));
853
+ segmentDataArray.push(
854
+ ...[this.moof_(streamInfo), this.mdat_(streamInfo)]);
852
855
  }
856
+ const result = shaka.util.Uint8ArrayUtils.concat(...segmentDataArray);
853
857
  return result;
854
858
  }
855
859
 
@@ -234,10 +234,12 @@ shaka.util.Platform = class {
234
234
  return !!navigator.vendor && navigator.vendor.includes('Apple') &&
235
235
  !shaka.util.Platform.isTizen() &&
236
236
  !shaka.util.Platform.isEOS() &&
237
+ !shaka.util.Platform.isAPL() &&
237
238
  !shaka.util.Platform.isVirginMedia() &&
238
239
  !shaka.util.Platform.isOrange() &&
239
240
  !shaka.util.Platform.isPS4() &&
240
- !shaka.util.Platform.isAmazonFireTV();
241
+ !shaka.util.Platform.isAmazonFireTV() &&
242
+ !shaka.util.Platform.isWPE();
241
243
  }
242
244
 
243
245
  /**
@@ -292,6 +294,14 @@ shaka.util.Platform = class {
292
294
  return shaka.util.Platform.userAgentContains_('AFT');
293
295
  }
294
296
 
297
+ /**
298
+ * Check if the current platform is Comcast X1.
299
+ * @return {boolean}
300
+ */
301
+ static isWPE() {
302
+ return shaka.util.Platform.userAgentContains_('WPE');
303
+ }
304
+
295
305
  /**
296
306
  * Returns a major version number for Safari, or Safari-based iOS browsers.
297
307
  *
@@ -348,6 +358,15 @@ shaka.util.Platform = class {
348
358
  return shaka.util.Platform.userAgentContains_('PC=EOS');
349
359
  }
350
360
 
361
+ /**
362
+ * Check if the current platform is an APL set-top box.
363
+ *
364
+ * @return {boolean}
365
+ */
366
+ static isAPL() {
367
+ return shaka.util.Platform.userAgentContains_('PC=APL');
368
+ }
369
+
351
370
  /**
352
371
  * Guesses if the platform is a mobile one (iOS or Android).
353
372
  *
@@ -32,7 +32,7 @@ shaka.util.TsParser = class {
32
32
  /** @private {?string} */
33
33
  this.videoCodec_ = null;
34
34
 
35
- /** @private {!Array.<Uint8Array>} */
35
+ /** @private {!Array.<!Array.<Uint8Array>>} */
36
36
  this.videoData_ = [];
37
37
 
38
38
  /** @private {!Array.<shaka.extern.MPEG_PES>} */
@@ -44,7 +44,7 @@ shaka.util.TsParser = class {
44
44
  /** @private {?string} */
45
45
  this.audioCodec_ = null;
46
46
 
47
- /** @private {!Array.<Uint8Array>} */
47
+ /** @private {!Array.<!Array.<Uint8Array>>} */
48
48
  this.audioData_ = [];
49
49
 
50
50
  /** @private {!Array.<shaka.extern.MPEG_PES>} */
@@ -53,7 +53,7 @@ shaka.util.TsParser = class {
53
53
  /** @private {?number} */
54
54
  this.id3Pid_ = null;
55
55
 
56
- /** @private {!Array.<Uint8Array>} */
56
+ /** @private {!Array.<!Array.<Uint8Array>>} */
57
57
  this.id3Data_ = [];
58
58
  }
59
59
 
@@ -79,7 +79,6 @@ shaka.util.TsParser = class {
79
79
  */
80
80
  parse(data) {
81
81
  const packetLength = shaka.util.TsParser.PacketLength_;
82
- const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;
83
82
 
84
83
  // A TS fragment should contain at least 3 TS packets, a PAT, a PMT, and
85
84
  // one PID.
@@ -162,12 +161,11 @@ shaka.util.TsParser = class {
162
161
  case this.videoPid_: {
163
162
  const videoData = data.subarray(offset, start + packetLength);
164
163
  if (payloadUnitStartIndicator) {
165
- this.videoData_.push(videoData);
164
+ this.videoData_.push([videoData]);
166
165
  } else if (this.videoData_.length) {
167
166
  const prevVideoData = this.videoData_[this.videoData_.length - 1];
168
167
  if (prevVideoData) {
169
- this.videoData_[this.videoData_.length - 1] =
170
- Uint8ArrayUtils.concat(prevVideoData, videoData);
168
+ this.videoData_[this.videoData_.length - 1].push(videoData);
171
169
  }
172
170
  }
173
171
  break;
@@ -175,12 +173,11 @@ shaka.util.TsParser = class {
175
173
  case this.audioPid_: {
176
174
  const audioData = data.subarray(offset, start + packetLength);
177
175
  if (payloadUnitStartIndicator) {
178
- this.audioData_.push(audioData);
176
+ this.audioData_.push([audioData]);
179
177
  } else if (this.audioData_.length) {
180
178
  const prevAudioData = this.audioData_[this.audioData_.length - 1];
181
179
  if (prevAudioData) {
182
- this.audioData_[this.audioData_.length - 1] =
183
- Uint8ArrayUtils.concat(prevAudioData, audioData);
180
+ this.audioData_[this.audioData_.length - 1].push(audioData);
184
181
  }
185
182
  }
186
183
  break;
@@ -188,12 +185,11 @@ shaka.util.TsParser = class {
188
185
  case this.id3Pid_: {
189
186
  const id3Data = data.subarray(offset, start + packetLength);
190
187
  if (payloadUnitStartIndicator) {
191
- this.id3Data_.push(id3Data);
188
+ this.id3Data_.push([id3Data]);
192
189
  } else if (this.id3Data_.length) {
193
190
  const prevId3Data = this.id3Data_[this.id3Data_.length - 1];
194
191
  if (prevId3Data) {
195
- this.id3Data_[this.id3Data_.length - 1] =
196
- Uint8ArrayUtils.concat(prevId3Data, id3Data);
192
+ this.id3Data_[this.id3Data_.length - 1].push(id3Data);
197
193
  }
198
194
  }
199
195
  break;
@@ -588,7 +584,8 @@ shaka.util.TsParser = class {
588
584
  getMetadata() {
589
585
  const timescale = shaka.util.TsParser.Timescale;
590
586
  const metadata = [];
591
- for (const id3Data of this.id3Data_) {
587
+ for (const id3DataArray of this.id3Data_) {
588
+ const id3Data = shaka.util.Uint8ArrayUtils.concat(...id3DataArray);
592
589
  const pes = this.parsePES_(id3Data);
593
590
  if (pes) {
594
591
  metadata.push({
@@ -612,7 +609,8 @@ shaka.util.TsParser = class {
612
609
  getAudioData() {
613
610
  if (this.audioData_.length && !this.audioPes_.length) {
614
611
  let sort = false;
615
- for (const audioData of this.audioData_) {
612
+ for (const audioDataArray of this.audioData_) {
613
+ const audioData = shaka.util.Uint8ArrayUtils.concat(...audioDataArray);
616
614
  const pes = this.parsePES_(audioData);
617
615
  let previousPes = this.audioPes_.length ?
618
616
  this.audioPes_[this.audioPes_.length - 1] : null;
@@ -654,7 +652,8 @@ shaka.util.TsParser = class {
654
652
  getVideoData(naluProcessing = true) {
655
653
  if (this.videoData_.length && !this.videoPes_.length) {
656
654
  let sort = false;
657
- for (const videoData of this.videoData_) {
655
+ for (const videoDataArray of this.videoData_) {
656
+ const videoData = shaka.util.Uint8ArrayUtils.concat(...videoDataArray);
658
657
  const pes = this.parsePES_(videoData);
659
658
  let previousPes = this.videoPes_.length ?
660
659
  this.videoPes_[this.videoPes_.length - 1] : null;
@@ -107,21 +107,26 @@ shaka.util.Uint8ArrayUtils = class {
107
107
  * @export
108
108
  */
109
109
  static concat(...varArgs) {
110
+ const BufferUtils = shaka.util.BufferUtils;
110
111
  let totalLength = 0;
111
- for (const arr of varArgs) {
112
- totalLength += arr.byteLength;
112
+ for (let i = 0; i < varArgs.length; ++i) {
113
+ const value = varArgs[i];
114
+ totalLength += value.byteLength;
113
115
  }
114
116
 
115
117
  const result = new Uint8Array(totalLength);
116
118
  let offset = 0;
117
- for (const arr of varArgs) {
118
- if (arr instanceof Uint8Array) {
119
- result.set(arr, offset);
119
+
120
+ for (let i = 0; i < varArgs.length; ++i) {
121
+ const value = varArgs[i];
122
+ if (value instanceof Uint8Array) {
123
+ result.set(value, offset);
120
124
  } else {
121
- result.set(shaka.util.BufferUtils.toUint8(arr), offset);
125
+ result.set(BufferUtils.toUint8(value), offset);
122
126
  }
123
- offset += arr.byteLength;
127
+ offset += value.byteLength;
124
128
  }
129
+
125
130
  return result;
126
131
  }
127
132
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "shaka-player",
3
3
  "description": "DASH/EME video player library",
4
- "version": "4.7.1",
4
+ "version": "4.7.2",
5
5
  "homepage": "https://github.com/shaka-project/shaka-player",
6
6
  "author": "Google",
7
7
  "maintainers": [
package/ui/controls.js CHANGED
@@ -652,7 +652,8 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
652
652
  isPiPAllowed() {
653
653
  if ('documentPictureInPicture' in window &&
654
654
  this.config_.preferDocumentPictureInPicture) {
655
- return true;
655
+ const video = /** @type {HTMLVideoElement} */(this.localVideo_);
656
+ return !video.disablePictureInPicture;
656
657
  }
657
658
  if (document.pictureInPictureEnabled) {
658
659
  const video = /** @type {HTMLVideoElement} */(this.localVideo_);