shaka-player 4.3.0 → 4.3.1

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.
Files changed (71) hide show
  1. package/.github/workflows/build-and-test.yaml +7 -0
  2. package/AUTHORS +1 -0
  3. package/CHANGELOG.md +33 -0
  4. package/CONTRIBUTORS +1 -0
  5. package/conditional/dummy_cast_proxy.js +120 -0
  6. package/dist/demo.compiled.debug.js +104 -110
  7. package/dist/demo.compiled.debug.map +3 -3
  8. package/dist/demo.compiled.js +104 -110
  9. package/dist/demo.compiled.map +3 -3
  10. package/dist/deps.js +8 -6
  11. package/dist/locales.js +28 -28
  12. package/dist/receiver.compiled.debug.js +54 -60
  13. package/dist/receiver.compiled.debug.map +3 -3
  14. package/dist/receiver.compiled.js +54 -60
  15. package/dist/receiver.compiled.map +3 -3
  16. package/dist/shaka-player.compiled.d.ts +19 -2
  17. package/dist/shaka-player.compiled.debug.d.ts +19 -2
  18. package/dist/shaka-player.compiled.debug.externs.js +102 -80
  19. package/dist/shaka-player.compiled.debug.js +632 -628
  20. package/dist/shaka-player.compiled.debug.map +4 -4
  21. package/dist/shaka-player.compiled.externs.js +102 -80
  22. package/dist/shaka-player.compiled.js +903 -900
  23. package/dist/shaka-player.compiled.map +4 -4
  24. package/dist/shaka-player.ui.d.ts +19 -2
  25. package/dist/shaka-player.ui.debug.d.ts +19 -2
  26. package/dist/shaka-player.ui.debug.externs.js +102 -80
  27. package/dist/shaka-player.ui.debug.js +681 -678
  28. package/dist/shaka-player.ui.debug.map +4 -4
  29. package/dist/shaka-player.ui.externs.js +102 -80
  30. package/dist/shaka-player.ui.js +1033 -1031
  31. package/dist/shaka-player.ui.map +4 -4
  32. package/docs/tutorials/welcome.md +2 -2
  33. package/externs/shaka/mp4_parser.js +3 -0
  34. package/externs/shaka/player.js +2 -1
  35. package/lib/cea/cea708_window.js +2 -2
  36. package/lib/cea/mp4_cea_parser.js +37 -16
  37. package/lib/dash/segment_template.js +1 -1
  38. package/lib/hls/hls_parser.js +37 -19
  39. package/lib/media/content_workarounds.js +12 -0
  40. package/lib/media/media_source_capabilities.js +36 -0
  41. package/lib/media/media_source_engine.js +12 -7
  42. package/lib/media/transmuxer.js +6 -4
  43. package/lib/player.js +5 -5
  44. package/lib/polyfill/abort_controller.js +143 -0
  45. package/lib/polyfill/media_capabilities.js +65 -11
  46. package/lib/polyfill/patchedmediakeys_apple.js +33 -28
  47. package/lib/text/ttml_text_parser.js +32 -7
  48. package/lib/text/ui_text_displayer.js +17 -0
  49. package/lib/util/mp4_box_parsers.js +24 -0
  50. package/lib/util/mp4_parser.js +35 -0
  51. package/lib/util/player_configuration.js +10 -3
  52. package/lib/util/stream_utils.js +35 -13
  53. package/package.json +4 -4
  54. package/shaka-player.uncompiled.js +1 -0
  55. package/test/ads/ad_manager_unit.js +3 -1
  56. package/test/dash/dash_parser_manifest_unit.js +1 -0
  57. package/test/hls/hls_parser_unit.js +132 -0
  58. package/test/media/drm_engine_unit.js +11 -1
  59. package/test/media/media_source_engine_integration.js +78 -2
  60. package/test/polyfill/media_capabilities_unit.js +259 -0
  61. package/test/polyfill/patchedmediakeys_apple_unit.js +6 -0
  62. package/test/test/util/stream_generator.js +212 -8
  63. package/test/test/util/test_scheme.js +4 -3
  64. package/test/test/util/util.js +3 -2
  65. package/test/text/mp4_ttml_parser_unit.js +6 -4
  66. package/test/text/ttml_text_parser_unit.js +119 -86
  67. package/test/text/ui_text_displayer_unit.js +76 -0
  68. package/test/util/stream_utils_unit.js +18 -0
  69. package/test/util/xml_utils_unit.js +6 -1
  70. package/third_party/closure-uri/uri.js +1 -1
  71. package/ui/controls.js +45 -36
@@ -29,8 +29,8 @@ You can build Shaka on Linux, Windows, or Mac.
29
29
  To get the sources and compile the library, you will need:
30
30
  * {@link https://git-scm.com/downloads Git v1.9+}
31
31
  * {@link https://www.python.org/downloads/ Python v2.7 or v3.5+}
32
- * {@link https://java.com/en/download/ Java Runtime Environment v8+}
33
- * {@link https://nodejs.org/en/download/ NodeJS v10+}
32
+ * {@link https://java.com/en/download/ Java Runtime Environment v14+}
33
+ * {@link https://nodejs.org/en/download/ NodeJS v14+}
34
34
  * A local web server, such as {@link https://httpd.apache.org/ Apache}
35
35
  * _NOTE: A local web server is required because browsers place restrictions
36
36
  on applications from file:/// URLs._
@@ -11,6 +11,7 @@
11
11
 
12
12
  /**
13
13
  * @typedef {{
14
+ * name: string,
14
15
  * parser: !shaka.util.Mp4Parser,
15
16
  * partialOkay: boolean,
16
17
  * start: number,
@@ -21,6 +22,8 @@
21
22
  * has64BitSize: boolean
22
23
  * }}
23
24
  *
25
+ * @property {string} name
26
+ * The box name, a 4-character string (fourcc).
24
27
  * @property {!shaka.util.Mp4Parser} parser
25
28
  * The parser that parsed this box. The parser can be used to parse child
26
29
  * boxes where the configuration of the current parser is needed to parsed
@@ -131,7 +131,8 @@ shaka.extern.StateChange;
131
131
  * @property {number} manifestTimeSeconds
132
132
  * The amount of time it took to download and parse the manifest.
133
133
  * @property {number} drmTimeSeconds
134
- * The amount of time it took to download the first drm key.
134
+ * The amount of time it took to download the first drm key, and load that key
135
+ * into the drm system.
135
136
  * @property {number} playTime
136
137
  * The total time spent in a playing state in seconds.
137
138
  * @property {number} pauseTime
@@ -420,7 +420,7 @@ shaka.cea.Cea708Window.TextJustification = {
420
420
  shaka.cea.Cea708Window.MAX_COLS = 42;
421
421
 
422
422
  /**
423
- * Maximum of 15 rows that can be indexed from 0 to 14.
423
+ * Maximum of 16 rows that can be indexed from 0 to 15.
424
424
  * @private @const {number}
425
425
  */
426
- shaka.cea.Cea708Window.MAX_ROWS = 15;
426
+ shaka.cea.Cea708Window.MAX_ROWS = 16;
@@ -66,14 +66,7 @@ shaka.cea.Mp4CeaParser = class {
66
66
  const trackIds = [];
67
67
  const timescales = [];
68
68
 
69
- // This generates a box-parser callback that simply sets a particular
70
- // bitstream format. It makes the list of codec-signalling boxes below
71
- // more compact and readable.
72
- const bitstreamFormatSetter = (format) => {
73
- return (box) => {
74
- this.bitstreamFormat_ = format;
75
- };
76
- };
69
+ const codecBoxParser = (box) => this.setBitstreamFormat_(box.name);
77
70
 
78
71
  new Mp4Parser()
79
72
  .box('moov', Mp4Parser.children)
@@ -108,14 +101,21 @@ shaka.cea.Mp4CeaParser = class {
108
101
  .fullBox('stsd', Mp4Parser.sampleDescription)
109
102
 
110
103
  // These are the various boxes that signal a codec.
111
- // Use these to set bistreamFormat_.
112
- .box('avc1', bitstreamFormatSetter(BitstreamFormat.H264))
113
- .box('avc3', bitstreamFormatSetter(BitstreamFormat.H264))
114
- .box('hev1', bitstreamFormatSetter(BitstreamFormat.H265))
115
- .box('hvc1', bitstreamFormatSetter(BitstreamFormat.H265))
116
- // Dobly vision is also H265.
117
- .box('dvh1', bitstreamFormatSetter(BitstreamFormat.H265))
118
- .box('dvhe', bitstreamFormatSetter(BitstreamFormat.H265))
104
+ .box('avc1', codecBoxParser)
105
+ .box('avc3', codecBoxParser)
106
+ .box('hev1', codecBoxParser)
107
+ .box('hvc1', codecBoxParser)
108
+ .box('dvh1', codecBoxParser)
109
+ .box('dvhe', codecBoxParser)
110
+
111
+ // This signals an encrypted sample, which we can go inside of to find
112
+ // the codec used.
113
+ .box('encv', Mp4Parser.visualSampleEntry)
114
+ .box('sinf', Mp4Parser.children)
115
+ .box('frma', (box) => {
116
+ const {codec} = shaka.util.Mp4BoxParsers.parseFRMA(box.reader);
117
+ this.setBitstreamFormat_(codec);
118
+ })
119
119
 
120
120
  .parse(initSegment, /* partialOkay= */ true);
121
121
 
@@ -338,6 +338,16 @@ shaka.cea.Mp4CeaParser = class {
338
338
  }
339
339
  }
340
340
  }
341
+
342
+ /**
343
+ * @param {string} codec A fourcc for a codec.
344
+ * @private
345
+ */
346
+ setBitstreamFormat_(codec) {
347
+ if (codec in shaka.cea.Mp4CeaParser.CodecBitstreamMap_) {
348
+ this.bitstreamFormat_ = shaka.cea.Mp4CeaParser.CodecBitstreamMap_[codec];
349
+ }
350
+ }
341
351
  };
342
352
 
343
353
  /** @enum {number} */
@@ -346,3 +356,14 @@ shaka.cea.Mp4CeaParser.BitstreamFormat = {
346
356
  H264: 1,
347
357
  H265: 2,
348
358
  };
359
+
360
+ /** @private {Object.<string, shaka.cea.Mp4CeaParser.BitstreamFormat>} */
361
+ shaka.cea.Mp4CeaParser.CodecBitstreamMap_ = {
362
+ 'avc1': shaka.cea.Mp4CeaParser.BitstreamFormat.H264,
363
+ 'avc3': shaka.cea.Mp4CeaParser.BitstreamFormat.H264,
364
+ 'hev1': shaka.cea.Mp4CeaParser.BitstreamFormat.H265,
365
+ 'hvc1': shaka.cea.Mp4CeaParser.BitstreamFormat.H265,
366
+ // Dobly vision is also H265.
367
+ 'dvh1': shaka.cea.Mp4CeaParser.BitstreamFormat.H265,
368
+ 'dvhe': shaka.cea.Mp4CeaParser.BitstreamFormat.H265,
369
+ };
@@ -67,7 +67,7 @@ shaka.dash.SegmentTemplate = class {
67
67
  },
68
68
  };
69
69
  } else if (info.segmentDuration) {
70
- if (!isUpdate) {
70
+ if (!isUpdate && context.adaptationSet.contentType !== 'image') {
71
71
  context.presentationTimeline.notifyMaxSegmentDuration(
72
72
  info.segmentDuration);
73
73
  context.presentationTimeline.notifyMinSegmentStartTime(
@@ -618,9 +618,23 @@ shaka.hls.HlsParser = class {
618
618
  if (playlist.segments.length) {
619
619
  const parsedUri = new goog.Uri(playlist.segments[0].absoluteUri);
620
620
  const extension = parsedUri.getPath().split('.').pop();
621
- const mimeType = HlsParser.RAW_FORMATS_TO_MIME_TYPES_[extension];
621
+ let mimeType = HlsParser.RAW_FORMATS_TO_MIME_TYPES_[extension];
622
622
  if (mimeType) {
623
623
  fullMimeType = mimeType;
624
+ } else if (extension === 'ts') {
625
+ // TODO: Fetch one segment a use the TsParser to analize if there is
626
+ // video, audio or both.
627
+ } else if (extension === 'mp4') {
628
+ // TODO: Fetch one segment a use the Mp4Parser to analize if there is
629
+ // video, audio or both.
630
+ } else if (HlsParser.AUDIO_EXTENSIONS_TO_MIME_TYPES_[extension]) {
631
+ mimeType = HlsParser.AUDIO_EXTENSIONS_TO_MIME_TYPES_[extension];
632
+ const defaultAudioCodec = this.config_.hls.defaultAudioCodec;
633
+ fullMimeType = `${mimeType}; codecs="${defaultAudioCodec}"`;
634
+ } else if (HlsParser.VIDEO_EXTENSIONS_TO_MIME_TYPES_[extension]) {
635
+ mimeType = HlsParser.VIDEO_EXTENSIONS_TO_MIME_TYPES_[extension];
636
+ const defaultVideoCodec = this.config_.hls.defaultVideoCodec;
637
+ fullMimeType = `${mimeType}; codecs="${defaultVideoCodec}"`;
624
638
  }
625
639
  }
626
640
 
@@ -1123,7 +1137,7 @@ shaka.hls.HlsParser = class {
1123
1137
  shaka.log.debug('Guessing audio-only.');
1124
1138
  type = ContentType.AUDIO;
1125
1139
  ignoreStream = true;
1126
- } else if (res.video.length) {
1140
+ } else if (res.video.length && !res.audio.length) {
1127
1141
  // There are associated video streams. Assume this is audio.
1128
1142
  shaka.log.debug('Guessing audio-only.');
1129
1143
  type = ContentType.AUDIO;
@@ -1677,9 +1691,10 @@ shaka.hls.HlsParser = class {
1677
1691
  stream.encrypted = realStream.encrypted;
1678
1692
  stream.drmInfos = realStream.drmInfos;
1679
1693
  stream.keyIds = realStream.keyIds;
1680
- stream.kind = realStream.kind;
1681
- stream.roles = realStream.roles;
1682
1694
  stream.mimeType = realStream.mimeType;
1695
+ if (shaka.media.MediaSourceEngine.RAW_FORMATS.includes(stream.mimeType)) {
1696
+ stream.codecs = '';
1697
+ }
1683
1698
 
1684
1699
  // Since we lazy-loaded this content, the player may need to create new
1685
1700
  // sessions for the DRM info in this stream.
@@ -1694,6 +1709,10 @@ shaka.hls.HlsParser = class {
1694
1709
  // To aid manifest filtering, assume before loading that all video
1695
1710
  // renditions have the same MIME type. (And likewise for audio.)
1696
1711
  otherStreamInfo.stream.mimeType = realStream.mimeType;
1712
+ if (shaka.media.MediaSourceEngine.RAW_FORMATS
1713
+ .includes(otherStreamInfo.stream.mimeType)) {
1714
+ otherStreamInfo.stream.codecs = '';
1715
+ }
1697
1716
  }
1698
1717
  }
1699
1718
  }
@@ -1923,23 +1942,20 @@ shaka.hls.HlsParser = class {
1923
1942
 
1924
1943
  const mediaSequenceToStartTime = this.isLive_() ?
1925
1944
  this.mediaSequenceToStartTimeByType_.get(type) : new Map();
1945
+ const prevLowLatencyMode = this.lowLatencyMode_;
1926
1946
  const segments = this.createSegments_(verbatimMediaPlaylistUri, playlist,
1927
1947
  type, mimeType, mediaSequenceToStartTime, mediaVariables);
1928
1948
 
1949
+ // This happens when autoLowLatencyMode is true, so we need set the
1950
+ // correct lowLatencyPresentationDelay_
1951
+ if (prevLowLatencyMode != this.lowLatencyMode_) {
1952
+ this.determinePresentationType_(playlist);
1953
+ }
1954
+
1929
1955
  const lastEndTime = segments[segments.length - 1].endTime;
1930
1956
  /** @type {!shaka.media.SegmentIndex} */
1931
1957
  const segmentIndex = new shaka.media.SegmentIndex(segments);
1932
1958
 
1933
- const kind = (type == shaka.util.ManifestParserUtils.ContentType.TEXT) ?
1934
- shaka.util.ManifestParserUtils.TextStreamKind.SUBTITLE : undefined;
1935
-
1936
- const roles = [];
1937
- if (characteristics) {
1938
- for (const characteristic of characteristics.split(',')) {
1939
- roles.push(characteristic);
1940
- }
1941
- }
1942
-
1943
1959
  const serverControlTag = shaka.hls.Utils.getFirstTagWithName(
1944
1960
  playlist.tags, 'EXT-X-SERVER-CONTROL');
1945
1961
  const canSkipSegments = serverControlTag ?
@@ -1951,8 +1967,6 @@ shaka.hls.HlsParser = class {
1951
1967
  stream.encrypted = encrypted;
1952
1968
  stream.drmInfos = drmInfos;
1953
1969
  stream.keyIds = keyIds;
1954
- stream.kind = kind;
1955
- stream.roles = roles;
1956
1970
  stream.mimeType = mimeType;
1957
1971
 
1958
1972
  return {
@@ -2002,7 +2016,8 @@ shaka.hls.HlsParser = class {
2002
2016
  segmentIndex: null,
2003
2017
  mimeType,
2004
2018
  codecs,
2005
- kind: undefined,
2019
+ kind: (type == shaka.util.ManifestParserUtils.ContentType.TEXT) ?
2020
+ shaka.util.ManifestParserUtils.TextStreamKind.SUBTITLE : undefined,
2006
2021
  encrypted: false,
2007
2022
  drmInfos: [],
2008
2023
  keyIds: new Set(),
@@ -2018,7 +2033,7 @@ shaka.hls.HlsParser = class {
2018
2033
  width: undefined,
2019
2034
  height: undefined,
2020
2035
  bandwidth: undefined,
2021
- roles: [],
2036
+ roles: characteristics ? characteristics.split(',') : [],
2022
2037
  forced,
2023
2038
  channelsCount,
2024
2039
  audioSamplingRate: null,
@@ -2156,8 +2171,11 @@ shaka.hls.HlsParser = class {
2156
2171
  shaka.util.Error.Code.HLS_AES_128_INVALID_KEY_LENGTH);
2157
2172
  }
2158
2173
 
2174
+ const algorithm = {
2175
+ name: 'AES-CBC',
2176
+ };
2159
2177
  keyInfo.cryptoKey = await window.crypto.subtle.importKey(
2160
- 'raw', keyResponse.data, 'AES-CBC', true, ['decrypt']);
2178
+ 'raw', keyResponse.data, algorithm, true, ['decrypt']);
2161
2179
  keyInfo.fetchKey = undefined; // No longer needed.
2162
2180
  };
2163
2181
 
@@ -69,6 +69,18 @@ shaka.media.ContentWorkarounds = class {
69
69
  })
70
70
  .fullBox('encv', onEncryptionMetadataBox)
71
71
  .fullBox('enca', onEncryptionMetadataBox)
72
+ .fullBox('hev1', (box) => {
73
+ boxesToModify.push({
74
+ box,
75
+ newType: ContentWorkarounds.BOX_TYPE_ENCV_,
76
+ });
77
+ })
78
+ .fullBox('hvc1', (box) => {
79
+ boxesToModify.push({
80
+ box,
81
+ newType: ContentWorkarounds.BOX_TYPE_ENCV_,
82
+ });
83
+ })
72
84
  .fullBox('avc1', (box) => {
73
85
  boxesToModify.push({
74
86
  box,
@@ -0,0 +1,36 @@
1
+ /*! @license
2
+ * Shaka Player
3
+ * Copyright 2016 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ goog.provide('shaka.media.Capabilities');
8
+
9
+ /**
10
+ * @summary
11
+ * This is for capturing all media source capabilities on current platform.
12
+ * And this is for static check and can not be constructed.
13
+ */
14
+ shaka.media.Capabilities = class {
15
+ /**
16
+ * Cache browser engine call to improve performance on some poor platforms
17
+ *
18
+ * @param {string} type
19
+ * @return {boolean}
20
+ */
21
+ static isTypeSupported(type) {
22
+ const supportMap = shaka.media.Capabilities.MediaSourceTypeSupportMap;
23
+ if (supportMap.has(type)) {
24
+ return supportMap.get(type);
25
+ }
26
+ const currentSupport = MediaSource.isTypeSupported(type);
27
+ supportMap.set(type, currentSupport);
28
+ return currentSupport;
29
+ }
30
+ };
31
+
32
+ /**
33
+ * Public it for unit test, and developer could also check the support map.
34
+ * @type {!Map.<string, boolean>}
35
+ */
36
+ shaka.media.Capabilities.MediaSourceTypeSupportMap = new Map();
@@ -8,6 +8,7 @@ goog.provide('shaka.media.MediaSourceEngine');
8
8
 
9
9
  goog.require('goog.asserts');
10
10
  goog.require('shaka.log');
11
+ goog.require('shaka.media.Capabilities');
11
12
  goog.require('shaka.media.ContentWorkarounds');
12
13
  goog.require('shaka.media.ClosedCaptionParser');
13
14
  goog.require('shaka.media.IClosedCaptionParser');
@@ -175,7 +176,7 @@ shaka.media.MediaSourceEngine = class {
175
176
  stream.mimeType, stream.codecs);
176
177
  const extendedMimeType = shaka.util.MimeUtils.getExtendedType(stream);
177
178
  return shaka.text.TextEngine.isTypeSupported(fullMimeType) ||
178
- MediaSource.isTypeSupported(extendedMimeType) ||
179
+ shaka.media.Capabilities.isTypeSupported(extendedMimeType) ||
179
180
  shaka.media.Transmuxer.isSupported(fullMimeType, stream.type);
180
181
  }
181
182
 
@@ -231,7 +232,7 @@ shaka.media.MediaSourceEngine = class {
231
232
  if (shaka.text.TextEngine.isTypeSupported(type)) {
232
233
  support[type] = true;
233
234
  } else {
234
- support[type] = MediaSource.isTypeSupported(type) ||
235
+ support[type] = shaka.media.Capabilities.isTypeSupported(type) ||
235
236
  shaka.media.Transmuxer.isSupported(type);
236
237
  }
237
238
  } else {
@@ -365,7 +366,8 @@ shaka.media.MediaSourceEngine = class {
365
366
  if (contentType == ContentType.TEXT) {
366
367
  this.reinitText(mimeType, sequenceMode);
367
368
  } else {
368
- if ((forceTransmux || !MediaSource.isTypeSupported(mimeType)) &&
369
+ if ((forceTransmux ||
370
+ !shaka.media.Capabilities.isTypeSupported(mimeType)) &&
369
371
  shaka.media.Transmuxer.isSupported(mimeType, contentType)) {
370
372
  this.transmuxers_[contentType] =
371
373
  new shaka.media.Transmuxer(mimeType);
@@ -586,11 +588,14 @@ shaka.media.MediaSourceEngine = class {
586
588
  mimeType = this.transmuxers_[contentType].getOrginalMimeType();
587
589
  }
588
590
  if (shaka.util.TsParser.probe(uint8ArrayData)) {
589
- const metadata = new shaka.util.TsParser().parse(uint8ArrayData)
590
- .getMetadata();
591
+ const tsParser = new shaka.util.TsParser().parse(uint8ArrayData);
592
+ // The SourceBuffer timestampOffset may or may not be set yet, so this is
593
+ // the timestamp offset that would eventually compute for this segment
594
+ // either way.
595
+ const timestampOffset =
596
+ reference.startTime - (tsParser.getStartTime()[contentType] || 0);
597
+ const metadata = tsParser.getMetadata();
591
598
  if (metadata.length) {
592
- const timestampOffset =
593
- this.sourceBuffers_[contentType].timestampOffset;
594
599
  this.onMetadata_(metadata, timestampOffset,
595
600
  reference ? reference.endTime : null);
596
601
  }
@@ -7,6 +7,7 @@
7
7
  goog.provide('shaka.media.Transmuxer');
8
8
 
9
9
  goog.require('goog.asserts');
10
+ goog.require('shaka.media.Capabilities');
10
11
  goog.require('shaka.util.BufferUtils');
11
12
  goog.require('shaka.util.Error');
12
13
  goog.require('shaka.util.IDestroyable');
@@ -74,6 +75,7 @@ shaka.media.Transmuxer = class {
74
75
  */
75
76
  static isSupported(mimeType, contentType) {
76
77
  const Transmuxer = shaka.media.Transmuxer;
78
+ const Capabilities = shaka.media.Capabilities;
77
79
 
78
80
  const isTs = Transmuxer.isTsContainer_(mimeType);
79
81
  const isAac = Transmuxer.isAacContainer_(mimeType);
@@ -83,11 +85,11 @@ shaka.media.Transmuxer = class {
83
85
  }
84
86
 
85
87
  if (isAac) {
86
- return MediaSource.isTypeSupported(Transmuxer.convertAacCodecs_());
88
+ return Capabilities.isTypeSupported(Transmuxer.convertAacCodecs_());
87
89
  }
88
90
 
89
91
  if (contentType) {
90
- return MediaSource.isTypeSupported(
92
+ return Capabilities.isTypeSupported(
91
93
  Transmuxer.convertTsCodecs_(contentType, mimeType));
92
94
  }
93
95
 
@@ -95,8 +97,8 @@ shaka.media.Transmuxer = class {
95
97
 
96
98
  const audioMime = Transmuxer.convertTsCodecs_(ContentType.AUDIO, mimeType);
97
99
  const videoMime = Transmuxer.convertTsCodecs_(ContentType.VIDEO, mimeType);
98
- return MediaSource.isTypeSupported(audioMime) ||
99
- MediaSource.isTypeSupported(videoMime);
100
+ return Capabilities.isTypeSupported(audioMime) ||
101
+ Capabilities.isTypeSupported(videoMime);
100
102
  }
101
103
 
102
104
 
package/lib/player.js CHANGED
@@ -2160,15 +2160,15 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
2160
2160
  // Unless the user has already picked a variant, anyway, by calling
2161
2161
  // selectVariantTrack before this loading stage.
2162
2162
  let initialVariant = null;
2163
- const activeVariantTrack = this.getVariantTracks().find((t) => t.active);
2164
- if (!activeVariantTrack) {
2163
+ const activeVariant = this.streamingEngine_.getCurrentVariant();
2164
+ if (!activeVariant) {
2165
2165
  initialVariant = this.chooseVariant_();
2166
2166
  goog.asserts.assert(initialVariant, 'Must choose an initial variant!');
2167
2167
  }
2168
2168
 
2169
2169
  // Lazy-load the stream, so we will have enough info to make the playhead.
2170
2170
  const createSegmentIndexPromises = [];
2171
- const toLazyLoad = activeVariantTrack || initialVariant;
2171
+ const toLazyLoad = activeVariant || initialVariant;
2172
2172
  for (const stream of [toLazyLoad.video, toLazyLoad.audio]) {
2173
2173
  if (stream && !stream.segmentIndex) {
2174
2174
  createSegmentIndexPromises.push(stream.createSegmentIndex());
@@ -2189,7 +2189,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
2189
2189
  this.startBufferManagement_(rebufferThreshold);
2190
2190
 
2191
2191
  // Now we can switch to the initial variant.
2192
- if (!activeVariantTrack) {
2192
+ if (!activeVariant) {
2193
2193
  goog.asserts.assert(initialVariant,
2194
2194
  'Must have choosen an initial variant!');
2195
2195
 
@@ -6974,7 +6974,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
6974
6974
  * @define {string} A version number taken from git at compile time.
6975
6975
  * @export
6976
6976
  */
6977
- shaka.Player.version = 'v4.3.0-uncompiled';
6977
+ shaka.Player.version = 'v4.3.1-uncompiled';
6978
6978
 
6979
6979
  // Initialize the deprecation system using the version string we just set
6980
6980
  // on the player.
@@ -0,0 +1,143 @@
1
+ /*! @license
2
+ * Shaka Player
3
+ * Copyright 2016 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ goog.provide('shaka.polyfill.AbortController');
8
+
9
+ goog.require('shaka.polyfill');
10
+ goog.require('shaka.util.FakeEvent');
11
+ goog.require('shaka.util.FakeEventTarget');
12
+
13
+ /**
14
+ * @summary A polyfill for systems that do not implement AbortController.
15
+ * This is used both with the fetch API for HTTP requests and inside the HLS
16
+ * parser.
17
+ * @export
18
+ * @extends AbortController
19
+ */
20
+ shaka.polyfill.AbortController = class {
21
+ /**
22
+ * Install the polyfill if needed.
23
+ * @export
24
+ */
25
+ static install() {
26
+ if (window.AbortController) {
27
+ // Not needed.
28
+ return;
29
+ }
30
+
31
+ window.AbortController = shaka.polyfill.AbortController;
32
+ window.AbortSignal = shaka.polyfill.AbortController.AbortSignal;
33
+ }
34
+
35
+ /** */
36
+ constructor() {
37
+ /** @private {!shaka.polyfill.AbortController.AbortSignal} */
38
+ this.signal_ = new shaka.polyfill.AbortController.AbortSignal();
39
+ }
40
+
41
+ /**
42
+ * @override
43
+ * @suppress {const|duplicate} Since the original is defined as "const", we
44
+ * need this suppression to override it.
45
+ */
46
+ get signal() {
47
+ return this.signal_;
48
+ }
49
+
50
+ /**
51
+ * @param {*=} reason
52
+ * @override
53
+ */
54
+ abort(reason) {
55
+ this.signal_.doAbort_(reason);
56
+ }
57
+ };
58
+
59
+ /**
60
+ * @summary A polyfill for AbortSignal, part of the AbortController API.
61
+ * @implements {AbortSignal}
62
+ */
63
+ shaka.polyfill.AbortController.AbortSignal =
64
+ class extends shaka.util.FakeEventTarget {
65
+ /** */
66
+ constructor() {
67
+ super();
68
+
69
+ /** @private {boolean} */
70
+ this.aborted_ = false;
71
+
72
+ /** @private {*} */
73
+ this.reason_ = undefined;
74
+
75
+ /** @type {?function(!Event)} */
76
+ this.onabort = null;
77
+ }
78
+
79
+ /** @override */
80
+ get aborted() {
81
+ return this.aborted_;
82
+ }
83
+
84
+ /** @return {*} */
85
+ get reason() {
86
+ return this.reason_;
87
+ }
88
+
89
+ /**
90
+ * @param {*} reason
91
+ * @private
92
+ */
93
+ doAbort_(reason) {
94
+ if (this.aborted_) {
95
+ return;
96
+ }
97
+
98
+ this.aborted_ = true;
99
+ this.reason_ = reason;
100
+ if (this.reason_ === undefined) {
101
+ // This is equivalent to a native implementation.
102
+ this.reason_ = new DOMException(
103
+ 'signal is aborted without reason', 'AbortError');
104
+ }
105
+
106
+ // According to MDN:
107
+ // "Event type - A generic Event with no added properties."
108
+ const event = new shaka.util.FakeEvent('abort');
109
+ if (this.onabort) {
110
+ this.onabort(event);
111
+ }
112
+ this.dispatchEvent(event);
113
+ }
114
+
115
+
116
+ /**
117
+ * @param {*=} reason
118
+ * @return {!AbortSignal}
119
+ */
120
+ static abort(reason) {
121
+ const signal = new shaka.polyfill.AbortController.AbortSignal();
122
+ signal.doAbort_(reason);
123
+ return signal;
124
+ }
125
+
126
+ /**
127
+ * @param {number} timeMs
128
+ * @return {!AbortSignal}
129
+ */
130
+ static timeout(timeMs) {
131
+ const signal = new shaka.polyfill.AbortController.AbortSignal();
132
+
133
+ window.setTimeout(() => {
134
+ // This is equivalent to a native implementation.
135
+ signal.doAbort_(new DOMException('signal timed out', 'TimeoutError'));
136
+ }, timeMs);
137
+
138
+ return signal;
139
+ }
140
+ };
141
+
142
+
143
+ shaka.polyfill.register(shaka.polyfill.AbortController.install);