shaka-player 4.13.1 → 4.13.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.
@@ -73,23 +73,21 @@ shaka.media.MediaSourceEngine = class {
73
73
  this.textDisplayer_ = textDisplayer;
74
74
 
75
75
  /**
76
- * @private {!Object<shaka.util.ManifestParserUtils.ContentType,
77
- * SourceBuffer>}
76
+ * @private {!Map<shaka.util.ManifestParserUtils.ContentType, SourceBuffer>}
78
77
  */
79
- this.sourceBuffers_ = {};
78
+ this.sourceBuffers_ = new Map();
80
79
 
81
80
  /**
82
- * @private {!Object<shaka.util.ManifestParserUtils.ContentType,
83
- * string>}
81
+ * @private {!Map<shaka.util.ManifestParserUtils.ContentType, string>}
84
82
  */
85
- this.sourceBufferTypes_ = {};
83
+ this.sourceBufferTypes_ = new Map();
86
84
 
87
85
 
88
86
  /**
89
- * @private {!Object<shaka.util.ManifestParserUtils.ContentType,
87
+ * @private {!Map<shaka.util.ManifestParserUtils.ContentType,
90
88
  * boolean>}
91
89
  */
92
- this.expectedEncryption_ = {};
90
+ this.expectedEncryption_ = new Map();
93
91
 
94
92
  /** @private {shaka.text.TextEngine} */
95
93
  this.textEngine_ = null;
@@ -101,16 +99,17 @@ shaka.media.MediaSourceEngine = class {
101
99
  this.lcevcDec_ = lcevcDec || null;
102
100
 
103
101
  /**
104
- * @private {!Object<string,
105
- * !Array<shaka.media.MediaSourceEngine.Operation>>}
102
+ * @private {!Map<string, !Array<shaka.media.MediaSourceEngine.Operation>>}
106
103
  */
107
- this.queues_ = {};
104
+ this.queues_ = new Map();
108
105
 
109
106
  /** @private {shaka.util.EventManager} */
110
107
  this.eventManager_ = new shaka.util.EventManager();
111
108
 
112
- /** @private {!Object<string, !shaka.extern.Transmuxer>} */
113
- this.transmuxers_ = {};
109
+ /**
110
+ * @private {!Map<shaka.util.ManifestParserUtils.ContentType,
111
+ !shaka.extern.Transmuxer>} */
112
+ this.transmuxers_ = new Map();
114
113
 
115
114
  /** @private {?shaka.media.IClosedCaptionParser} */
116
115
  this.captionParser_ = null;
@@ -171,10 +170,10 @@ shaka.media.MediaSourceEngine = class {
171
170
  this.lastDuration_ = null;
172
171
 
173
172
  /**
174
- * @private {!Object<shaka.util.ManifestParserUtils.ContentType,
173
+ * @private {!Map<shaka.util.ManifestParserUtils.ContentType,
175
174
  * !shaka.util.TsParser>}
176
175
  */
177
- this.tsParsers_ = {};
176
+ this.tsParsers_ = new Map();
178
177
 
179
178
  /** @private {?number} */
180
179
  this.firstVideoTimestamp_ = null;
@@ -456,13 +455,14 @@ shaka.media.MediaSourceEngine = class {
456
455
 
457
456
  const cleanup = [];
458
457
 
459
- for (const contentType in this.queues_) {
458
+ for (const [key, q] of this.queues_) {
460
459
  // Make a local copy of the queue and the first item.
461
- const q = this.queues_[contentType];
462
460
  const inProgress = q[0];
463
461
 
462
+ const contentType = /** @type {string} */(key);
463
+
464
464
  // Drop everything else out of the original queue.
465
- this.queues_[contentType] = q.slice(0, 1);
465
+ this.queues_.set(contentType, q.slice(0, 1));
466
466
 
467
467
  // We will wait for this item to complete/fail.
468
468
  if (inProgress) {
@@ -481,8 +481,8 @@ shaka.media.MediaSourceEngine = class {
481
481
 
482
482
  await Promise.all(cleanup);
483
483
 
484
- for (const contentType in this.transmuxers_) {
485
- this.transmuxers_[contentType].destroy();
484
+ for (const transmuxer of this.transmuxers_.values()) {
485
+ transmuxer.destroy();
486
486
  }
487
487
 
488
488
  if (this.eventManager_) {
@@ -507,22 +507,23 @@ shaka.media.MediaSourceEngine = class {
507
507
  this.mediaSource_ = null;
508
508
  this.textEngine_ = null;
509
509
  this.textDisplayer_ = null;
510
- this.sourceBuffers_ = {};
511
- this.transmuxers_ = {};
510
+ this.sourceBuffers_.clear();
511
+ this.expectedEncryption_.clear();
512
+ this.transmuxers_.clear();
512
513
  this.captionParser_ = null;
513
514
  if (goog.DEBUG) {
514
- for (const contentType in this.queues_) {
515
+ for (const [contentType, q] of this.queues_) {
515
516
  goog.asserts.assert(
516
- this.queues_[contentType].length == 0,
517
+ q.length == 0,
517
518
  contentType + ' queue should be empty after destroy!');
518
519
  }
519
520
  }
520
- this.queues_ = {};
521
+ this.queues_.clear();
521
522
 
522
523
  // This object is owned by Player
523
524
  this.lcevcDec_ = null;
524
525
 
525
- this.tsParsers_ = {};
526
+ this.tsParsers_.clear();
526
527
  this.playerInterface_ = null;
527
528
  }
528
529
 
@@ -581,7 +582,7 @@ shaka.media.MediaSourceEngine = class {
581
582
  this.manifestType_ == shaka.media.ManifestParser.HLS &&
582
583
  !this.ignoreManifestTimestampsInSegmentsMode_;
583
584
 
584
- this.tsParsers_ = {};
585
+ this.tsParsers_.clear();
585
586
  this.firstVideoTimestamp_ = null;
586
587
  this.firstVideoReferenceStartTime_ = null;
587
588
  this.firstAudioTimestamp_ = null;
@@ -593,10 +594,10 @@ shaka.media.MediaSourceEngine = class {
593
594
  // eslint-disable-next-line no-await-in-loop
594
595
  await this.initSourceBuffer_(contentType, stream, stream.codecs);
595
596
  if (this.needSplitMuxedContent_) {
596
- this.queues_[ContentType.AUDIO] = [];
597
- this.queues_[ContentType.VIDEO] = [];
597
+ this.queues_.set(ContentType.AUDIO, []);
598
+ this.queues_.set(ContentType.VIDEO, []);
598
599
  } else {
599
- this.queues_[contentType] = [];
600
+ this.queues_.set(contentType, []);
600
601
  }
601
602
  }
602
603
  const audio = streamsByType.get(ContentType.AUDIO);
@@ -656,7 +657,7 @@ shaka.media.MediaSourceEngine = class {
656
657
  .findTransmuxer(mimeTypeWithAllCodecs);
657
658
  if (transmuxerPlugin) {
658
659
  const transmuxer = transmuxerPlugin();
659
- this.transmuxers_[contentType] = transmuxer;
660
+ this.transmuxers_.set(contentType, transmuxer);
660
661
  mimeType =
661
662
  transmuxer.convertCodecs(contentType, mimeTypeWithAllCodecs);
662
663
  }
@@ -691,9 +692,9 @@ shaka.media.MediaSourceEngine = class {
691
692
  this.eventManager_.listen(
692
693
  sourceBuffer, 'updateend',
693
694
  () => this.onUpdateEnd_(contentType));
694
- this.sourceBuffers_[contentType] = sourceBuffer;
695
- this.sourceBufferTypes_[contentType] = mimeType;
696
- this.expectedEncryption_[contentType] = !!stream.drmInfos.length;
695
+ this.sourceBuffers_.set(contentType, sourceBuffer);
696
+ this.sourceBufferTypes_.set(contentType, mimeType);
697
+ this.expectedEncryption_.set(contentType, !!stream.drmInfos.length);
697
698
  }
698
699
  }
699
700
 
@@ -767,7 +768,7 @@ shaka.media.MediaSourceEngine = class {
767
768
  * @return {?number} The timestamp in seconds, or null if nothing is buffered.
768
769
  */
769
770
  bufferStart(contentType) {
770
- if (!Object.keys(this.sourceBuffers_).length) {
771
+ if (!this.sourceBuffers_.size) {
771
772
  return null;
772
773
  }
773
774
  const ContentType = shaka.util.ManifestParserUtils.ContentType;
@@ -785,7 +786,7 @@ shaka.media.MediaSourceEngine = class {
785
786
  * @return {?number} The timestamp in seconds, or null if nothing is buffered.
786
787
  */
787
788
  bufferEnd(contentType) {
788
- if (!Object.keys(this.sourceBuffers_).length) {
789
+ if (!this.sourceBuffers_.size) {
789
790
  return null;
790
791
  }
791
792
  const ContentType = shaka.util.ManifestParserUtils.ContentType;
@@ -872,9 +873,9 @@ shaka.media.MediaSourceEngine = class {
872
873
  return null;
873
874
  }
874
875
  try {
875
- return this.sourceBuffers_[contentType].buffered;
876
+ return this.sourceBuffers_.get(contentType).buffered;
876
877
  } catch (exception) {
877
- if (contentType in this.sourceBuffers_) {
878
+ if (this.sourceBuffers_.has(contentType)) {
878
879
  // Note: previous MediaSource errors may cause access to |buffered| to
879
880
  // throw.
880
881
  shaka.log.error('failed to get buffered range for ' + contentType,
@@ -973,12 +974,12 @@ shaka.media.MediaSourceEngine = class {
973
974
  }
974
975
  } else if (!mimeType.includes('/mp4') && !mimeType.includes('/webm') &&
975
976
  shaka.util.TsParser.probe(uint8ArrayData)) {
976
- if (!this.tsParsers_[contentType]) {
977
- this.tsParsers_[contentType] = new shaka.util.TsParser();
977
+ if (!this.tsParsers_.has(contentType)) {
978
+ this.tsParsers_.set(contentType, new shaka.util.TsParser());
978
979
  } else {
979
- this.tsParsers_[contentType].clearData();
980
+ this.tsParsers_.get(contentType).clearData();
980
981
  }
981
- const tsParser = this.tsParsers_[contentType].parse(uint8ArrayData);
982
+ const tsParser = this.tsParsers_.get(contentType).parse(uint8ArrayData);
982
983
  const startTime = tsParser.getStartTime(contentType);
983
984
  if (startTime != null) {
984
985
  timestamp = startTime;
@@ -1203,16 +1204,16 @@ shaka.media.MediaSourceEngine = class {
1203
1204
  return;
1204
1205
  }
1205
1206
 
1206
- if (!this.sourceBuffers_[contentType]) {
1207
+ if (!this.sourceBuffers_.has(contentType)) {
1207
1208
  shaka.log.warning('Attempted to restore a non-existent source buffer');
1208
1209
  return;
1209
1210
  }
1210
1211
 
1211
- let timestampOffset = this.sourceBuffers_[contentType].timestampOffset;
1212
+ let timestampOffset = this.sourceBuffers_.get(contentType).timestampOffset;
1212
1213
 
1213
- let mimeType = this.sourceBufferTypes_[contentType];
1214
- if (this.transmuxers_[contentType]) {
1215
- mimeType = this.transmuxers_[contentType].getOriginalMimeType();
1214
+ let mimeType = this.sourceBufferTypes_.get(contentType);
1215
+ if (this.transmuxers_.has(contentType)) {
1216
+ mimeType = this.transmuxers_.get(contentType).getOriginalMimeType();
1216
1217
  }
1217
1218
  if (reference) {
1218
1219
  const {timestamp, metadata} = this.getTimestampAndDispatchMetadata(
@@ -1256,7 +1257,7 @@ shaka.media.MediaSourceEngine = class {
1256
1257
  // adjust TimestampOffset relative to 0 because segments do not have
1257
1258
  // any timestamp information.
1258
1259
  if (!this.sequenceMode_ &&
1259
- RAW_FORMATS.includes(this.sourceBufferTypes_[contentType])) {
1260
+ RAW_FORMATS.includes(this.sourceBufferTypes_.get(contentType))) {
1260
1261
  realTimestamp = 0;
1261
1262
  }
1262
1263
  const calculatedTimestampOffset = reference.startTime - realTimestamp;
@@ -1282,7 +1283,7 @@ shaka.media.MediaSourceEngine = class {
1282
1283
  // Prefer video for this when available.
1283
1284
  const isBestSourceBufferForTimestamps =
1284
1285
  contentType == ContentType.VIDEO ||
1285
- !(ContentType.VIDEO in this.sourceBuffers_);
1286
+ !(this.sourceBuffers_.has(ContentType.VIDEO));
1286
1287
  if (isBestSourceBufferForTimestamps) {
1287
1288
  this.textSequenceModeOffset_.resolve(timestampOffset);
1288
1289
  }
@@ -1317,8 +1318,8 @@ shaka.media.MediaSourceEngine = class {
1317
1318
  }
1318
1319
  }
1319
1320
 
1320
- if (this.transmuxers_[contentType]) {
1321
- data = await this.transmuxers_[contentType].transmux(
1321
+ if (this.transmuxers_.has(contentType)) {
1322
+ data = await this.transmuxers_.get(contentType).transmux(
1322
1323
  data, stream, reference, this.mediaSource_.duration, contentType);
1323
1324
  }
1324
1325
 
@@ -1337,7 +1338,7 @@ shaka.media.MediaSourceEngine = class {
1337
1338
  if (this.manifestType_ == shaka.media.ManifestParser.HLS &&
1338
1339
  !this.needSplitMuxedContent_ &&
1339
1340
  contentType == ContentType.AUDIO &&
1340
- this.sourceBuffers_[ContentType.VIDEO]) {
1341
+ this.sourceBuffers_.has(ContentType.VIDEO)) {
1341
1342
  const compensation = await this.audioCompensation_;
1342
1343
  // Only apply compensation if the difference is greater than 100ms
1343
1344
  if (Math.abs(compensation) > 0.1) {
@@ -1692,13 +1693,13 @@ shaka.media.MediaSourceEngine = class {
1692
1693
  // have to insert a dummy operation into the beginning of each queue,
1693
1694
  // which the 'updateend' handler will remove.
1694
1695
  if (duration < this.mediaSource_.duration) {
1695
- for (const contentType in this.sourceBuffers_) {
1696
+ for (const contentType of this.sourceBuffers_.keys()) {
1696
1697
  const dummyOperation = {
1697
1698
  start: () => {},
1698
1699
  p: new shaka.util.PublicPromise(),
1699
1700
  uri: null,
1700
1701
  };
1701
- this.queues_[contentType].unshift(dummyOperation);
1702
+ this.queues_.get(contentType).unshift(dummyOperation);
1702
1703
  }
1703
1704
  }
1704
1705
 
@@ -1771,7 +1772,7 @@ shaka.media.MediaSourceEngine = class {
1771
1772
  }
1772
1773
 
1773
1774
  // This will trigger an 'updateend' event.
1774
- this.sourceBuffers_[contentType].appendBuffer(data);
1775
+ this.sourceBuffers_.get(contentType).appendBuffer(data);
1775
1776
  }
1776
1777
 
1777
1778
  /**
@@ -1790,7 +1791,7 @@ shaka.media.MediaSourceEngine = class {
1790
1791
  }
1791
1792
 
1792
1793
  // This will trigger an 'updateend' event.
1793
- this.sourceBuffers_[contentType].remove(startTime, endTime);
1794
+ this.sourceBuffers_.get(contentType).remove(startTime, endTime);
1794
1795
  }
1795
1796
 
1796
1797
  /**
@@ -1801,18 +1802,18 @@ shaka.media.MediaSourceEngine = class {
1801
1802
  * @private
1802
1803
  */
1803
1804
  abort_(contentType) {
1805
+ const sourceBuffer = this.sourceBuffers_.get(contentType);
1804
1806
  // Save the append window, which is reset on abort().
1805
- const appendWindowStart =
1806
- this.sourceBuffers_[contentType].appendWindowStart;
1807
- const appendWindowEnd = this.sourceBuffers_[contentType].appendWindowEnd;
1807
+ const appendWindowStart = sourceBuffer.appendWindowStart;
1808
+ const appendWindowEnd = sourceBuffer.appendWindowEnd;
1808
1809
 
1809
1810
  // This will not trigger an 'updateend' event, since nothing is happening.
1810
1811
  // This is only to reset MSE internals, not to abort an actual operation.
1811
- this.sourceBuffers_[contentType].abort();
1812
+ sourceBuffer.abort();
1812
1813
 
1813
1814
  // Restore the append window.
1814
- this.sourceBuffers_[contentType].appendWindowStart = appendWindowStart;
1815
- this.sourceBuffers_[contentType].appendWindowEnd = appendWindowEnd;
1815
+ sourceBuffer.appendWindowStart = appendWindowStart;
1816
+ sourceBuffer.appendWindowEnd = appendWindowEnd;
1816
1817
 
1817
1818
  // Fake an 'updateend' event to resolve the operation.
1818
1819
  this.onUpdateEnd_(contentType);
@@ -1854,7 +1855,7 @@ shaka.media.MediaSourceEngine = class {
1854
1855
  timestampOffset += 0.001;
1855
1856
  }
1856
1857
 
1857
- this.sourceBuffers_[contentType].timestampOffset = timestampOffset;
1858
+ this.sourceBuffers_.get(contentType).timestampOffset = timestampOffset;
1858
1859
 
1859
1860
  // Fake an 'updateend' event to resolve the operation.
1860
1861
  this.onUpdateEnd_(contentType);
@@ -1868,12 +1869,13 @@ shaka.media.MediaSourceEngine = class {
1868
1869
  * @private
1869
1870
  */
1870
1871
  setAppendWindow_(contentType, appendWindowStart, appendWindowEnd) {
1872
+ const sourceBuffer = this.sourceBuffers_.get(contentType);
1871
1873
  // You can't set start > end, so first set start to 0, then set the new
1872
1874
  // end, then set the new start. That way, there are no intermediate
1873
1875
  // states which are invalid.
1874
- this.sourceBuffers_[contentType].appendWindowStart = 0;
1875
- this.sourceBuffers_[contentType].appendWindowEnd = appendWindowEnd;
1876
- this.sourceBuffers_[contentType].appendWindowStart = appendWindowStart;
1876
+ sourceBuffer.appendWindowStart = 0;
1877
+ sourceBuffer.appendWindowEnd = appendWindowEnd;
1878
+ sourceBuffer.appendWindowStart = appendWindowStart;
1877
1879
 
1878
1880
  // Fake an 'updateend' event to resolve the operation.
1879
1881
  this.onUpdateEnd_(contentType);
@@ -1884,9 +1886,9 @@ shaka.media.MediaSourceEngine = class {
1884
1886
  * @private
1885
1887
  */
1886
1888
  onError_(contentType) {
1887
- const operation = this.queues_[contentType][0];
1889
+ const operation = this.queues_.get(contentType)[0];
1888
1890
  goog.asserts.assert(operation, 'Spurious error event!');
1889
- goog.asserts.assert(!this.sourceBuffers_[contentType].updating,
1891
+ goog.asserts.assert(!this.sourceBuffers_.get(contentType).updating,
1890
1892
  'SourceBuffer should not be updating on error!');
1891
1893
  const code = this.video_.error ? this.video_.error.code : 0;
1892
1894
  operation.p.reject(new shaka.util.Error(
@@ -1909,12 +1911,12 @@ shaka.media.MediaSourceEngine = class {
1909
1911
  if (this.reloadingMediaSource_) {
1910
1912
  return;
1911
1913
  }
1912
- const operation = this.queues_[contentType][0];
1914
+ const operation = this.queues_.get(contentType)[0];
1913
1915
  goog.asserts.assert(operation, 'Spurious updateend event!');
1914
1916
  if (!operation) {
1915
1917
  return;
1916
1918
  }
1917
- goog.asserts.assert(!this.sourceBuffers_[contentType].updating,
1919
+ goog.asserts.assert(!this.sourceBuffers_.get(contentType).updating,
1918
1920
  'SourceBuffer should not be updating on updateend!');
1919
1921
  operation.p.resolve();
1920
1922
  this.popFromQueue_(contentType);
@@ -1936,9 +1938,9 @@ shaka.media.MediaSourceEngine = class {
1936
1938
  p: new shaka.util.PublicPromise(),
1937
1939
  uri,
1938
1940
  };
1939
- this.queues_[contentType].push(operation);
1941
+ this.queues_.get(contentType).push(operation);
1940
1942
 
1941
- if (this.queues_[contentType].length == 1) {
1943
+ if (this.queues_.get(contentType).length == 1) {
1942
1944
  this.startOperation_(contentType);
1943
1945
  }
1944
1946
  return operation.p;
@@ -1958,7 +1960,7 @@ shaka.media.MediaSourceEngine = class {
1958
1960
  /** @type {!Array<!shaka.util.PublicPromise>} */
1959
1961
  const allWaiters = [];
1960
1962
  /** @type {!Array<!shaka.util.ManifestParserUtils.ContentType>} */
1961
- const contentTypes = Object.keys(this.sourceBuffers_);
1963
+ const contentTypes = Array.from(this.sourceBuffers_.keys());
1962
1964
 
1963
1965
  // Enqueue a 'wait' operation onto each queue.
1964
1966
  // This operation signals its readiness when it starts.
@@ -1971,10 +1973,12 @@ shaka.media.MediaSourceEngine = class {
1971
1973
  uri: null,
1972
1974
  };
1973
1975
 
1974
- this.queues_[contentType].push(operation);
1976
+ const queue = this.queues_.get(contentType);
1977
+
1978
+ queue.push(operation);
1975
1979
  allWaiters.push(ready);
1976
1980
 
1977
- if (this.queues_[contentType].length == 1) {
1981
+ if (queue.length == 1) {
1978
1982
  operation.start();
1979
1983
  }
1980
1984
  }
@@ -1994,14 +1998,13 @@ shaka.media.MediaSourceEngine = class {
1994
1998
  // are wiped in destroy.
1995
1999
  if (goog.DEBUG) {
1996
2000
  for (const contentType of contentTypes) {
1997
- if (this.queues_[contentType].length) {
1998
- goog.asserts.assert(
1999
- this.queues_[contentType].length == 1,
2001
+ const queue = this.queues_.get(contentType);
2002
+ if (queue.length) {
2003
+ goog.asserts.assert(queue.length == 1,
2000
2004
  'Should be at most one item in queue!');
2001
- goog.asserts.assert(
2002
- allWaiters.includes(this.queues_[contentType][0].p),
2005
+ goog.asserts.assert(allWaiters.includes(queue[0].p),
2003
2006
  'The item in queue should be one of our waiters!');
2004
- this.queues_[contentType].shift();
2007
+ queue.shift();
2005
2008
  }
2006
2009
  }
2007
2010
  }
@@ -2012,7 +2015,7 @@ shaka.media.MediaSourceEngine = class {
2012
2015
  // If we did it correctly, nothing is updating.
2013
2016
  for (const contentType of contentTypes) {
2014
2017
  goog.asserts.assert(
2015
- this.sourceBuffers_[contentType].updating == false,
2018
+ this.sourceBuffers_.get(contentType).updating == false,
2016
2019
  'SourceBuffers should not be updating after a blocking op!');
2017
2020
  }
2018
2021
  }
@@ -2042,9 +2045,9 @@ shaka.media.MediaSourceEngine = class {
2042
2045
  * @private
2043
2046
  */
2044
2047
  popFromQueue_(contentType) {
2045
- goog.asserts.assert(this.queues_[contentType], 'Queue should exist');
2048
+ goog.asserts.assert(this.queues_.has(contentType), 'Queue should exist');
2046
2049
  // Remove the in-progress operation, which is now complete.
2047
- this.queues_[contentType].shift();
2050
+ this.queues_.get(contentType).shift();
2048
2051
  this.startOperation_(contentType);
2049
2052
  }
2050
2053
 
@@ -2055,7 +2058,7 @@ shaka.media.MediaSourceEngine = class {
2055
2058
  */
2056
2059
  startOperation_(contentType) {
2057
2060
  // Retrieve the next operation, if any, from the queue and start it.
2058
- const next = this.queues_[contentType][0];
2061
+ const next = this.queues_.get(contentType)[0];
2059
2062
  if (next) {
2060
2063
  try {
2061
2064
  next.start();
@@ -2123,7 +2126,7 @@ shaka.media.MediaSourceEngine = class {
2123
2126
  const Platform = shaka.util.Platform;
2124
2127
 
2125
2128
  const isInitSegment = startTime == null;
2126
- const encryptionExpected = this.expectedEncryption_[contentType];
2129
+ const encryptionExpected = this.expectedEncryption_.get(contentType);
2127
2130
  const keySystem = this.playerInterface_.getKeySystem();
2128
2131
 
2129
2132
  // If:
@@ -2141,7 +2144,7 @@ shaka.media.MediaSourceEngine = class {
2141
2144
  encryptionExpected &&
2142
2145
  Platform.requiresEncryptionInfoInAllInitSegments(keySystem) &&
2143
2146
  shaka.util.MimeUtils.getContainerType(
2144
- this.sourceBufferTypes_[contentType]) == 'mp4') {
2147
+ this.sourceBufferTypes_.get(contentType)) == 'mp4') {
2145
2148
  shaka.log.debug('Forcing fake encryption information in init segment.');
2146
2149
  segment = shaka.media.ContentWorkarounds.fakeEncryption(segment, uri);
2147
2150
  }
@@ -2149,7 +2152,7 @@ shaka.media.MediaSourceEngine = class {
2149
2152
  if (isInitSegment &&
2150
2153
  Platform.requiresEC3InitSegments() &&
2151
2154
  shaka.util.MimeUtils.getContainerType(
2152
- this.sourceBufferTypes_[contentType]) == 'mp4') {
2155
+ this.sourceBufferTypes_.get(contentType)) == 'mp4') {
2153
2156
  shaka.log.debug('Forcing fake EC-3 information in init segment.');
2154
2157
  segment = shaka.media.ContentWorkarounds.fakeEC3(segment);
2155
2158
  }
@@ -2171,19 +2174,20 @@ shaka.media.MediaSourceEngine = class {
2171
2174
  shaka.log.debug(`Change not supported for ${contentType}`);
2172
2175
  return;
2173
2176
  }
2177
+ const sourceBuffer = this.sourceBufferTypes_.get(contentType);
2174
2178
  shaka.log.debug(
2175
- `Change Type: ${this.sourceBufferTypes_[contentType]} -> ${mimeType}`);
2179
+ `Change Type: ${sourceBuffer} -> ${mimeType}`);
2176
2180
  if (shaka.media.Capabilities.isChangeTypeSupported()) {
2177
- if (this.transmuxers_[contentType]) {
2178
- this.transmuxers_[contentType].destroy();
2179
- delete this.transmuxers_[contentType];
2181
+ if (this.transmuxers_.has(contentType)) {
2182
+ this.transmuxers_.get(contentType).destroy();
2183
+ this.transmuxers_.delete(contentType);
2180
2184
  }
2181
2185
  if (transmuxer) {
2182
- this.transmuxers_[contentType] = transmuxer;
2186
+ this.transmuxers_.set(contentType, transmuxer);
2183
2187
  }
2184
2188
  const type = this.addExtraFeaturesToMimeType_(mimeType);
2185
- this.sourceBuffers_[contentType].changeType(type);
2186
- this.sourceBufferTypes_[contentType] = mimeType;
2189
+ this.sourceBuffers_.get(contentType).changeType(type);
2190
+ this.sourceBufferTypes_.set(contentType, mimeType);
2187
2191
  } else {
2188
2192
  shaka.log.debug('Change Type not supported');
2189
2193
  }
@@ -2237,19 +2241,18 @@ shaka.media.MediaSourceEngine = class {
2237
2241
  try {
2238
2242
  this.eventManager_.removeAll();
2239
2243
 
2240
- for (const contentType in this.transmuxers_) {
2241
- this.transmuxers_[contentType].destroy();
2244
+ for (const transmuxer of this.transmuxers_.values()) {
2245
+ transmuxer.destroy();
2242
2246
  }
2243
- for (const contentType in this.sourceBuffers_) {
2244
- const sourceBuffer = this.sourceBuffers_[contentType];
2247
+ for (const sourceBuffer of this.sourceBuffers_.values()) {
2245
2248
  try {
2246
2249
  this.mediaSource_.removeSourceBuffer(sourceBuffer);
2247
2250
  } catch (e) {
2248
2251
  shaka.log.debug('Exception on removeSourceBuffer', e);
2249
2252
  }
2250
2253
  }
2251
- this.transmuxers_ = {};
2252
- this.sourceBuffers_ = {};
2254
+ this.transmuxers_.clear();
2255
+ this.sourceBuffers_.clear();
2253
2256
 
2254
2257
  const previousDuration = this.mediaSource_.duration;
2255
2258
  this.mediaSourceOpen_ = new shaka.util.PublicPromise();
@@ -2288,8 +2291,8 @@ shaka.media.MediaSourceEngine = class {
2288
2291
  if (audio && audio.isAudioMuxedInVideo) {
2289
2292
  this.needSplitMuxedContent_ = true;
2290
2293
  }
2291
- if (this.needSplitMuxedContent_ && !this.queues_[ContentType.AUDIO]) {
2292
- this.queues_[ContentType.AUDIO] = [];
2294
+ if (this.needSplitMuxedContent_ && !this.queues_.has(ContentType.AUDIO)) {
2295
+ this.queues_.set(ContentType.AUDIO, []);
2293
2296
  }
2294
2297
 
2295
2298
  // Fake a seek to catchup the playhead.
@@ -2408,9 +2411,9 @@ shaka.media.MediaSourceEngine = class {
2408
2411
  }
2409
2412
  const MimeUtils = shaka.util.MimeUtils;
2410
2413
  const currentCodec = MimeUtils.getNormalizedCodec(
2411
- MimeUtils.getCodecs(this.sourceBufferTypes_[contentType]));
2414
+ MimeUtils.getCodecs(this.sourceBufferTypes_.get(contentType)));
2412
2415
  const currentBasicType = MimeUtils.getBasicType(
2413
- this.sourceBufferTypes_[contentType]);
2416
+ this.sourceBufferTypes_.get(contentType));
2414
2417
 
2415
2418
  const realInfo = this.getRealInfo_(contentType, mimeType, codecs);
2416
2419
  const transmuxer = realInfo.transmuxer;
@@ -2424,9 +2427,9 @@ shaka.media.MediaSourceEngine = class {
2424
2427
  const muxedRealInfo =
2425
2428
  this.getRealInfo_(ContentType.AUDIO, mimeType, codecs);
2426
2429
  const muxedCurrentCodec = MimeUtils.getNormalizedCodec(
2427
- MimeUtils.getCodecs(this.sourceBufferTypes_[ContentType.AUDIO]));
2430
+ MimeUtils.getCodecs(this.sourceBufferTypes_.get(ContentType.AUDIO)));
2428
2431
  const muxedCurrentBasicType = MimeUtils.getBasicType(
2429
- this.sourceBufferTypes_[ContentType.AUDIO]);
2432
+ this.sourceBufferTypes_.get(ContentType.AUDIO));
2430
2433
  muxedContentCheck = muxedCurrentCodec == muxedRealInfo.codec &&
2431
2434
  muxedCurrentBasicType == muxedRealInfo.basicType;
2432
2435
  if (muxedRealInfo.transmuxer) {
@@ -2437,18 +2440,19 @@ shaka.media.MediaSourceEngine = class {
2437
2440
  // Current/new codecs base and basic type match then no need to switch
2438
2441
  if (currentCodec === newCodec && currentBasicType === newBasicType &&
2439
2442
  muxedContentCheck) {
2440
- if (this.transmuxers_[contentType] && !transmuxer) {
2441
- this.transmuxers_[contentType].destroy();
2442
- delete this.transmuxers_[contentType];
2443
- } else if (!this.transmuxers_[contentType] && transmuxer) {
2444
- this.transmuxers_[contentType] = transmuxer;
2443
+ if (this.transmuxers_.has(contentType) && !transmuxer) {
2444
+ this.transmuxers_.get(contentType).destroy();
2445
+ this.transmuxers_.delete(contentType);
2446
+ } else if (!this.transmuxers_.has(contentType) && transmuxer) {
2447
+ this.transmuxers_.set(contentType, transmuxer);
2445
2448
  } else if (transmuxer) {
2446
2449
  // Compare if the transmuxer is different
2447
- if (this.transmuxers_[contentType] &&
2448
- this.transmuxers_[contentType].transmux != transmuxer.transmux) {
2449
- this.transmuxers_[contentType].destroy();
2450
- delete this.transmuxers_[contentType];
2451
- this.transmuxers_[contentType] = transmuxer;
2450
+ if (this.transmuxers_.has(contentType) &&
2451
+ this.transmuxers_.get(contentType).transmux !=
2452
+ transmuxer.transmux) {
2453
+ this.transmuxers_.get(contentType).destroy();
2454
+ this.transmuxers_.delete(contentType);
2455
+ this.transmuxers_.set(contentType, transmuxer);
2452
2456
  } else {
2453
2457
  transmuxer.destroy();
2454
2458
  }
@@ -2458,7 +2462,7 @@ shaka.media.MediaSourceEngine = class {
2458
2462
 
2459
2463
  let allowChangeType = true;
2460
2464
  if (this.needSplitMuxedContent_ || (transmuxerMuxed &&
2461
- transmuxer && !this.transmuxers_[contentType])) {
2465
+ transmuxer && !this.transmuxers_.has(contentType))) {
2462
2466
  allowChangeType = false;
2463
2467
  }
2464
2468
 
@@ -2490,9 +2494,9 @@ shaka.media.MediaSourceEngine = class {
2490
2494
  }
2491
2495
  const MimeUtils = shaka.util.MimeUtils;
2492
2496
  const currentCodec = MimeUtils.getNormalizedCodec(
2493
- MimeUtils.getCodecs(this.sourceBufferTypes_[contentType]));
2497
+ MimeUtils.getCodecs(this.sourceBufferTypes_.get(contentType)));
2494
2498
  const currentBasicType = MimeUtils.getBasicType(
2495
- this.sourceBufferTypes_[contentType]);
2499
+ this.sourceBufferTypes_.get(contentType));
2496
2500
 
2497
2501
  let newMimeType = shaka.util.MimeUtils.getFullType(refMimeType, refCodecs);
2498
2502
  let needTransmux = this.config_.forceTransmux;