rx-player 3.26.2 → 3.26.3-dev.2022021400

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 (218) hide show
  1. package/.github/workflows/perfs.yml +22 -0
  2. package/CHANGELOG.md +19 -1
  3. package/VERSION +1 -1
  4. package/dist/_esm5.processed/compat/eme/custom_media_keys/index.js +6 -2
  5. package/dist/_esm5.processed/core/abr/buffer_based_chooser.d.ts +28 -6
  6. package/dist/_esm5.processed/core/abr/buffer_based_chooser.js +63 -12
  7. package/dist/_esm5.processed/core/abr/network_analyzer.d.ts +1 -1
  8. package/dist/_esm5.processed/core/abr/pending_requests_store.js +3 -5
  9. package/dist/_esm5.processed/core/abr/representation_estimator.d.ts +1 -1
  10. package/dist/_esm5.processed/core/abr/representation_estimator.js +2 -2
  11. package/dist/_esm5.processed/core/api/media_element_track_choice_manager.d.ts +6 -0
  12. package/dist/_esm5.processed/core/api/media_element_track_choice_manager.js +20 -3
  13. package/dist/_esm5.processed/core/api/public_api.d.ts +3 -3
  14. package/dist/_esm5.processed/core/api/public_api.js +2 -2
  15. package/dist/_esm5.processed/core/api/track_choice_manager.d.ts +6 -6
  16. package/dist/_esm5.processed/core/eme/__tests__/__global__/utils.d.ts +0 -2
  17. package/dist/_esm5.processed/core/eme/__tests__/__global__/utils.js +5 -10
  18. package/dist/_esm5.processed/core/eme/find_key_system.js +15 -5
  19. package/dist/_esm5.processed/core/eme/types.d.ts +2 -2
  20. package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.d.ts +4 -4
  21. package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +1 -1
  22. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +2 -2
  23. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +5 -1
  24. package/dist/_esm5.processed/core/fetchers/utils/try_urls_with_backoff.js +1 -1
  25. package/dist/_esm5.processed/core/init/initialize_directfile.d.ts +2 -2
  26. package/dist/_esm5.processed/core/init/initialize_media_source.d.ts +1 -1
  27. package/dist/_esm5.processed/core/init/manifest_update_scheduler.d.ts +4 -4
  28. package/dist/_esm5.processed/core/init/stream_events_emitter/are_same_stream_events.d.ts +4 -4
  29. package/dist/_esm5.processed/core/init/stream_events_emitter/types.d.ts +2 -2
  30. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.d.ts +3 -3
  31. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/text_track_cues_store.js +32 -31
  32. package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.d.ts +4 -4
  33. package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.js +3 -4
  34. package/dist/_esm5.processed/errors/request_error.js +3 -1
  35. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/thumbnail_loader.d.ts +2 -2
  36. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/thumbnail_loader.js +1 -3
  37. package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/api/probeMediaConfiguration.d.ts +1 -1
  38. package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/api/probeMediaConfiguration.js +1 -1
  39. package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/types.d.ts +3 -3
  40. package/dist/_esm5.processed/manifest/adaptation.d.ts +2 -2
  41. package/dist/_esm5.processed/manifest/adaptation.js +3 -1
  42. package/dist/_esm5.processed/manifest/manifest.d.ts +9 -9
  43. package/dist/_esm5.processed/manifest/period.d.ts +3 -3
  44. package/dist/_esm5.processed/manifest/representation.d.ts +2 -2
  45. package/dist/_esm5.processed/manifest/representation_index/types.d.ts +18 -18
  46. package/dist/_esm5.processed/manifest/types.d.ts +3 -3
  47. package/dist/_esm5.processed/parsers/manifest/dash/common/get_hdr_information.d.ts +1 -1
  48. package/dist/_esm5.processed/parsers/manifest/dash/common/get_periods_time_infos.d.ts +3 -3
  49. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/base.d.ts +6 -6
  50. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_init_segment.d.ts +3 -3
  51. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_segments_from_timeline.d.ts +2 -2
  52. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/list.d.ts +14 -14
  53. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.d.ts +17 -17
  54. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/construct_timeline_from_elements.js +1 -1
  55. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.d.ts +28 -20
  56. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.js +19 -4
  57. package/dist/_esm5.processed/parsers/manifest/dash/common/infer_adaptation_type.d.ts +2 -2
  58. package/dist/_esm5.processed/parsers/manifest/dash/common/manifest_bounds_calculator.d.ts +1 -1
  59. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_adaptation_sets.d.ts +17 -35
  60. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_adaptation_sets.js +24 -23
  61. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_mpd.d.ts +8 -8
  62. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_periods.d.ts +18 -27
  63. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_periods.js +25 -23
  64. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representation_index.d.ts +21 -15
  65. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representation_index.js +19 -19
  66. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representations.d.ts +15 -38
  67. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representations.js +8 -8
  68. package/dist/_esm5.processed/parsers/manifest/dash/node_parser_types.d.ts +30 -30
  69. package/dist/_esm5.processed/parsers/manifest/dash/parsers_types.d.ts +3 -3
  70. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.js +1 -1
  71. package/dist/_esm5.processed/parsers/manifest/metaplaylist/metaplaylist_parser.d.ts +2 -2
  72. package/dist/_esm5.processed/parsers/manifest/smooth/create_parser.d.ts +7 -7
  73. package/dist/_esm5.processed/parsers/manifest/smooth/representation_index.d.ts +8 -8
  74. package/dist/_esm5.processed/parsers/manifest/types.d.ts +28 -28
  75. package/dist/_esm5.processed/parsers/manifest/utils/clear_timeline_from_position.d.ts +3 -2
  76. package/dist/_esm5.processed/parsers/manifest/utils/clear_timeline_from_position.js +15 -5
  77. package/dist/_esm5.processed/parsers/manifest/utils/index_helpers.d.ts +2 -2
  78. package/dist/_esm5.processed/parsers/manifest/utils/update_segment_timeline.d.ts +11 -1
  79. package/dist/_esm5.processed/parsers/manifest/utils/update_segment_timeline.js +31 -19
  80. package/dist/_esm5.processed/parsers/texttracks/webvtt/html/to_html.d.ts +2 -2
  81. package/dist/_esm5.processed/parsers/texttracks/webvtt/parse_cue_block.d.ts +1 -1
  82. package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +2 -1
  83. package/dist/_esm5.processed/transports/dash/image_pipelines.js +1 -1
  84. package/dist/_esm5.processed/transports/dash/init_segment_loader.js +1 -1
  85. package/dist/_esm5.processed/transports/dash/manifest_parser.js +1 -1
  86. package/dist/_esm5.processed/transports/dash/segment_loader.d.ts +2 -2
  87. package/dist/_esm5.processed/transports/dash/segment_loader.js +2 -2
  88. package/dist/_esm5.processed/transports/dash/segment_parser.d.ts +1 -1
  89. package/dist/_esm5.processed/transports/dash/text_loader.d.ts +1 -1
  90. package/dist/_esm5.processed/transports/dash/text_loader.js +1 -1
  91. package/dist/_esm5.processed/transports/dash/text_parser.d.ts +1 -1
  92. package/dist/_esm5.processed/transports/local/segment_loader.d.ts +1 -2
  93. package/dist/_esm5.processed/transports/local/segment_loader.js +1 -1
  94. package/dist/_esm5.processed/transports/metaplaylist/manifest_loader.d.ts +1 -1
  95. package/dist/_esm5.processed/transports/metaplaylist/pipelines.js +1 -1
  96. package/dist/_esm5.processed/transports/smooth/pipelines.js +1 -1
  97. package/dist/_esm5.processed/transports/smooth/segment_loader.d.ts +0 -1
  98. package/dist/_esm5.processed/transports/smooth/segment_loader.js +2 -2
  99. package/dist/_esm5.processed/transports/types.d.ts +36 -30
  100. package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.js +1 -1
  101. package/dist/_esm5.processed/transports/utils/generate_manifest_loader.d.ts +1 -1
  102. package/dist/_esm5.processed/utils/cancellable_sleep.js +1 -1
  103. package/dist/_esm5.processed/utils/cast_to_observable.d.ts +1 -2
  104. package/dist/_esm5.processed/utils/cast_to_observable.js +1 -1
  105. package/dist/_esm5.processed/utils/request/fetch.d.ts +4 -5
  106. package/dist/_esm5.processed/utils/request/fetch.js +7 -4
  107. package/dist/_esm5.processed/utils/request/xhr.d.ts +6 -6
  108. package/dist/_esm5.processed/utils/request/xhr.js +2 -1
  109. package/dist/_esm5.processed/utils/rx-from_cancellable_promise.d.ts +1 -2
  110. package/dist/rx-player.js +404 -321
  111. package/dist/rx-player.min.js +1 -1
  112. package/package.json +3 -4
  113. package/scripts/doc-generator/generate_header_html.js +6 -7
  114. package/scripts/doc-generator/generate_page_html.js +3 -4
  115. package/scripts/doc-generator/generate_page_list_html.js +4 -5
  116. package/scripts/doc-generator/generate_sidebar_html.js +4 -7
  117. package/scripts/doc-generator/utils.js +0 -11
  118. package/scripts/generate_demo_list.js +3 -3
  119. package/scripts/generate_documentation_list.js +3 -3
  120. package/scripts/launch_static_server.js +127 -67
  121. package/scripts/run_standalone_demo.js +1 -0
  122. package/scripts/start_demo_web_server.js +1 -0
  123. package/sonar-project.properties +1 -1
  124. package/src/compat/__tests__/fullscreen.test.ts +7 -7
  125. package/src/compat/__tests__/is_vtt_cue.test.ts +1 -1
  126. package/src/compat/eme/custom_media_keys/ie11_media_keys.ts +1 -1
  127. package/src/compat/eme/custom_media_keys/index.ts +7 -3
  128. package/src/core/abr/__tests__/{get_estimate_from_buffer_levels.test.ts → buffer_based_chooser.test.ts} +94 -123
  129. package/src/core/abr/buffer_based_chooser.ts +85 -20
  130. package/src/core/abr/network_analyzer.ts +1 -1
  131. package/src/core/abr/pending_requests_store.ts +3 -5
  132. package/src/core/abr/representation_estimator.ts +6 -3
  133. package/src/core/api/media_element_track_choice_manager.ts +22 -3
  134. package/src/core/api/public_api.ts +6 -6
  135. package/src/core/api/track_choice_manager.ts +10 -9
  136. package/src/core/eme/__tests__/__global__/utils.ts +5 -10
  137. package/src/core/eme/find_key_system.ts +14 -12
  138. package/src/core/eme/types.ts +2 -2
  139. package/src/core/fetchers/manifest/manifest_fetcher.ts +5 -5
  140. package/src/core/fetchers/segment/segment_fetcher.ts +6 -3
  141. package/src/core/fetchers/utils/try_urls_with_backoff.ts +1 -1
  142. package/src/core/init/initialize_directfile.ts +2 -2
  143. package/src/core/init/initialize_media_source.ts +2 -2
  144. package/src/core/init/manifest_update_scheduler.ts +7 -7
  145. package/src/core/init/stream_events_emitter/are_same_stream_events.ts +4 -4
  146. package/src/core/init/stream_events_emitter/types.ts +2 -2
  147. package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +3 -3
  148. package/src/core/segment_buffers/implementations/text/html/text_track_cues_store.ts +32 -31
  149. package/src/core/segment_buffers/implementations/text/native/native_text_segment_buffer.ts +4 -4
  150. package/src/core/stream/representation/force_garbage_collection.ts +3 -5
  151. package/src/errors/request_error.ts +4 -1
  152. package/src/experimental/tools/VideoThumbnailLoader/thumbnail_loader.ts +3 -6
  153. package/src/experimental/tools/mediaCapabilitiesProber/api/index.ts +1 -1
  154. package/src/experimental/tools/mediaCapabilitiesProber/api/probeMediaConfiguration.ts +3 -3
  155. package/src/experimental/tools/mediaCapabilitiesProber/types.ts +3 -3
  156. package/src/manifest/adaptation.ts +6 -4
  157. package/src/manifest/manifest.ts +10 -10
  158. package/src/manifest/period.ts +3 -3
  159. package/src/manifest/representation.ts +2 -2
  160. package/src/manifest/representation_index/types.ts +18 -18
  161. package/src/manifest/types.ts +3 -3
  162. package/src/parsers/manifest/dash/common/__tests__/manifest_bounds_calculator.test.ts +1 -0
  163. package/src/parsers/manifest/dash/common/get_hdr_information.ts +1 -1
  164. package/src/parsers/manifest/dash/common/get_periods_time_infos.ts +3 -3
  165. package/src/parsers/manifest/dash/common/indexes/base.ts +6 -6
  166. package/src/parsers/manifest/dash/common/indexes/get_init_segment.ts +4 -2
  167. package/src/parsers/manifest/dash/common/indexes/get_segments_from_timeline.ts +2 -2
  168. package/src/parsers/manifest/dash/common/indexes/list.ts +14 -14
  169. package/src/parsers/manifest/dash/common/indexes/template.ts +17 -16
  170. package/src/parsers/manifest/dash/common/indexes/timeline/construct_timeline_from_elements.ts +1 -1
  171. package/src/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.ts +50 -22
  172. package/src/parsers/manifest/dash/common/infer_adaptation_type.ts +2 -2
  173. package/src/parsers/manifest/dash/common/manifest_bounds_calculator.ts +1 -1
  174. package/src/parsers/manifest/dash/common/parse_adaptation_sets.ts +58 -70
  175. package/src/parsers/manifest/dash/common/parse_mpd.ts +8 -8
  176. package/src/parsers/manifest/dash/common/parse_periods.ts +80 -79
  177. package/src/parsers/manifest/dash/common/parse_representation_index.ts +83 -75
  178. package/src/parsers/manifest/dash/common/parse_representations.ts +44 -63
  179. package/src/parsers/manifest/dash/node_parser_types.ts +30 -30
  180. package/src/parsers/manifest/dash/parsers_types.ts +3 -3
  181. package/src/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.ts +1 -1
  182. package/src/parsers/manifest/metaplaylist/metaplaylist_parser.ts +4 -4
  183. package/src/parsers/manifest/smooth/create_parser.ts +23 -21
  184. package/src/parsers/manifest/smooth/representation_index.ts +14 -14
  185. package/src/parsers/manifest/types.ts +28 -28
  186. package/src/parsers/manifest/utils/__tests__/update_segment_timeline.test.ts +31 -33
  187. package/src/parsers/manifest/utils/clear_timeline_from_position.ts +15 -6
  188. package/src/parsers/manifest/utils/index_helpers.ts +2 -2
  189. package/src/parsers/manifest/utils/update_segment_timeline.ts +32 -21
  190. package/src/parsers/texttracks/webvtt/html/to_html.ts +2 -2
  191. package/src/parsers/texttracks/webvtt/parse_cue_block.ts +1 -1
  192. package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +2 -2
  193. package/src/transports/dash/image_pipelines.ts +1 -1
  194. package/src/transports/dash/init_segment_loader.ts +1 -1
  195. package/src/transports/dash/manifest_parser.ts +1 -1
  196. package/src/transports/dash/segment_loader.ts +7 -7
  197. package/src/transports/dash/segment_parser.ts +3 -1
  198. package/src/transports/dash/text_loader.ts +2 -2
  199. package/src/transports/dash/text_parser.ts +3 -1
  200. package/src/transports/local/segment_loader.ts +4 -4
  201. package/src/transports/metaplaylist/manifest_loader.ts +1 -1
  202. package/src/transports/metaplaylist/pipelines.ts +1 -1
  203. package/src/transports/smooth/pipelines.ts +7 -7
  204. package/src/transports/smooth/segment_loader.ts +8 -8
  205. package/src/transports/types.ts +37 -30
  206. package/src/transports/utils/call_custom_manifest_loader.ts +6 -6
  207. package/src/transports/utils/generate_manifest_loader.ts +1 -1
  208. package/src/utils/__tests__/flat_map.test.ts +12 -7
  209. package/src/utils/cancellable_sleep.ts +1 -1
  210. package/src/utils/cast_to_observable.ts +1 -2
  211. package/src/utils/request/fetch.ts +16 -13
  212. package/src/utils/request/xhr.ts +9 -7
  213. package/src/utils/rx-from_cancellable_promise.ts +1 -2
  214. package/tsconfig.json +1 -2
  215. package/tsconfig.modules.json +1 -2
  216. package/dist/_esm5.processed/core/abr/get_estimate_from_buffer_levels.d.ts +0 -29
  217. package/dist/_esm5.processed/core/abr/get_estimate_from_buffer_levels.js +0 -67
  218. package/src/core/abr/get_estimate_from_buffer_levels.ts +0 -85
@@ -34,91 +34,55 @@ import {
34
34
  import flattenOverlappingPeriods from "./flatten_overlapping_periods";
35
35
  import getPeriodsTimeInformation from "./get_periods_time_infos";
36
36
  import ManifestBoundsCalculator from "./manifest_bounds_calculator";
37
- import parseAdaptationSets from "./parse_adaptation_sets";
38
- import resolveBaseURLs, {
39
- IResolvedBaseUrl,
40
- } from "./resolve_base_urls";
37
+ import parseAdaptationSets, {
38
+ IAdaptationSetContext,
39
+ } from "./parse_adaptation_sets";
40
+ import resolveBaseURLs from "./resolve_base_urls";
41
41
 
42
42
  const generatePeriodID = idGenerator();
43
43
 
44
44
  /** Information about each linked Xlink. */
45
45
  export type IXLinkInfos = WeakMap<IPeriodIntermediateRepresentation, {
46
46
  /** Real URL (post-redirection) used to download this xlink. */
47
- url? : string;
47
+ url? : string | undefined;
48
48
  /** Time at which the request was sent (since the time origin), in ms. */
49
- sendingTime? : number;
49
+ sendingTime? : number | undefined;
50
50
  /** Time at which the request was received (since the time origin), in ms. */
51
- receivedTime? : number;
51
+ receivedTime? : number | undefined;
52
52
  }>;
53
53
 
54
- /** Context needed when calling `parsePeriods`. */
55
- export interface IPeriodsContextInfos {
56
- /** Whether we should request new segments even if they are not yet finished. */
57
- aggressiveMode : boolean;
58
- availabilityStartTime : number;
59
- baseURLs : IResolvedBaseUrl[];
60
- clockOffset? : number;
61
- duration? : number;
62
- isDynamic : boolean;
63
- manifestProfiles?: string;
64
- /**
65
- * Time (in terms of `performance.now`) at which the XML file containing this
66
- * Period was received.
67
- */
68
- receivedTime? : number;
69
- /** Depth of the buffer for the whole content, in seconds. */
70
- timeShiftBufferDepth? : number;
71
- /**
72
- * The parser should take this Manifest - which is a previously parsed
73
- * Manifest for the same dynamic content - as a base to speed-up the parsing
74
- * process.
75
- * /!\ If unexpected differences exist between the two, there is a risk of
76
- * de-synchronization with what is actually on the server,
77
- * Use with moderation.
78
- */
79
- unsafelyBaseOnPreviousManifest : Manifest | null;
80
- xlinkInfos : IXLinkInfos;
81
-
82
- /**
83
- * XML namespaces linked to the `<MPD>` element.
84
- * May be needed to convert EventStream's Event elements back into the
85
- * Document form.
86
- */
87
- xmlNamespaces? : Array<{ key : string;
88
- value : string; }>;
89
- }
90
-
91
54
  /**
92
55
  * Process intermediate periods to create final parsed periods.
93
56
  * @param {Array.<Object>} periodsIR
94
- * @param {Object} contextInfos
57
+ * @param {Object} context
95
58
  * @returns {Array.<Object>}
96
59
  */
97
60
  export default function parsePeriods(
98
61
  periodsIR : IPeriodIntermediateRepresentation[],
99
- contextInfos : IPeriodsContextInfos
62
+ context : IPeriodContext
100
63
  ): IParsedPeriod[] {
101
64
  const parsedPeriods : IParsedPeriod[] = [];
102
- const periodsTimeInformation = getPeriodsTimeInformation(periodsIR, contextInfos);
65
+ const periodsTimeInformation = getPeriodsTimeInformation(periodsIR, context);
103
66
  if (periodsTimeInformation.length !== periodsIR.length) {
104
67
  throw new Error("MPD parsing error: the time information are incoherent.");
105
68
  }
106
69
 
107
70
  const { isDynamic,
108
- timeShiftBufferDepth } = contextInfos;
71
+ timeShiftBufferDepth } = context;
109
72
  const manifestBoundsCalculator = new ManifestBoundsCalculator({ isDynamic,
110
73
  timeShiftBufferDepth });
111
74
 
112
- if (!isDynamic && contextInfos.duration != null) {
113
- manifestBoundsCalculator.setLastPosition(contextInfos.duration);
75
+ if (!isDynamic && context.duration != null) {
76
+ manifestBoundsCalculator.setLastPosition(context.duration);
114
77
  }
115
78
 
116
79
  // We parse it in reverse because we might need to deduce the buffer depth from
117
80
  // the last Periods' indexes
118
81
  for (let i = periodsIR.length - 1; i >= 0; i--) {
82
+ const isLastPeriod = i === periodsIR.length - 1;
119
83
  const periodIR = periodsIR[i];
120
- const xlinkInfos = contextInfos.xlinkInfos.get(periodIR);
121
- const periodBaseURLs = resolveBaseURLs(contextInfos.baseURLs,
84
+ const xlinkInfos = context.xlinkInfos.get(periodIR);
85
+ const periodBaseURLs = resolveBaseURLs(context.baseURLs,
122
86
  periodIR.children.baseURLs);
123
87
 
124
88
  const { periodStart,
@@ -139,30 +103,32 @@ export default function parsePeriods(
139
103
  }
140
104
 
141
105
  const receivedTime = xlinkInfos !== undefined ? xlinkInfos.receivedTime :
142
- contextInfos.receivedTime;
106
+ context.receivedTime;
143
107
 
144
- const unsafelyBaseOnPreviousPeriod = contextInfos
108
+ const unsafelyBaseOnPreviousPeriod = context
145
109
  .unsafelyBaseOnPreviousManifest?.getPeriod(periodID) ?? null;
146
110
 
147
111
  const availabilityTimeComplete = periodIR.attributes.availabilityTimeComplete ?? true;
148
112
  const availabilityTimeOffset = periodIR.attributes.availabilityTimeOffset ?? 0;
149
- const periodInfos = { aggressiveMode: contextInfos.aggressiveMode,
150
- availabilityTimeComplete,
151
- availabilityTimeOffset,
152
- baseURLs: periodBaseURLs,
153
- manifestBoundsCalculator,
154
- end: periodEnd,
155
- isDynamic,
156
- manifestProfiles: contextInfos.manifestProfiles,
157
- receivedTime,
158
- segmentTemplate: periodIR.children.segmentTemplate,
159
- start: periodStart,
160
- timeShiftBufferDepth,
161
- unsafelyBaseOnPreviousPeriod };
162
- const adaptations = parseAdaptationSets(periodIR.children.adaptations,
163
- periodInfos);
113
+ const { aggressiveMode, manifestProfiles } = context;
114
+ const { segmentTemplate } = periodIR.children;
115
+ const adapCtxt : IAdaptationSetContext = { aggressiveMode,
116
+ availabilityTimeComplete,
117
+ availabilityTimeOffset,
118
+ baseURLs: periodBaseURLs,
119
+ manifestBoundsCalculator,
120
+ end: periodEnd,
121
+ isDynamic,
122
+ isLastPeriod,
123
+ manifestProfiles,
124
+ receivedTime,
125
+ segmentTemplate,
126
+ start: periodStart,
127
+ timeShiftBufferDepth,
128
+ unsafelyBaseOnPreviousPeriod };
129
+ const adaptations = parseAdaptationSets(periodIR.children.adaptations, adapCtxt);
164
130
 
165
- const namespaces = (contextInfos.xmlNamespaces ?? [])
131
+ const namespaces = (context.xmlNamespaces ?? [])
166
132
  .concat(periodIR.attributes.namespaces ?? []);
167
133
  const streamEvents = generateStreamEvents(periodIR.children.eventStreams,
168
134
  periodStart,
@@ -187,7 +153,7 @@ export default function parsePeriods(
187
153
  manifestBoundsCalculator.setLastPosition(lastPosition, positionTime);
188
154
  } else {
189
155
  const guessedLastPositionFromClock =
190
- guessLastPositionFromClock(contextInfos, periodStart);
156
+ guessLastPositionFromClock(context, periodStart);
191
157
  if (guessedLastPositionFromClock !== undefined) {
192
158
  const [guessedLastPosition, guessedPositionTime] =
193
159
  guessedLastPositionFromClock;
@@ -199,9 +165,9 @@ export default function parsePeriods(
199
165
  }
200
166
  }
201
167
 
202
- if (contextInfos.isDynamic && !manifestBoundsCalculator.lastPositionIsKnown()) {
168
+ if (context.isDynamic && !manifestBoundsCalculator.lastPositionIsKnown()) {
203
169
  // Guess a last time the last position
204
- const guessedLastPositionFromClock = guessLastPositionFromClock(contextInfos, 0);
170
+ const guessedLastPositionFromClock = guessLastPositionFromClock(context, 0);
205
171
  if (guessedLastPositionFromClock !== undefined) {
206
172
  const [lastPosition, positionTime] = guessedLastPositionFromClock;
207
173
  manifestBoundsCalculator.setLastPosition(lastPosition, positionTime);
@@ -233,17 +199,17 @@ export default function parsePeriods(
233
199
  * the live time more directly from that previous one, we might be better off
234
200
  * than just using the clock.
235
201
  *
236
- * @param {Object} contextInfos
202
+ * @param {Object} context
237
203
  * @param {number} minimumTime
238
204
  * @returns {Array.<number|undefined>}
239
205
  */
240
206
  function guessLastPositionFromClock(
241
- contextInfos : IPeriodsContextInfos,
207
+ context : IPeriodContext,
242
208
  minimumTime : number
243
209
  ) : [number, number] | undefined {
244
- if (contextInfos.clockOffset != null) {
245
- const lastPosition = contextInfos.clockOffset / 1000 -
246
- contextInfos.availabilityStartTime;
210
+ if (context.clockOffset != null) {
211
+ const lastPosition = context.clockOffset / 1000 -
212
+ context.availabilityStartTime;
247
213
  const positionTime = performance.now() / 1000;
248
214
  const timeInSec = positionTime + lastPosition;
249
215
  if (timeInSec >= minimumTime) {
@@ -254,7 +220,7 @@ function guessLastPositionFromClock(
254
220
  if (now >= minimumTime) {
255
221
  log.warn("DASH Parser: no clock synchronization mechanism found." +
256
222
  " Using the system clock instead.");
257
- const lastPosition = now - contextInfos.availabilityStartTime;
223
+ const lastPosition = now - context.availabilityStartTime;
258
224
  const positionTime = performance.now() / 1000;
259
225
  return [lastPosition, positionTime];
260
226
  }
@@ -366,3 +332,38 @@ function generateStreamEvents(
366
332
  }
367
333
  return res;
368
334
  }
335
+
336
+ /** Context needed when calling `parsePeriods`. */
337
+ export interface IPeriodContext extends IInheritedAdaptationContext {
338
+ availabilityStartTime : number;
339
+ clockOffset? : number | undefined;
340
+ /** Duration (mediaPresentationDuration) of the whole MPD, in seconds. */
341
+ duration? : number | undefined;
342
+ /**
343
+ * The parser should take this Manifest - which is a previously parsed
344
+ * Manifest for the same dynamic content - as a base to speed-up the parsing
345
+ * process.
346
+ * /!\ If unexpected differences exist between the two, there is a risk of
347
+ * de-synchronization with what is actually on the server,
348
+ * Use with moderation.
349
+ */
350
+ unsafelyBaseOnPreviousManifest : Manifest | null;
351
+ xlinkInfos : IXLinkInfos;
352
+
353
+ /**
354
+ * XML namespaces linked to the `<MPD>` element.
355
+ * May be needed to convert EventStream's Event elements back into the
356
+ * Document form.
357
+ */
358
+ xmlNamespaces? : Array<{ key : string;
359
+ value : string; }> | undefined;
360
+ }
361
+
362
+ type IInheritedAdaptationContext = Omit<IAdaptationSetContext,
363
+ "availabilityTimeComplete" |
364
+ "availabilityTimeOffset" |
365
+ "duration" |
366
+ "isLastPeriod" |
367
+ "manifestBoundsCalculator" |
368
+ "start" |
369
+ "unsafelyBaseOnPreviousPeriod">;
@@ -37,61 +37,18 @@ import resolveBaseURLs, {
37
37
  IResolvedBaseUrl,
38
38
  } from "./resolve_base_urls";
39
39
 
40
- /** Supplementary context needed to parse a RepresentationIndex. */
41
- export interface IRepresentationInfos {
42
- /** Parsed AdaptationSet which contains the Representation. */
43
- adaptation : IAdaptationSetIntermediateRepresentation;
44
- /** Whether we should request new segments even if they are not yet finished. */
45
- aggressiveMode : boolean;
46
- availabilityTimeComplete : boolean;
47
- /** availability time offset of the concerned Adaptation. */
48
- availabilityTimeOffset : number;
49
- /** Eventual URLs from which every relative URL will be based on. */
50
- baseURLs : IResolvedBaseUrl[];
51
- /** Allows to obtain the first/last available position of a dynamic content. */
52
- manifestBoundsCalculator : ManifestBoundsCalculator;
53
- /** End time of the current period, in seconds. */
54
- end? : number;
55
- /** Whether the Manifest can evolve with time. */
56
- isDynamic : boolean;
57
- /**
58
- * Parent parsed SegmentTemplate elements.
59
- * Sorted by provenance from higher level (e.g. Period) to lower-lever (e.g.
60
- * AdaptationSet).
61
- */
62
- parentSegmentTemplates : ISegmentTemplateIntermediateRepresentation[];
63
- /**
64
- * Time (in terms of `performance.now`) at which the XML file containing this
65
- * Representation was received.
66
- */
67
- receivedTime? : number;
68
- /** Start time of the current period, in seconds. */
69
- start : number;
70
- /** Depth of the buffer for the whole content, in seconds. */
71
- timeShiftBufferDepth? : number;
72
- /**
73
- * The parser should take this Representation - which is the same as this one
74
- * parsed at an earlier time - as a base to speed-up the parsing process.
75
- * /!\ If unexpected differences exist between both, there is a risk of
76
- * de-synchronization with what is actually on the server.
77
- */
78
- unsafelyBaseOnPreviousRepresentation : Representation | null;
79
- /** List of inband event streams that are present on the representation */
80
- inbandEventStreams: IScheme[] | undefined;
81
- }
82
-
83
40
  /**
84
41
  * Parse the specific segment indexing information found in a representation
85
42
  * into a IRepresentationIndex implementation.
86
43
  * @param {Array.<Object>} representation
87
- * @param {Object} representationInfos
44
+ * @param {Object} context
88
45
  * @returns {Array.<Object>}
89
46
  */
90
47
  export default function parseRepresentationIndex(
91
48
  representation : IRepresentationIntermediateRepresentation,
92
- representationInfos : IRepresentationInfos
49
+ context : IRepresentationIndexContext
93
50
  ) : IRepresentationIndex {
94
- const representationBaseURLs = resolveBaseURLs(representationInfos.baseURLs,
51
+ const representationBaseURLs = resolveBaseURLs(context.baseURLs,
95
52
  representation.children.baseURLs);
96
53
  const { aggressiveMode,
97
54
  availabilityTimeOffset,
@@ -102,7 +59,8 @@ export default function parseRepresentationIndex(
102
59
  receivedTime,
103
60
  timeShiftBufferDepth,
104
61
  unsafelyBaseOnPreviousRepresentation,
105
- inbandEventStreams } = representationInfos;
62
+ inbandEventStreams,
63
+ isLastPeriod } = context;
106
64
 
107
65
  const isEMSGWhitelisted = (inbandEvent: IEMSG): boolean => {
108
66
  if (inbandEventStreams === undefined) {
@@ -111,31 +69,32 @@ export default function parseRepresentationIndex(
111
69
  return inbandEventStreams
112
70
  .some(({ schemeIdUri }) => schemeIdUri === inbandEvent.schemeIdUri);
113
71
  };
114
- const context = { aggressiveMode,
115
- availabilityTimeComplete: true,
116
- availabilityTimeOffset,
117
- unsafelyBaseOnPreviousRepresentation,
118
- isEMSGWhitelisted,
119
- manifestBoundsCalculator,
120
- isDynamic,
121
- periodEnd,
122
- periodStart,
123
- receivedTime,
124
- representationBaseURLs,
125
- representationBitrate: representation.attributes.bitrate,
126
- representationId: representation.attributes.id,
127
- timeShiftBufferDepth };
72
+ const reprIndexCtxt = { aggressiveMode,
73
+ availabilityTimeComplete: true,
74
+ availabilityTimeOffset,
75
+ unsafelyBaseOnPreviousRepresentation,
76
+ isEMSGWhitelisted,
77
+ isLastPeriod,
78
+ manifestBoundsCalculator,
79
+ isDynamic,
80
+ periodEnd,
81
+ periodStart,
82
+ receivedTime,
83
+ representationBaseURLs,
84
+ representationBitrate: representation.attributes.bitrate,
85
+ representationId: representation.attributes.id,
86
+ timeShiftBufferDepth };
128
87
  let representationIndex : IRepresentationIndex;
129
88
  if (representation.children.segmentBase !== undefined) {
130
89
  const { segmentBase } = representation.children;
131
- representationIndex = new BaseRepresentationIndex(segmentBase, context);
90
+ representationIndex = new BaseRepresentationIndex(segmentBase, reprIndexCtxt);
132
91
  } else if (representation.children.segmentList !== undefined) {
133
92
  const { segmentList } = representation.children;
134
- representationIndex = new ListRepresentationIndex(segmentList, context);
93
+ representationIndex = new ListRepresentationIndex(segmentList, reprIndexCtxt);
135
94
  } else if (representation.children.segmentTemplate !== undefined ||
136
- representationInfos.parentSegmentTemplates.length > 0)
95
+ context.parentSegmentTemplates.length > 0)
137
96
  {
138
- const segmentTemplates = representationInfos.parentSegmentTemplates.slice();
97
+ const segmentTemplates = context.parentSegmentTemplates.slice();
139
98
  const childSegmentTemplate = representation.children.segmentTemplate;
140
99
  if (childSegmentTemplate !== undefined) {
141
100
  segmentTemplates.push(childSegmentTemplate);
@@ -145,32 +104,81 @@ export default function parseRepresentationIndex(
145
104
  ...segmentTemplates as [
146
105
  ISegmentTemplateIntermediateRepresentation
147
106
  ] /* Ugly TS Hack */);
148
- context.availabilityTimeComplete =
107
+ reprIndexCtxt.availabilityTimeComplete =
149
108
  segmentTemplate.availabilityTimeComplete ??
150
- representationInfos.availabilityTimeComplete;
151
- context.availabilityTimeOffset =
109
+ context.availabilityTimeComplete;
110
+ reprIndexCtxt.availabilityTimeOffset =
152
111
  (segmentTemplate.availabilityTimeOffset ?? 0) +
153
- representationInfos.availabilityTimeOffset;
112
+ context.availabilityTimeOffset;
154
113
  representationIndex = TimelineRepresentationIndex
155
114
  .isTimelineIndexArgument(segmentTemplate) ?
156
- new TimelineRepresentationIndex(segmentTemplate, context) :
157
- new TemplateRepresentationIndex(segmentTemplate, context);
115
+ new TimelineRepresentationIndex(segmentTemplate, reprIndexCtxt) :
116
+ new TemplateRepresentationIndex(segmentTemplate, reprIndexCtxt);
158
117
  } else {
159
- const adaptationChildren = representationInfos.adaptation.children;
118
+ const adaptationChildren = context.adaptation.children;
160
119
  if (adaptationChildren.segmentBase !== undefined) {
161
120
  const { segmentBase } = adaptationChildren;
162
- representationIndex = new BaseRepresentationIndex(segmentBase, context);
121
+ representationIndex = new BaseRepresentationIndex(segmentBase, reprIndexCtxt);
163
122
  } else if (adaptationChildren.segmentList !== undefined) {
164
123
  const { segmentList } = adaptationChildren;
165
- representationIndex = new ListRepresentationIndex(segmentList, context);
124
+ representationIndex = new ListRepresentationIndex(segmentList, reprIndexCtxt);
166
125
  } else {
167
126
  representationIndex = new TemplateRepresentationIndex({
168
127
  duration: Number.MAX_VALUE,
169
128
  timescale: 1,
170
129
  startNumber: 0,
171
130
  media: "",
172
- }, context);
131
+ }, reprIndexCtxt);
173
132
  }
174
133
  }
175
134
  return representationIndex;
176
135
  }
136
+
137
+ /** Supplementary context needed to parse a RepresentationIndex. */
138
+ export interface IRepresentationIndexContext {
139
+ /** Parsed AdaptationSet which contains the Representation. */
140
+ adaptation : IAdaptationSetIntermediateRepresentation;
141
+ /** Whether we should request new segments even if they are not yet finished. */
142
+ aggressiveMode : boolean;
143
+ /** If false, declared segments in the MPD might still be not completely generated. */
144
+ availabilityTimeComplete : boolean;
145
+ /** availability time offset of the concerned Adaptation. */
146
+ availabilityTimeOffset : number;
147
+ /** Eventual URLs from which every relative URL will be based on. */
148
+ baseURLs : IResolvedBaseUrl[];
149
+ /** End time of the current Period, in seconds. */
150
+ end? : number | undefined;
151
+ /** List of inband event streams that are present on the representation */
152
+ inbandEventStreams: IScheme[] | undefined;
153
+ /**
154
+ * Set to `true` if the linked Period is the chronologically last one in the
155
+ * Manifest.
156
+ */
157
+ isLastPeriod : boolean;
158
+ /** Allows to obtain the first/last available position of a dynamic content. */
159
+ manifestBoundsCalculator : ManifestBoundsCalculator;
160
+ /** Whether the Manifest can evolve with time. */
161
+ isDynamic : boolean;
162
+ /**
163
+ * Parent parsed SegmentTemplate elements.
164
+ * Sorted by provenance from higher level (e.g. Period) to lower-lever (e.g.
165
+ * AdaptationSet).
166
+ */
167
+ parentSegmentTemplates : ISegmentTemplateIntermediateRepresentation[];
168
+ /**
169
+ * Time (in terms of `performance.now`) at which the XML file containing this
170
+ * Representation was received.
171
+ */
172
+ receivedTime? : number | undefined;
173
+ /** Start time of the current period, in seconds. */
174
+ start : number;
175
+ /** Depth of the buffer for the whole content, in seconds. */
176
+ timeShiftBufferDepth? : number | undefined;
177
+ /**
178
+ * The parser should take this Representation - which is the same as this one
179
+ * parsed at an earlier time - as a base to speed-up the parsing process.
180
+ * /!\ If unexpected differences exist between both, there is a risk of
181
+ * de-synchronization with what is actually on the server.
182
+ */
183
+ unsafelyBaseOnPreviousRepresentation : Representation | null;
184
+ }
@@ -26,14 +26,13 @@ import {
26
26
  import {
27
27
  IAdaptationSetIntermediateRepresentation,
28
28
  IRepresentationIntermediateRepresentation,
29
- ISegmentTemplateIntermediateRepresentation,
30
29
  IScheme,
31
30
  IContentProtectionIntermediateRepresentation,
32
31
  } from "../node_parser_types";
33
32
  import { getWEBMHDRInformation } from "./get_hdr_information";
34
- import ManifestBoundsCalculator from "./manifest_bounds_calculator";
35
- import parseRepresentationIndex from "./parse_representation_index";
36
- import { IResolvedBaseUrl } from "./resolve_base_urls";
33
+ import parseRepresentationIndex, {
34
+ IRepresentationIndexContext,
35
+ } from "./parse_representation_index";
37
36
 
38
37
  /**
39
38
  * Combine inband event streams from representation and
@@ -59,49 +58,6 @@ function combineInbandEventStreams(
59
58
  return newSchemeId;
60
59
  }
61
60
 
62
- /** Supplementary context needed to parse a Representation. */
63
- export interface IAdaptationInfos {
64
- /** Whether we should request new segments even if they are not yet finished. */
65
- aggressiveMode : boolean;
66
- availabilityTimeComplete: boolean;
67
- /** availability time offset of the concerned Adaptation. */
68
- availabilityTimeOffset: number;
69
- /** Eventual URLs from which every relative URL will be based on. */
70
- baseURLs : IResolvedBaseUrl[];
71
- /** Allows to obtain the first/last available position of a dynamic content. */
72
- manifestBoundsCalculator : ManifestBoundsCalculator;
73
- /** End time of the current period, in seconds. */
74
- end? : number;
75
- /** Whether the Manifest can evolve with time. */
76
- isDynamic : boolean;
77
- /** Manifest DASH profiles used for signalling some features */
78
- manifestProfiles?: string;
79
- /**
80
- * Parent parsed SegmentTemplate elements.
81
- * Sorted by provenance from higher level (e.g. Period) to lower-lever (e.g.
82
- * AdaptationSet).
83
- */
84
- parentSegmentTemplates : ISegmentTemplateIntermediateRepresentation[];
85
- /**
86
- * Time (in terms of `performance.now`) at which the XML file containing this
87
- * Representation was received.
88
- */
89
- receivedTime? : number;
90
- /** Start time of the current period, in seconds. */
91
- start : number;
92
- /** Depth of the buffer for the whole content, in seconds. */
93
- timeShiftBufferDepth? : number;
94
- /**
95
- * The parser should take this Adaptation - which is from a previously parsed
96
- * Manifest for the same dynamic content - as a base to speed-up the parsing
97
- * process.
98
- * /!\ If unexpected differences exist between both, there is a risk of
99
- * de-synchronization with what is actually on the server,
100
- * Use with moderation.
101
- */
102
- unsafelyBaseOnPreviousAdaptation : Adaptation | null;
103
- }
104
-
105
61
  /**
106
62
  * Extract HDR information from manifest and codecs.
107
63
  * @param {Object}
@@ -111,9 +67,9 @@ function getHDRInformation(
111
67
  { adaptationProfiles,
112
68
  manifestProfiles,
113
69
  codecs,
114
- }: { adaptationProfiles?: string;
115
- manifestProfiles?: string;
116
- codecs?: string; }
70
+ }: { adaptationProfiles?: string | undefined;
71
+ manifestProfiles?: string | undefined;
72
+ codecs?: string | undefined; }
117
73
  ): undefined | IHDRInformation {
118
74
  const profiles = (adaptationProfiles ?? "") + (manifestProfiles ?? "");
119
75
  if (codecs === undefined) {
@@ -138,13 +94,13 @@ function getHDRInformation(
138
94
  /**
139
95
  * Process intermediate representations to create final parsed representations.
140
96
  * @param {Array.<Object>} representationsIR
141
- * @param {Object} adaptationInfos
97
+ * @param {Object} context
142
98
  * @returns {Array.<Object>}
143
99
  */
144
100
  export default function parseRepresentations(
145
101
  representationsIR : IRepresentationIntermediateRepresentation[],
146
102
  adaptation : IAdaptationSetIntermediateRepresentation,
147
- adaptationInfos : IAdaptationInfos
103
+ context : IRepresentationContext
148
104
  ): IParsedRepresentation[] {
149
105
  const parsedRepresentations : IParsedRepresentation[] = [];
150
106
  for (const representation of representationsIR) {
@@ -171,7 +127,7 @@ export default function parseRepresentations(
171
127
  }
172
128
 
173
129
  // Retrieve previous version of the Representation, if one.
174
- const unsafelyBaseOnPreviousRepresentation = adaptationInfos
130
+ const unsafelyBaseOnPreviousRepresentation = context
175
131
  .unsafelyBaseOnPreviousAdaptation?.getRepresentation(representationID) ??
176
132
  null;
177
133
 
@@ -180,18 +136,19 @@ export default function parseRepresentations(
180
136
 
181
137
  const availabilityTimeComplete =
182
138
  representation.attributes.availabilityTimeComplete ??
183
- adaptationInfos.availabilityTimeComplete;
139
+ context.availabilityTimeComplete;
184
140
  const availabilityTimeOffset =
185
141
  (representation.attributes.availabilityTimeOffset ?? 0) +
186
- adaptationInfos.availabilityTimeOffset;
187
- const representationInfos = objectAssign({}, adaptationInfos,
188
- { availabilityTimeOffset,
189
- availabilityTimeComplete,
190
- unsafelyBaseOnPreviousRepresentation,
191
- adaptation,
192
- inbandEventStreams });
142
+ context.availabilityTimeOffset;
143
+ const reprIndexCtxt = objectAssign({},
144
+ context,
145
+ { availabilityTimeOffset,
146
+ availabilityTimeComplete,
147
+ unsafelyBaseOnPreviousRepresentation,
148
+ adaptation,
149
+ inbandEventStreams });
193
150
  const representationIndex = parseRepresentationIndex(representation,
194
- representationInfos);
151
+ reprIndexCtxt);
195
152
 
196
153
  // Find bitrate
197
154
  let representationBitrate : number;
@@ -297,10 +254,34 @@ export default function parseRepresentations(
297
254
 
298
255
  parsedRepresentation.hdrInfo =
299
256
  getHDRInformation({ adaptationProfiles: adaptation.attributes.profiles,
300
- manifestProfiles: adaptationInfos.manifestProfiles,
257
+ manifestProfiles: context.manifestProfiles,
301
258
  codecs });
302
259
 
303
260
  parsedRepresentations.push(parsedRepresentation);
304
261
  }
305
262
  return parsedRepresentations;
306
263
  }
264
+
265
+ /** Supplementary context needed to parse a Representation. */
266
+ export interface IRepresentationContext extends IInheritedRepresentationIndexContext {
267
+ /** Manifest DASH profiles used for signalling some features */
268
+ manifestProfiles?: string | undefined;
269
+ /**
270
+ * The parser should take this Adaptation - which is from a previously parsed
271
+ * Manifest for the same dynamic content - as a base to speed-up the parsing
272
+ * process.
273
+ * /!\ If unexpected differences exist between both, there is a risk of
274
+ * de-synchronization with what is actually on the server,
275
+ * Use with moderation.
276
+ */
277
+ unsafelyBaseOnPreviousAdaptation : Adaptation | null;
278
+ }
279
+
280
+ /**
281
+ * Supplementary context needed to parse a Representation common with
282
+ * `IRepresentationIndexContext`.
283
+ */
284
+ type IInheritedRepresentationIndexContext = Omit<IRepresentationIndexContext,
285
+ "adaptation" |
286
+ "unsafelyBaseOnPreviousRepresentation" |
287
+ "inbandEventStreams">;