shaka-player 4.2.4 → 4.3.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.
Files changed (137) hide show
  1. package/.github/workflows/sync-labels.yaml +1 -1
  2. package/.github/workflows/update-issues.yaml +1 -1
  3. package/AUTHORS +4 -0
  4. package/CHANGELOG.md +85 -54
  5. package/CONTRIBUTORS +4 -0
  6. package/README.md +14 -0
  7. package/demo/common/assets.js +58 -0
  8. package/demo/common/message_ids.js +22 -1
  9. package/demo/config.js +89 -5
  10. package/demo/demo.less +7 -1
  11. package/demo/index.html +8 -1
  12. package/demo/locales/en.json +21 -1
  13. package/demo/locales/source.json +82 -2
  14. package/demo/main.js +57 -1
  15. package/demo/search.js +2 -0
  16. package/demo/visualizer.js +337 -0
  17. package/demo/visualizer_button.js +103 -0
  18. package/dist/controls.css +1 -1
  19. package/dist/controls.css.map +1 -1
  20. package/dist/demo.compiled.debug.js +83 -58
  21. package/dist/demo.compiled.debug.map +4 -4
  22. package/dist/demo.compiled.js +83 -58
  23. package/dist/demo.compiled.map +4 -4
  24. package/dist/demo.css +1 -1
  25. package/dist/demo.css.map +1 -1
  26. package/dist/deps.js +16 -9
  27. package/dist/locales.js +32 -32
  28. package/dist/receiver.compiled.debug.js +23 -19
  29. package/dist/receiver.compiled.debug.map +3 -3
  30. package/dist/receiver.compiled.js +23 -19
  31. package/dist/receiver.compiled.map +3 -3
  32. package/dist/shaka-player.compiled.d.ts +173 -26
  33. package/dist/shaka-player.compiled.debug.d.ts +173 -26
  34. package/dist/shaka-player.compiled.debug.externs.js +161 -31
  35. package/dist/shaka-player.compiled.debug.js +464 -401
  36. package/dist/shaka-player.compiled.debug.map +4 -4
  37. package/dist/shaka-player.compiled.externs.js +161 -31
  38. package/dist/shaka-player.compiled.js +897 -862
  39. package/dist/shaka-player.compiled.map +4 -4
  40. package/dist/shaka-player.ui.d.ts +173 -26
  41. package/dist/shaka-player.ui.debug.d.ts +173 -26
  42. package/dist/shaka-player.ui.debug.externs.js +161 -31
  43. package/dist/shaka-player.ui.debug.js +488 -422
  44. package/dist/shaka-player.ui.debug.map +4 -4
  45. package/dist/shaka-player.ui.externs.js +161 -31
  46. package/dist/shaka-player.ui.js +1053 -1018
  47. package/dist/shaka-player.ui.map +4 -4
  48. package/docs/design/lcevc-architecture.png +0 -0
  49. package/docs/design/lcevc-demo.png +0 -0
  50. package/docs/design/lcevc-integration.md +72 -0
  51. package/docs/tutorials/fairplay.md +7 -0
  52. package/docs/tutorials/faq.md +1 -1
  53. package/docs/tutorials/ui.md +7 -7
  54. package/docs/tutorials/upgrade.md +6 -0
  55. package/externs/ima.js +13 -1
  56. package/externs/lcevc.js +81 -0
  57. package/externs/mux.js +1 -42
  58. package/externs/shaka/ads.js +11 -1
  59. package/externs/shaka/manifest_parser.js +5 -1
  60. package/externs/shaka/player.js +178 -15
  61. package/lib/abr/simple_abr_manager.js +7 -0
  62. package/lib/ads/ad_manager.js +0 -8
  63. package/lib/ads/client_side_ad.js +15 -0
  64. package/lib/ads/client_side_ad_manager.js +21 -8
  65. package/lib/ads/server_side_ad.js +15 -0
  66. package/lib/ads/server_side_ad_manager.js +3 -3
  67. package/lib/cast/cast_utils.js +2 -0
  68. package/lib/cea/dummy_cea_parser.js +28 -0
  69. package/lib/cea/i_cea_parser.js +14 -2
  70. package/lib/cea/mp4_cea_parser.js +87 -5
  71. package/lib/config/auto_show_text.js +33 -0
  72. package/lib/dash/dash_parser.js +1 -1
  73. package/lib/hls/hls_parser.js +790 -374
  74. package/lib/lcevc/lcevc_dil.js +152 -0
  75. package/lib/media/closed_caption_parser.js +9 -6
  76. package/lib/media/drm_engine.js +14 -6
  77. package/lib/media/media_source_engine.js +106 -26
  78. package/lib/media/presentation_timeline.js +26 -11
  79. package/lib/media/segment_reference.js +49 -1
  80. package/lib/media/streaming_engine.js +142 -12
  81. package/lib/media/transmuxer.js +73 -18
  82. package/lib/offline/storage.js +1 -0
  83. package/lib/player.js +454 -75
  84. package/lib/polyfill/patchedmediakeys_apple.js +55 -1
  85. package/lib/text/ui_text_displayer.js +5 -5
  86. package/lib/text/vtt_text_parser.js +35 -1
  87. package/lib/util/dom_utils.js +0 -1
  88. package/lib/util/error.js +17 -0
  89. package/lib/util/fake_event.js +2 -0
  90. package/lib/util/id3_utils.js +300 -0
  91. package/lib/util/mime_utils.js +3 -6
  92. package/lib/util/mp4_box_parsers.js +15 -5
  93. package/lib/util/platform.js +9 -1
  94. package/lib/util/player_configuration.js +23 -1
  95. package/lib/util/ts_parser.js +499 -0
  96. package/maintained-branches.md +2 -2
  97. package/package.json +4 -1
  98. package/roadmap.md +5 -3
  99. package/test/ads/ad_manager_unit.js +180 -29
  100. package/test/cast/cast_utils_unit.js +3 -1
  101. package/test/dash/dash_parser_content_protection_unit.js +1 -0
  102. package/test/dash/dash_parser_live_unit.js +1 -0
  103. package/test/dash/dash_parser_manifest_unit.js +93 -1
  104. package/test/dash/dash_parser_segment_base_unit.js +1 -0
  105. package/test/dash/dash_parser_segment_list_unit.js +1 -0
  106. package/test/dash/dash_parser_segment_template_unit.js +1 -0
  107. package/test/demo/demo_unit.js +2 -1
  108. package/test/hls/hls_live_unit.js +253 -19
  109. package/test/hls/hls_parser_unit.js +500 -12
  110. package/test/media/closed_caption_parser_unit.js +2 -1
  111. package/test/media/drm_engine_integration.js +3 -1
  112. package/test/media/media_source_engine_integration.js +71 -6
  113. package/test/media/media_source_engine_unit.js +10 -5
  114. package/test/media/streaming_engine_integration.js +4 -1
  115. package/test/media/streaming_engine_unit.js +144 -1
  116. package/test/media/transmuxer_integration.js +21 -10
  117. package/test/player_integration.js +224 -82
  118. package/test/player_unit.js +5 -2
  119. package/test/polyfill/patchedmediakeys_apple_unit.js +124 -0
  120. package/test/test/assets/id3-metadata.aac +0 -0
  121. package/test/test/assets/id3-metadata.ts +0 -0
  122. package/test/test/assets/thumbnails-sprites.vtt +10 -0
  123. package/test/test/assets/thumbnails.vtt +10 -0
  124. package/test/test/util/dash_parser_util.js +2 -0
  125. package/test/test/util/fake_ad.js +21 -0
  126. package/test/test/util/fake_media_source_engine.js +7 -0
  127. package/test/test/util/id3_generator.js +100 -0
  128. package/test/test/util/manifest_generator.js +3 -6
  129. package/test/test/util/simple_fakes.js +4 -0
  130. package/test/test/util/stream_generator.js +38 -0
  131. package/test/test/util/test_scheme.js +43 -14
  132. package/test/text/vtt_text_parser_unit.js +11 -0
  133. package/test/ui/text_displayer_layout_unit.js +14 -0
  134. package/test/util/id3_utils_unit.js +116 -0
  135. package/test/util/ts_parser_unit.js +77 -0
  136. package/ui/less/containers.less +7 -0
  137. package/ui/ui.js +43 -4
@@ -9,6 +9,7 @@ goog.provide('shaka.cea.Mp4CeaParser');
9
9
  goog.require('goog.asserts');
10
10
  goog.require('shaka.cea.ICeaParser');
11
11
  goog.require('shaka.cea.SeiProcessor');
12
+ goog.require('shaka.log');
12
13
  goog.require('shaka.util.DataViewReader');
13
14
  goog.require('shaka.util.Error');
14
15
  goog.require('shaka.util.Mp4Parser');
@@ -45,6 +46,11 @@ shaka.cea.Mp4CeaParser = class {
45
46
  * @private {number}
46
47
  */
47
48
  this.defaultSampleSize_ = 0;
49
+
50
+ /**
51
+ * @private {shaka.cea.Mp4CeaParser.BitstreamFormat}
52
+ */
53
+ this.bitstreamFormat_ = shaka.cea.Mp4CeaParser.BitstreamFormat.UNKNOWN;
48
54
  }
49
55
 
50
56
  /**
@@ -56,9 +62,19 @@ shaka.cea.Mp4CeaParser = class {
56
62
  */
57
63
  init(initSegment) {
58
64
  const Mp4Parser = shaka.util.Mp4Parser;
65
+ const BitstreamFormat = shaka.cea.Mp4CeaParser.BitstreamFormat;
59
66
  const trackIds = [];
60
67
  const timescales = [];
61
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
+ };
77
+
62
78
  new Mp4Parser()
63
79
  .box('moov', Mp4Parser.children)
64
80
  .box('mvex', Mp4Parser.children)
@@ -87,6 +103,20 @@ shaka.cea.Mp4CeaParser = class {
87
103
  box.reader, box.version);
88
104
  timescales.push(parsedMDHDBox.timescale);
89
105
  })
106
+ .box('minf', Mp4Parser.children)
107
+ .box('stbl', Mp4Parser.children)
108
+ .fullBox('stsd', Mp4Parser.sampleDescription)
109
+
110
+ // 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))
119
+
90
120
  .parse(initSegment, /* partialOkay= */ true);
91
121
 
92
122
  // At least one track should exist, and each track should have a
@@ -99,6 +129,11 @@ shaka.cea.Mp4CeaParser = class {
99
129
  shaka.util.Error.Code.INVALID_MP4_CEA);
100
130
  }
101
131
 
132
+ if (this.bitstreamFormat_ == BitstreamFormat.UNKNOWN) {
133
+ shaka.log.alwaysWarn(
134
+ 'Unable to determine bitstream format for CEA parsing!');
135
+ }
136
+
102
137
  // Populate the map from track Id to timescale
103
138
  trackIds.forEach((trackId, idx) => {
104
139
  this.trackIdToTimescale_.set(trackId, timescales[idx]);
@@ -115,6 +150,12 @@ shaka.cea.Mp4CeaParser = class {
115
150
  */
116
151
  parse(mediaSegment) {
117
152
  const Mp4Parser = shaka.util.Mp4Parser;
153
+ const BitstreamFormat = shaka.cea.Mp4CeaParser.BitstreamFormat;
154
+
155
+ if (this.bitstreamFormat_ == BitstreamFormat.UNKNOWN) {
156
+ // We don't know how to extract SEI from this.
157
+ return [];
158
+ }
118
159
 
119
160
  /** @type {!Array<!shaka.cea.ICeaParser.CaptionPacket>} **/
120
161
  const captionPackets = [];
@@ -123,11 +164,16 @@ shaka.cea.Mp4CeaParser = class {
123
164
  let defaultSampleDuration = this.defaultSampleDuration_;
124
165
  let defaultSampleSize = this.defaultSampleSize_;
125
166
  let sampleData = [];
167
+ let moofOffset = null;
168
+ let trunOffset = null;
126
169
  let baseMediaDecodeTime = null;
127
170
  let timescale = shaka.cea.ICeaParser.DEFAULT_TIMESCALE_VALUE;
128
171
 
129
172
  new Mp4Parser()
130
- .box('moof', Mp4Parser.children)
173
+ .box('moof', (box) => {
174
+ moofOffset = box.start;
175
+ Mp4Parser.children(box);
176
+ })
131
177
  .box('traf', Mp4Parser.children)
132
178
  .fullBox('trun', (box) => {
133
179
  goog.asserts.assert(
@@ -138,6 +184,7 @@ shaka.cea.Mp4CeaParser = class {
138
184
  box.reader, box.version, box.flags);
139
185
 
140
186
  sampleData = parsedTRUN.sampleData;
187
+ trunOffset = parsedTRUN.dataOffset;
141
188
  })
142
189
 
143
190
  .fullBox('tfhd', (box) => {
@@ -183,8 +230,9 @@ shaka.cea.Mp4CeaParser = class {
183
230
  shaka.util.Error.Category.TEXT,
184
231
  shaka.util.Error.Code.INVALID_MP4_CEA);
185
232
  }
233
+ const offset = (moofOffset || 0) + (trunOffset || 0) - box.start - 8;
186
234
  this.parseMdat_(box.reader, baseMediaDecodeTime, timescale,
187
- defaultSampleDuration, defaultSampleSize, sampleData,
235
+ defaultSampleDuration, defaultSampleSize, offset, sampleData,
188
236
  captionPackets);
189
237
  })
190
238
  .parse(mediaSegment, /* partialOkay= */ false);
@@ -199,12 +247,15 @@ shaka.cea.Mp4CeaParser = class {
199
247
  * @param {number} timescale
200
248
  * @param {number} defaultSampleDuration
201
249
  * @param {number} defaultSampleSize
250
+ * @param {number} offset
202
251
  * @param {!Array<shaka.util.ParsedTRUNSample>} sampleData
203
252
  * @param {!Array<!shaka.cea.ICeaParser.CaptionPacket>} captionPackets
204
253
  * @private
205
254
  */
206
255
  parseMdat_(reader, time, timescale, defaultSampleDuration,
207
- defaultSampleSize, sampleData, captionPackets) {
256
+ defaultSampleSize, offset, sampleData, captionPackets) {
257
+ const BitstreamFormat = shaka.cea.Mp4CeaParser.BitstreamFormat;
258
+ const ICeaParser = shaka.cea.ICeaParser;
208
259
  let sampleIndex = 0;
209
260
 
210
261
  // The fields in each ParsedTRUNSample contained in the sampleData
@@ -217,10 +268,34 @@ shaka.cea.Mp4CeaParser = class {
217
268
  sampleSize = sampleData[0].sampleSize || defaultSampleSize;
218
269
  }
219
270
 
271
+ reader.skip(offset);
272
+
220
273
  while (reader.hasMoreData()) {
221
274
  const naluSize = reader.readUint32();
222
- const naluType = reader.readUint8() & 0x1F;
223
- if (naluType == shaka.cea.ICeaParser.NALU_TYPE_SEI) {
275
+ const naluHeader = reader.readUint8();
276
+ let naluType = null;
277
+ let isSeiMessage = false;
278
+
279
+ goog.asserts.assert(this.bitstreamFormat_ != BitstreamFormat.UNKNOWN,
280
+ 'Bitstream format should have been checked before now!');
281
+ switch (this.bitstreamFormat_) {
282
+ case BitstreamFormat.H264:
283
+ naluType = naluHeader & 0x1f;
284
+ isSeiMessage = naluType == ICeaParser.H264_NALU_TYPE_SEI;
285
+ break;
286
+
287
+ case BitstreamFormat.H265:
288
+ naluType = (naluHeader >> 1) & 0x3f;
289
+ isSeiMessage =
290
+ naluType == ICeaParser.H265_PREFIX_NALU_TYPE_SEI ||
291
+ naluType == ICeaParser.H265_SUFFIX_NALU_TYPE_SEI;
292
+ break;
293
+
294
+ default:
295
+ return;
296
+ }
297
+
298
+ if (isSeiMessage) {
224
299
  let timeOffset = 0;
225
300
 
226
301
  if (sampleData.length > sampleIndex) {
@@ -264,3 +339,10 @@ shaka.cea.Mp4CeaParser = class {
264
339
  }
265
340
  }
266
341
  };
342
+
343
+ /** @enum {number} */
344
+ shaka.cea.Mp4CeaParser.BitstreamFormat = {
345
+ UNKNOWN: 0,
346
+ H264: 1,
347
+ H265: 2,
348
+ };
@@ -0,0 +1,33 @@
1
+ /*! @license
2
+ * Shaka Player
3
+ * Copyright 2016 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ goog.provide('shaka.config.AutoShowText');
8
+
9
+ /**
10
+ * @enum {number}
11
+ * @export
12
+ */
13
+ shaka.config.AutoShowText = {
14
+ /** Never show text automatically on startup. */
15
+ 'NEVER': 0,
16
+ /** Always show text automatically on startup. */
17
+ 'ALWAYS': 1,
18
+ /**
19
+ * Show text automatically on startup if it matches the preferred text
20
+ * language.
21
+ */
22
+ 'IF_PREFERRED_TEXT_LANGUAGE': 2,
23
+ /**
24
+ * Show text automatically on startup if we think that subtitles may be
25
+ * needed. This is specifically if the selected text matches the preferred
26
+ * text language AND is different from the initial audio language. (Example:
27
+ * You prefer English, but the audio is only available in French, so English
28
+ * subtitles should be enabled by default.)
29
+ * <br>
30
+ * This is the default setting.
31
+ */
32
+ 'IF_SUBTITLES_MAY_BE_NEEDED': 3,
33
+ };
@@ -498,7 +498,7 @@ shaka.dash.DashParser = class {
498
498
  imageStreams: this.periodCombiner_.getImageStreams(),
499
499
  offlineSessionIds: [],
500
500
  minBufferTime: minBufferTime || 0,
501
- sequenceMode: false,
501
+ sequenceMode: this.config_.dash.sequenceMode,
502
502
  };
503
503
 
504
504
  // We only need to do clock sync when we're using presentation start