rx-player 4.0.0-beta.1 → 4.0.0-beta.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.
Files changed (169) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/CONTRIBUTING.md +48 -168
  3. package/FILES.md +40 -92
  4. package/VERSION +1 -1
  5. package/dist/_esm5.processed/compat/browser_detection.d.ts +3 -1
  6. package/dist/_esm5.processed/compat/browser_detection.js +7 -2
  7. package/dist/_esm5.processed/compat/eme/load_session.js +1 -1
  8. package/dist/_esm5.processed/compat/has_issues_with_high_media_source_duration.d.ts +21 -0
  9. package/dist/_esm5.processed/compat/has_issues_with_high_media_source_duration.js +26 -0
  10. package/dist/_esm5.processed/config.d.ts +2 -0
  11. package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +5 -4
  12. package/dist/_esm5.processed/core/adaptive/buffer_based_chooser.d.ts +18 -1
  13. package/dist/_esm5.processed/core/adaptive/buffer_based_chooser.js +106 -25
  14. package/dist/_esm5.processed/core/adaptive/guess_based_chooser.js +6 -6
  15. package/dist/_esm5.processed/core/adaptive/network_analyzer.js +8 -5
  16. package/dist/_esm5.processed/core/adaptive/utils/representation_score_calculator.d.ts +19 -1
  17. package/dist/_esm5.processed/core/adaptive/utils/representation_score_calculator.js +1 -1
  18. package/dist/_esm5.processed/core/api/debug/render.js +1 -1
  19. package/dist/_esm5.processed/core/api/playback_observer.js +1 -0
  20. package/dist/_esm5.processed/core/api/public_api.d.ts +54 -1
  21. package/dist/_esm5.processed/core/api/public_api.js +232 -35
  22. package/dist/_esm5.processed/core/api/track_management/media_element_tracks_store.js +10 -1
  23. package/dist/_esm5.processed/core/api/track_management/track_dispatcher.d.ts +13 -1
  24. package/dist/_esm5.processed/core/api/track_management/track_dispatcher.js +30 -15
  25. package/dist/_esm5.processed/core/api/track_management/tracks_store.d.ts +3 -1
  26. package/dist/_esm5.processed/core/api/track_management/tracks_store.js +67 -152
  27. package/dist/_esm5.processed/core/api/utils.d.ts +10 -0
  28. package/dist/_esm5.processed/core/api/utils.js +20 -0
  29. package/dist/_esm5.processed/core/decrypt/session_events_listener.js +7 -1
  30. package/dist/_esm5.processed/core/decrypt/utils/clean_old_loaded_sessions.js +2 -0
  31. package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.js +5 -1
  32. package/dist/_esm5.processed/core/init/directfile_content_initializer.js +1 -1
  33. package/dist/_esm5.processed/core/init/media_source_content_initializer.js +47 -10
  34. package/dist/_esm5.processed/core/init/types.d.ts +9 -1
  35. package/dist/_esm5.processed/core/init/utils/content_time_boundaries_observer.d.ts +28 -1
  36. package/dist/_esm5.processed/core/init/utils/content_time_boundaries_observer.js +22 -9
  37. package/dist/_esm5.processed/core/init/utils/media_source_duration_updater.d.ts +58 -0
  38. package/dist/_esm5.processed/core/init/utils/{media_duration_updater.js → media_source_duration_updater.js} +84 -87
  39. package/dist/_esm5.processed/core/init/utils/rebuffering_controller.d.ts +36 -2
  40. package/dist/_esm5.processed/core/init/utils/rebuffering_controller.js +82 -2
  41. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.d.ts +18 -7
  42. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +31 -40
  43. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.d.ts +8 -0
  44. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +12 -0
  45. package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.d.ts +8 -0
  46. package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +12 -0
  47. package/dist/_esm5.processed/core/segment_buffers/implementations/types.d.ts +11 -4
  48. package/dist/_esm5.processed/core/segment_buffers/index.d.ts +2 -2
  49. package/dist/_esm5.processed/core/stream/adaptation/utils/create_representation_estimator.d.ts +47 -0
  50. package/dist/_esm5.processed/core/stream/adaptation/utils/create_representation_estimator.js +70 -0
  51. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +15 -8
  52. package/dist/_esm5.processed/core/stream/period/period_stream.js +1 -1
  53. package/dist/_esm5.processed/core/stream/representation/representation_stream.js +22 -13
  54. package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.d.ts +4 -2
  55. package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.js +2 -2
  56. package/dist/_esm5.processed/core/stream/representation/utils/push_init_segment.d.ts +3 -2
  57. package/dist/_esm5.processed/core/stream/representation/utils/push_init_segment.js +8 -8
  58. package/dist/_esm5.processed/core/stream/representation/utils/push_media_segment.d.ts +2 -2
  59. package/dist/_esm5.processed/core/stream/representation/utils/push_media_segment.js +2 -3
  60. package/dist/_esm5.processed/default_config.d.ts +25 -0
  61. package/dist/_esm5.processed/default_config.js +27 -2
  62. package/dist/_esm5.processed/errors/index.d.ts +2 -2
  63. package/dist/_esm5.processed/errors/media_error.d.ts +23 -1
  64. package/dist/_esm5.processed/errors/media_error.js +18 -5
  65. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_and_push_segment.d.ts +1 -1
  66. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_and_push_segment.js +8 -7
  67. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +17 -9
  68. package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/index.js +0 -2
  69. package/dist/_esm5.processed/manifest/adaptation.d.ts +21 -2
  70. package/dist/_esm5.processed/manifest/adaptation.js +76 -1
  71. package/dist/_esm5.processed/manifest/manifest.js +1 -1
  72. package/dist/_esm5.processed/manifest/period.js +2 -2
  73. package/dist/_esm5.processed/manifest/representation.d.ts +33 -2
  74. package/dist/_esm5.processed/manifest/representation.js +21 -0
  75. package/dist/_esm5.processed/manifest/utils.js +1 -3
  76. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/parse_from_document.d.ts +1 -1
  77. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/parse_from_document.js +1 -1
  78. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.js +1 -0
  79. package/dist/_esm5.processed/public_types.d.ts +13 -3
  80. package/dist/_esm5.processed/tools/TextTrackRenderer/text_track_renderer.js +1 -1
  81. package/dist/_esm5.processed/transports/smooth/isobmff/create_boxes.d.ts +4 -6
  82. package/dist/_esm5.processed/transports/smooth/isobmff/create_boxes.js +4 -6
  83. package/dist/_esm5.processed/utils/is_null_or_undefined.d.ts +1 -1
  84. package/dist/_esm5.processed/utils/is_null_or_undefined.js +1 -1
  85. package/dist/mpd-parser.wasm +0 -0
  86. package/dist/rx-player.js +4709 -4218
  87. package/dist/rx-player.min.js +1 -1
  88. package/package.json +42 -36
  89. package/scripts/build/generate_build.js +1 -1
  90. package/scripts/fast_demo_build.js +4 -3
  91. package/scripts/generate_full_demo.js +1 -1
  92. package/sonar-project.properties +1 -1
  93. package/src/compat/browser_detection.ts +7 -1
  94. package/src/compat/eme/load_session.ts +1 -1
  95. package/src/compat/has_issues_with_high_media_source_duration.ts +27 -0
  96. package/src/core/adaptive/__tests__/buffer_based_chooser.test.ts +147 -48
  97. package/src/core/adaptive/adaptive_representation_selector.ts +7 -4
  98. package/src/core/adaptive/buffer_based_chooser.ts +144 -26
  99. package/src/core/adaptive/guess_based_chooser.ts +9 -8
  100. package/src/core/adaptive/network_analyzer.ts +9 -4
  101. package/src/core/adaptive/utils/representation_score_calculator.ts +22 -2
  102. package/src/core/api/debug/render.ts +1 -1
  103. package/src/core/api/playback_observer.ts +1 -0
  104. package/src/core/api/public_api.ts +277 -44
  105. package/src/core/api/track_management/media_element_tracks_store.ts +17 -8
  106. package/src/core/api/track_management/track_dispatcher.ts +37 -14
  107. package/src/core/api/track_management/tracks_store.ts +77 -167
  108. package/src/core/api/utils.ts +26 -0
  109. package/src/core/decrypt/session_events_listener.ts +6 -1
  110. package/src/core/decrypt/utils/clean_old_loaded_sessions.ts +2 -1
  111. package/src/core/decrypt/utils/loaded_sessions_store.ts +8 -1
  112. package/src/core/init/directfile_content_initializer.ts +1 -0
  113. package/src/core/init/media_source_content_initializer.ts +52 -9
  114. package/src/core/init/types.ts +9 -1
  115. package/src/core/init/utils/content_time_boundaries_observer.ts +46 -10
  116. package/src/core/init/utils/{media_duration_updater.ts → media_source_duration_updater.ts} +100 -112
  117. package/src/core/init/utils/rebuffering_controller.ts +114 -3
  118. package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +56 -55
  119. package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +16 -0
  120. package/src/core/segment_buffers/implementations/text/native/native_text_segment_buffer.ts +16 -0
  121. package/src/core/segment_buffers/implementations/types.ts +16 -4
  122. package/src/core/segment_buffers/index.ts +2 -0
  123. package/src/core/stream/adaptation/utils/create_representation_estimator.ts +114 -0
  124. package/src/core/stream/orchestrator/stream_orchestrator.ts +16 -8
  125. package/src/core/stream/period/period_stream.ts +2 -1
  126. package/src/core/stream/representation/representation_stream.ts +34 -22
  127. package/src/core/stream/representation/utils/append_segment_to_buffer.ts +8 -3
  128. package/src/core/stream/representation/utils/push_init_segment.ts +11 -6
  129. package/src/core/stream/representation/utils/push_media_segment.ts +3 -3
  130. package/src/default_config.ts +29 -2
  131. package/src/errors/__tests__/media_error.test.ts +6 -6
  132. package/src/errors/index.ts +4 -1
  133. package/src/errors/media_error.ts +67 -1
  134. package/src/experimental/tools/VideoThumbnailLoader/load_and_push_segment.ts +10 -7
  135. package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.ts +17 -6
  136. package/src/experimental/tools/mediaCapabilitiesProber/index.ts +0 -4
  137. package/src/manifest/__tests__/manifest.test.ts +7 -7
  138. package/src/manifest/__tests__/period.test.ts +90 -45
  139. package/src/manifest/adaptation.ts +89 -1
  140. package/src/manifest/manifest.ts +1 -1
  141. package/src/manifest/period.ts +4 -2
  142. package/src/manifest/representation.ts +67 -1
  143. package/src/manifest/utils.ts +1 -3
  144. package/src/parsers/manifest/dash/js-parser/parse_from_document.ts +1 -1
  145. package/src/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.ts +1 -0
  146. package/src/parsers/texttracks/ttml/parse_ttml.ts +1 -1
  147. package/src/public_types.ts +16 -1
  148. package/src/tools/TextTrackRenderer/text_track_renderer.ts +1 -1
  149. package/src/transports/smooth/isobmff/create_boxes.ts +4 -6
  150. package/src/typings/globals.d.ts +20 -20
  151. package/src/utils/is_null_or_undefined.ts +1 -1
  152. package/dist/_esm5.processed/core/init/utils/media_duration_updater.d.ts +0 -56
  153. package/scripts/doc-generator/construct_table_of_contents.js +0 -76
  154. package/scripts/doc-generator/convert_MD_to_HMTL.js +0 -26
  155. package/scripts/doc-generator/create_documentation.js +0 -331
  156. package/scripts/doc-generator/create_documentation_page.js +0 -209
  157. package/scripts/doc-generator/create_page.js +0 -210
  158. package/scripts/doc-generator/generate_header_html.js +0 -147
  159. package/scripts/doc-generator/generate_page_html.js +0 -115
  160. package/scripts/doc-generator/generate_page_list_html.js +0 -92
  161. package/scripts/doc-generator/generate_sidebar_html.js +0 -85
  162. package/scripts/doc-generator/get_search_data_for_content.js +0 -137
  163. package/scripts/doc-generator/index.js +0 -34
  164. package/scripts/doc-generator/parse_doc_configs.js +0 -327
  165. package/scripts/doc-generator/scripts/lunr.js +0 -10
  166. package/scripts/doc-generator/scripts/script.js +0 -451
  167. package/scripts/doc-generator/styles/code.css +0 -99
  168. package/scripts/doc-generator/styles/style.css +0 -835
  169. package/scripts/doc-generator/utils.js +0 -74
@@ -149,25 +149,30 @@ describe("Manifest - Period", () => {
149
149
  const videoAda1 = { type: "video",
150
150
  id: "54",
151
151
  isSupported: true,
152
- representations: [{}] };
152
+ representations: [{}],
153
+ toVideoTrack() { return videoAda1; } };
153
154
  const videoAda2 = { type: "video",
154
155
  id: "56",
155
156
  isSupported: true,
156
- representations: [{}] };
157
+ representations: [{}],
158
+ toVideoTrack() { return videoAda2; } };
157
159
  const videoAda3 = { type: "video",
158
160
  id: "57",
159
161
  isSupported: true,
160
- representations: [{}] };
162
+ representations: [{}],
163
+ toVideoTrack() { return videoAda3; } };
161
164
  const video = [videoAda1, videoAda2, videoAda3];
162
165
 
163
166
  const audioAda1 = { type: "audio",
164
167
  id: "58",
165
168
  isSupported: true,
166
- representations: [] };
169
+ representations: [],
170
+ toAudioTrack() { return audioAda1; } };
167
171
  const audioAda2 = { type: "audio",
168
172
  id: "59",
169
173
  isSupported: true,
170
- representations: [] };
174
+ representations: [],
175
+ toAudioTrack() { return audioAda2; } };
171
176
  const audio = [audioAda1, audioAda2];
172
177
  const args = { id: "12", adaptations: { video, audio }, start: 0 };
173
178
  let period = null;
@@ -205,25 +210,30 @@ describe("Manifest - Period", () => {
205
210
  const videoAda1 = { type: "video",
206
211
  id: "54",
207
212
  isSupported: true,
208
- representations: [{}] };
213
+ representations: [{}],
214
+ toVideoTrack() { return videoAda1; } };
209
215
  const videoAda2 = { type: "video",
210
216
  id: "55",
211
217
  isSupported: true,
212
- representations: [{}] };
218
+ representations: [{}],
219
+ toVideoTrack() { return videoAda2; } };
213
220
  const videoAda3 = { type: "video",
214
221
  id: "56",
215
222
  isSupported: true,
216
- representations: [{}] };
223
+ representations: [{}],
224
+ toVideoTrack() { return videoAda3; } };
217
225
  const video = [videoAda1, videoAda2, videoAda3];
218
226
 
219
227
  const audioAda1 = { type: "audio",
220
228
  id: "57",
221
229
  isSupported: false,
222
- representations: [{}] };
230
+ representations: [{}],
231
+ toAudioTrack() { return audioAda1; } };
223
232
  const audioAda2 = { type: "audio",
224
233
  id: "58",
225
234
  isSupported: false,
226
- representations: [{}] };
235
+ representations: [{}],
236
+ toAudioTrack() { return audioAda1; } };
227
237
  const audio = [audioAda1, audioAda2];
228
238
  const args = { id: "12", adaptations: { video, audio }, start: 0 };
229
239
  let period = null;
@@ -261,25 +271,30 @@ describe("Manifest - Period", () => {
261
271
  const videoAda1 = { type: "video",
262
272
  id: "54",
263
273
  isSupported: true,
264
- representations: [] };
274
+ representations: [],
275
+ toVideoTrack() { return videoAda1; } };
265
276
  const videoAda2 = { type: "video",
266
277
  id: "55",
267
278
  isSupported: true,
268
- representations: [] };
279
+ representations: [],
280
+ toVideoTrack() { return videoAda2; } };
269
281
  const videoAda3 = { type: "video",
270
282
  id: "56",
271
283
  isSupported: true,
272
- representations: [] };
284
+ representations: [],
285
+ toVideoTrack() { return videoAda3; } };
273
286
  const video = [videoAda1, videoAda2, videoAda3];
274
287
 
275
288
  const audioAda1 = { type: "audio",
276
289
  id: "58",
277
290
  isSupported: true,
278
- representations: [{}] };
291
+ representations: [{}],
292
+ toAudioTrack() { return audioAda1; } };
279
293
  const audioAda2 = { type: "audio",
280
294
  id: "59",
281
295
  isSupported: true,
282
- representations: [{}] };
296
+ representations: [{}],
297
+ toAudioTrack() { return audioAda2; } };
283
298
  const audio = [audioAda1, audioAda2];
284
299
  const args = { id: "12", adaptations: { video, audio }, start: 0 };
285
300
  let period = null;
@@ -317,25 +332,30 @@ describe("Manifest - Period", () => {
317
332
  const videoAda1 = { type: "video",
318
333
  id: "54",
319
334
  isSupported: false,
320
- representations: [{}] };
335
+ representations: [{}],
336
+ toVideoTrack() { return videoAda1; } };
321
337
  const videoAda2 = { type: "video",
322
338
  id: "55",
323
339
  isSupported: false,
324
- representations: [{}] };
340
+ representations: [{}],
341
+ toVideoTrack() { return videoAda2; } };
325
342
  const videoAda3 = { type: "video",
326
343
  id: "56",
327
344
  isSupported: false,
328
- representations: [{}] };
345
+ representations: [{}],
346
+ toVideoTrack() { return videoAda3; } };
329
347
  const video = [videoAda1, videoAda2, videoAda3];
330
348
 
331
349
  const audioAda1 = { type: "audio",
332
350
  id: "58",
333
351
  isSupported: true,
334
- representations: [{}] };
352
+ representations: [{}],
353
+ toAudioTrack() { return audioAda1; } };
335
354
  const audioAda2 = { type: "audio",
336
355
  id: "59",
337
356
  isSupported: true,
338
- representations: [{}] };
357
+ representations: [{}],
358
+ toAudioTrack() { return audioAda2; } };
339
359
  const audio = [audioAda1, audioAda2];
340
360
  const args = { id: "12", adaptations: { video, audio }, start: 0 };
341
361
  let period = null;
@@ -376,12 +396,14 @@ describe("Manifest - Period", () => {
376
396
  const videoAda1 = { type: "video",
377
397
  id: "55",
378
398
  isSupported: true,
379
- representations: [{}] };
399
+ representations: [{}],
400
+ toVideoTrack() { return videoAda1; } };
380
401
  const video = [videoAda1];
381
402
  const videoAda2 = { type: "video",
382
403
  id: "55",
383
404
  isSupported: false,
384
- representations: [{}] };
405
+ representations: [{}],
406
+ toVideoTrack() { return videoAda2; } };
385
407
  const video2 = [videoAda2];
386
408
  const args = { id: "12", adaptations: { video, video2 }, start: 0 };
387
409
  const period = new Period(args);
@@ -412,7 +434,8 @@ describe("Manifest - Period", () => {
412
434
  const videoAda1 = { type: "video",
413
435
  id: "55",
414
436
  isSupported: true,
415
- representations: [{}] };
437
+ representations: [{}],
438
+ toVideoTrack() { return videoAda1; } };
416
439
  const video = [videoAda1];
417
440
  const bar = undefined;
418
441
  const args = { id: "12", adaptations: { bar, video }, start: 0 };
@@ -439,11 +462,13 @@ describe("Manifest - Period", () => {
439
462
  const videoAda1 = { type: "video",
440
463
  id: "54",
441
464
  isSupported: true,
442
- representations: [{}] };
465
+ representations: [{}],
466
+ toVideoTrack() { return videoAda1; } };
443
467
  const videoAda2 = { type: "video",
444
468
  id: "55",
445
469
  isSupported: true,
446
- representations: [{}] };
470
+ representations: [{}],
471
+ toVideoTrack() { return videoAda2; } };
447
472
  const video = [videoAda1, videoAda2];
448
473
  const args = { id: "12", adaptations: { video }, start: 0 };
449
474
  const period = new Period(args, representationFilter);
@@ -471,11 +496,13 @@ describe("Manifest - Period", () => {
471
496
  const videoAda1 = { type: "video",
472
497
  id: "54",
473
498
  isSupported: false,
474
- representations: [{}] };
499
+ representations: [{}],
500
+ toVideoTrack() { return videoAda1; } };
475
501
  const videoAda2 = { type: "video",
476
502
  id: "55",
477
503
  isSupported: true,
478
- representations: [{}] };
504
+ representations: [{}],
505
+ toVideoTrack() { return videoAda2; } };
479
506
  const fooAda1 = { type: "foo",
480
507
  id: "12",
481
508
  isSupported: false,
@@ -507,11 +534,13 @@ describe("Manifest - Period", () => {
507
534
  const videoAda1 = { type: "video",
508
535
  id: "54",
509
536
  isSupported: false,
510
- representations: [] };
537
+ representations: [],
538
+ toVideoTrack() { return videoAda1; } };
511
539
  const videoAda2 = { type: "video",
512
540
  id: "55",
513
541
  isSupported: true,
514
- representations: [{}] };
542
+ representations: [{}],
543
+ toVideoTrack() { return videoAda2; } };
515
544
  const fooAda1 = { type: "foo",
516
545
  id: "12",
517
546
  isSupported: false,
@@ -536,11 +565,13 @@ describe("Manifest - Period", () => {
536
565
  const videoAda1 = { type: "video",
537
566
  id: "54",
538
567
  isSupported: true,
539
- representations: [{}] };
568
+ representations: [{}],
569
+ toVideoTrack() { return videoAda1; } };
540
570
  const videoAda2 = { type: "video",
541
571
  id: "55",
542
572
  isSupported: true,
543
- representations: [{}] };
573
+ representations: [{}],
574
+ toVideoTrack() { return videoAda2; } };
544
575
  const video = [videoAda1, videoAda2];
545
576
  const args = { id: "12", adaptations: { video }, start: 72 };
546
577
  const period = new Period(args);
@@ -561,11 +592,13 @@ describe("Manifest - Period", () => {
561
592
  const videoAda1 = { type: "video",
562
593
  id: "54",
563
594
  isSupported: true,
564
- representations: [{}] };
595
+ representations: [{}],
596
+ toVideoTrack() { return videoAda1; } };
565
597
  const videoAda2 = { type: "video",
566
598
  id: "55",
567
599
  isSupported: true,
568
- representations: [{}] };
600
+ representations: [{}],
601
+ toVideoTrack() { return videoAda2; } };
569
602
  const video = [videoAda1, videoAda2];
570
603
  const args = { id: "12", adaptations: { video }, start: 0, duration: 12 };
571
604
  const period = new Period(args);
@@ -586,11 +619,13 @@ describe("Manifest - Period", () => {
586
619
  const videoAda1 = { type: "video",
587
620
  id: "54",
588
621
  isSupported: true,
589
- representations: [{}] };
622
+ representations: [{}],
623
+ toVideoTrack() { return videoAda1; } };
590
624
  const videoAda2 = { type: "video",
591
625
  id: "55",
592
626
  isSupported: true,
593
- representations: [{}] };
627
+ representations: [{}],
628
+ toVideoTrack() { return videoAda2; } };
594
629
  const video = [videoAda1, videoAda2];
595
630
  const args = { id: "12", adaptations: { video }, start: 50, duration: 12 };
596
631
  const period = new Period(args);
@@ -611,17 +646,20 @@ describe("Manifest - Period", () => {
611
646
  const videoAda1 = { type: "video",
612
647
  id: "54",
613
648
  isSupported: true,
614
- representations: [{}] };
649
+ representations: [{}],
650
+ toVideoTrack() { return videoAda1; } };
615
651
  const videoAda2 = { type: "video",
616
652
  id: "55",
617
653
  isSupported: true,
618
- representations: [{}] };
654
+ representations: [{}],
655
+ toVideoTrack() { return videoAda2; } };
619
656
  const video = [videoAda1, videoAda2];
620
657
 
621
658
  const audioAda1 = { type: "audio",
622
659
  id: "56",
623
660
  isSupported: true,
624
- representations: [{}] };
661
+ representations: [{}],
662
+ toAudioTrack() { return audioAda1; } };
625
663
  const audio = [audioAda1];
626
664
 
627
665
  const args = { id: "12", adaptations: { video, audio }, start: 50, duration: 12 };
@@ -647,17 +685,20 @@ describe("Manifest - Period", () => {
647
685
  const videoAda1 = { type: "video",
648
686
  id: "54",
649
687
  isSupported: true,
650
- representations: [{}] };
688
+ representations: [{}],
689
+ toVideoTrack() { return videoAda1; } };
651
690
  const videoAda2 = { type: "video",
652
691
  id: "55",
653
692
  isSupported: true,
654
- representations: [{}] };
693
+ representations: [{}],
694
+ toVideoTrack() { return videoAda2; } };
655
695
  const video = [videoAda1, videoAda2];
656
696
 
657
697
  const audioAda1 = { type: "audio",
658
698
  id: "56",
659
699
  isSupported: true,
660
- representations: [{}] };
700
+ representations: [{}],
701
+ toAudioTrack() { return audioAda1; } };
661
702
  const audio = [audioAda1];
662
703
 
663
704
  const args = { id: "12", adaptations: { video, audio }, start: 50, duration: 12 };
@@ -689,21 +730,25 @@ describe("Manifest - Period", () => {
689
730
  const videoAda1 = { type: "video",
690
731
  id: "54",
691
732
  isSupported: true,
692
- representations: [{}] };
733
+ representations: [{}],
734
+ toVideoTrack() { return videoAda1; } };
693
735
  const videoAda2 = { type: "video",
694
736
  id: "55",
695
737
  isSupported: true,
696
- representations: [{}] };
738
+ representations: [{}],
739
+ toVideoTrack() { return videoAda2; } };
697
740
  const videoAda3 = { type: "video",
698
741
  id: "55",
699
742
  isSupported: true,
700
- representations: [{}] };
743
+ representations: [{}],
744
+ toVideoTrack() { return videoAda3; } };
701
745
  const video = [videoAda1, videoAda2, videoAda3];
702
746
 
703
747
  const audioAda1 = { type: "audio",
704
748
  id: "56",
705
749
  isSupported: true,
706
- representations: [{}] };
750
+ representations: [{}],
751
+ toAudioTrack() { return audioAda1; } };
707
752
  const audio = [audioAda1];
708
753
 
709
754
  const args = { id: "12", adaptations: { video, audio }, start: 50, duration: 12 };
@@ -17,8 +17,11 @@
17
17
  import log from "../log";
18
18
  import { IParsedAdaptation } from "../parsers/manifest";
19
19
  import {
20
+ IAudioTrack,
20
21
  ITrackType,
21
22
  IRepresentationFilter,
23
+ ITextTrack,
24
+ IVideoTrack,
22
25
  IRepresentationFilterRepresentation,
23
26
  } from "../public_types";
24
27
  import arrayFind from "../utils/array_find";
@@ -31,7 +34,7 @@ export const SUPPORTED_ADAPTATIONS_TYPE: ITrackType[] = ["audio", "video", "text
31
34
 
32
35
  /**
33
36
  * Normalized Adaptation structure.
34
- * An Adaptation describes a single `Track`. For example a specific audio
37
+ * An `Adaptation` describes a single `Track`. For example a specific audio
35
38
  * track (in a given language) or a specific video track.
36
39
  * It istelf can be represented in different qualities, which we call here
37
40
  * `Representation`.
@@ -216,4 +219,89 @@ export default class Adaptation {
216
219
  getRepresentation(wantedId : number|string) : Representation|undefined {
217
220
  return arrayFind(this.representations, ({ id }) => wantedId === id);
218
221
  }
222
+
223
+ /**
224
+ * Format an `Adaptation`, generally of type `"audio"`, as an `IAudioTrack`.
225
+ * @param {boolean} filterPlayable - If `true` only "playable" Representation
226
+ * will be returned.
227
+ * @returns {Object}
228
+ */
229
+ public toAudioTrack(filterPlayable: boolean) : IAudioTrack {
230
+ const formatted : IAudioTrack = {
231
+ language: this.language ?? "",
232
+ normalized: this.normalizedLanguage ?? "",
233
+ audioDescription: this.isAudioDescription === true,
234
+ id: this.id,
235
+ representations: (
236
+ filterPlayable ?
237
+ this.getPlayableRepresentations() :
238
+ this.representations
239
+ ).map(r => r.toAudioRepresentation()),
240
+ label: this.label,
241
+ };
242
+ if (this.isDub === true) {
243
+ formatted.dub = true;
244
+ }
245
+ return formatted;
246
+ }
247
+
248
+ /**
249
+ * Format an `Adaptation`, generally of type `"audio"`, as an `IAudioTrack`.
250
+ * @returns {Object}
251
+ */
252
+ public toTextTrack() : ITextTrack {
253
+ return {
254
+ language: this.language ?? "",
255
+ normalized: this.normalizedLanguage ?? "",
256
+ closedCaption: this.isClosedCaption === true,
257
+ id: this.id,
258
+ label: this.label,
259
+ forced: this.isForcedSubtitles,
260
+ };
261
+ }
262
+
263
+ /**
264
+ * Format an `Adaptation`, generally of type `"video"`, as an `IAudioTrack`.
265
+ * @param {boolean} filterPlayable - If `true` only "playable" Representation
266
+ * will be returned.
267
+ * @returns {Object}
268
+ */
269
+ public toVideoTrack(filterPlayable: boolean) : IVideoTrack {
270
+ const trickModeTracks = this.trickModeTracks !== undefined ?
271
+ this.trickModeTracks.map((trickModeAdaptation) => {
272
+ const representations = (
273
+ filterPlayable ?
274
+ trickModeAdaptation.getPlayableRepresentations() :
275
+ trickModeAdaptation.representations
276
+ ).map(r => r.toVideoRepresentation());
277
+ const trickMode : IVideoTrack = { id: trickModeAdaptation.id,
278
+ representations,
279
+ isTrickModeTrack: true };
280
+ if (trickModeAdaptation.isSignInterpreted === true) {
281
+ trickMode.signInterpreted = true;
282
+ }
283
+ return trickMode;
284
+ }) :
285
+ undefined;
286
+
287
+ const videoTrack: IVideoTrack = {
288
+ id: this.id,
289
+ representations: (
290
+ filterPlayable ?
291
+ this.getPlayableRepresentations() :
292
+ this.representations
293
+ ).map(r => r.toVideoRepresentation()),
294
+ label: this.label,
295
+ };
296
+ if (this.isSignInterpreted === true) {
297
+ videoTrack.signInterpreted = true;
298
+ }
299
+ if (this.isTrickModeTrack === true) {
300
+ videoTrack.isTrickModeTrack = true;
301
+ }
302
+ if (trickModeTracks !== undefined) {
303
+ videoTrack.trickModeTracks = trickModeTracks;
304
+ }
305
+ return videoTrack;
306
+ }
219
307
  }
@@ -626,10 +626,10 @@ function updateDeciperability(
626
626
  const result = isDecipherable(representation);
627
627
  if (result !== representation.decipherable) {
628
628
  updates.push({ manifest, period, adaptation, representation });
629
+ representation.decipherable = result;
629
630
  log.debug(`Decipherability changed for "${representation.id}"`,
630
631
  `(${representation.bitrate})`,
631
632
  String(representation.decipherable));
632
- representation.decipherable = result;
633
633
  }
634
634
  }
635
635
  }
@@ -89,7 +89,8 @@ export default class Period {
89
89
  if (newAdaptation.representations.length > 0 && !newAdaptation.isSupported) {
90
90
  const error =
91
91
  new MediaError("MANIFEST_INCOMPATIBLE_CODECS_ERROR",
92
- "An Adaptation contains only incompatible codecs.");
92
+ "An Adaptation contains only incompatible codecs.",
93
+ { adaptation: newAdaptation });
93
94
  this.contentWarnings.push(error);
94
95
  }
95
96
  return newAdaptation;
@@ -102,7 +103,8 @@ export default class Period {
102
103
  (type === "video" || type === "audio")
103
104
  ) {
104
105
  throw new MediaError("MANIFEST_INCOMPATIBLE_CODECS_ERROR",
105
- "No supported " + type + " adaptations");
106
+ "No supported " + type + " adaptations",
107
+ { adaptation: undefined });
106
108
  }
107
109
 
108
110
  if (filteredAdaptations.length > 0) {
@@ -22,20 +22,47 @@ import {
22
22
  IParsedRepresentation,
23
23
  } from "../parsers/manifest";
24
24
  import {
25
+ IAudioRepresentation,
25
26
  ITrackType,
26
27
  IHDRInformation,
28
+ IVideoRepresentation,
27
29
  } from "../public_types";
28
30
  import areArraysOfNumbersEqual from "../utils/are_arrays_of_numbers_equal";
31
+ import idGenerator from "../utils/id_generator";
29
32
  import { IRepresentationIndex } from "./representation_index";
30
33
 
34
+ const generateRepresentationUniqueId = idGenerator();
35
+
31
36
  /**
32
37
  * Normalized Representation structure.
33
38
  * @class Representation
34
39
  */
35
40
  class Representation {
36
- /** ID uniquely identifying the Representation in the Adaptation. */
41
+ /**
42
+ * ID uniquely identifying the `Representation` in its parent `Adaptation`.
43
+ *
44
+ * This identifier might be linked to an identifier present in the original
45
+ * Manifest file, it is thus the identifier to use to determine if a
46
+ * `Representation` from a refreshed `Manifest` is actually the same one than
47
+ * one in the previously loaded Manifest (as long as the `Adaptation` and
48
+ * `Period` are also the same).
49
+ *
50
+ * For a globally unique identifier regardless of the `Adaptation`, `Period`
51
+ * or even `Manifest`, you can rely on `uniqueId` instead.
52
+ */
37
53
  public readonly id : string;
38
54
 
55
+ /**
56
+ * Globally unique identifier for this `Representation` object.
57
+ *
58
+ * This identifier is guaranteed to be unique for any `Representation`s of all
59
+ * `Manifest` objects created in the current JS Realm.
60
+ * As such, it can be used as an identifier for the JS object itself, whereas
61
+ * `id` is the identifier for the original Manifest's Representation in the
62
+ * scope of its parent `Adaptation`.
63
+ */
64
+ public readonly uniqueId : string;
65
+
39
66
  /**
40
67
  * Interface allowing to get information about segments available for this
41
68
  * Representation.
@@ -115,6 +142,7 @@ class Representation {
115
142
  */
116
143
  constructor(args : IParsedRepresentation, opts : { type : ITrackType }) {
117
144
  this.id = args.id;
145
+ this.uniqueId = generateRepresentationUniqueId();
118
146
  this.bitrate = args.bitrate;
119
147
  this.codec = args.codecs;
120
148
 
@@ -335,6 +363,44 @@ class Representation {
335
363
  return true;
336
364
  }
337
365
 
366
+ /**
367
+ * Format Representation as an `IAudioRepresentation`.
368
+ * @returns {Object}
369
+ */
370
+ public toAudioRepresentation(): IAudioRepresentation {
371
+ const { id, bitrate, codec, isSupported, decipherable } = this;
372
+ return { id,
373
+ bitrate,
374
+ codec,
375
+ isCodecSupported: isSupported,
376
+ seemsDecipherable: decipherable };
377
+ }
378
+
379
+ /**
380
+ * Format Representation as an `IVideoRepresentation`.
381
+ * @returns {Object}
382
+ */
383
+ public toVideoRepresentation(): IVideoRepresentation {
384
+ const { id,
385
+ bitrate,
386
+ frameRate,
387
+ width,
388
+ height,
389
+ codec,
390
+ hdrInfo,
391
+ isSupported,
392
+ decipherable } = this;
393
+ return { id,
394
+ bitrate,
395
+ frameRate,
396
+ width,
397
+ height,
398
+ codec,
399
+ hdrInfo,
400
+ isCodecSupported: isSupported,
401
+ seemsDecipherable: decipherable };
402
+ }
403
+
338
404
  /**
339
405
  * Returns `true` if this Representation can be played (that is: not
340
406
  * undecipherable and with a supported codec).
@@ -37,9 +37,7 @@ export function areSameContent(
37
37
  content2: IBufferedChunkInfos
38
38
  ): boolean {
39
39
  return (content1.segment.id === content2.segment.id &&
40
- content1.representation.id === content2.representation.id &&
41
- content1.adaptation.id === content2.adaptation.id &&
42
- content1.period.id === content2.period.id);
40
+ content1.representation.uniqueId === content2.representation.uniqueId);
43
41
  }
44
42
 
45
43
  /**
@@ -32,7 +32,7 @@ import {
32
32
 
33
33
  /**
34
34
  * Parse MPD through the JS parser, on a `Document` instance.
35
- * @param {Document} manifest - Original manifest as returned by the server
35
+ * @param {Document} document - Original manifest as returned by the server
36
36
  * @param {Object} args - Various parsing options and information.
37
37
  * @returns {Object} - Response returned by the DASH-JS parser.
38
38
  */
@@ -199,6 +199,7 @@ export default class DashWasmParser {
199
199
  "Unknown error";
200
200
  log.warn("DW: Could not create DASH-WASM parser:", message);
201
201
  this.status = "failure";
202
+ throw err;
202
203
  });
203
204
 
204
205
  return this._initProm;
@@ -95,7 +95,7 @@ export default function parseTTMLString(
95
95
 
96
96
  if (xml !== null && xml !== undefined) {
97
97
  const tts = xml.getElementsByTagName("tt");
98
- let tt = tts[0];
98
+ let tt: Element = tts[0];
99
99
  if (tt === undefined) {
100
100
  // EBU-TT sometimes namespaces tt, by "tt:"
101
101
  // Just catch all namespaces to play it safe