rx-player 3.29.0-dev.2022091600 → 3.29.0-dev.2022103100

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 (184) hide show
  1. package/CHANGELOG.md +22 -10
  2. package/MAINTAINERS.md +2 -1
  3. package/VERSION +1 -1
  4. package/dist/_esm5.processed/compat/browser_detection.d.ts +4 -1
  5. package/dist/_esm5.processed/compat/browser_detection.js +7 -1
  6. package/dist/_esm5.processed/compat/can_reuse_media_keys.d.ts +12 -0
  7. package/dist/_esm5.processed/compat/can_reuse_media_keys.js +15 -0
  8. package/dist/_esm5.processed/compat/enable_audio_track.d.ts +11 -0
  9. package/dist/_esm5.processed/compat/enable_audio_track.js +26 -0
  10. package/dist/_esm5.processed/compat/index.d.ts +4 -2
  11. package/dist/_esm5.processed/compat/index.js +4 -2
  12. package/dist/_esm5.processed/compat/{should_renew_media_keys.d.ts → should_renew_media_key_system_access.d.ts} +3 -3
  13. package/dist/_esm5.processed/compat/{should_renew_media_keys.js → should_renew_media_key_system_access.js} +3 -3
  14. package/dist/_esm5.processed/config.d.ts +1 -0
  15. package/dist/_esm5.processed/core/api/playback_observer.d.ts +14 -5
  16. package/dist/_esm5.processed/core/api/playback_observer.js +54 -22
  17. package/dist/_esm5.processed/core/api/public_api.d.ts +7 -4
  18. package/dist/_esm5.processed/core/api/public_api.js +79 -61
  19. package/dist/_esm5.processed/core/api/tracks_management/media_element_track_choice_manager.js +9 -10
  20. package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.js +1 -1
  21. package/dist/_esm5.processed/core/decrypt/find_key_system.js +3 -3
  22. package/dist/_esm5.processed/core/decrypt/get_media_keys.js +4 -1
  23. package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.d.ts +98 -0
  24. package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.js +173 -0
  25. package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +4 -4
  26. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +2 -1
  27. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +15 -16
  28. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.d.ts +3 -1
  29. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.js +5 -2
  30. package/dist/_esm5.processed/core/fetchers/utils/schedule_request.d.ts +103 -0
  31. package/dist/_esm5.processed/core/fetchers/utils/schedule_request.js +414 -0
  32. package/dist/_esm5.processed/core/init/content_time_boundaries_observer.d.ts +4 -3
  33. package/dist/_esm5.processed/core/init/content_time_boundaries_observer.js +21 -22
  34. package/dist/_esm5.processed/core/init/initialize_media_source.d.ts +18 -4
  35. package/dist/_esm5.processed/core/init/initialize_media_source.js +10 -2
  36. package/dist/_esm5.processed/core/init/load_on_media_source.js +7 -1
  37. package/dist/_esm5.processed/core/init/stall_avoider.js +3 -1
  38. package/dist/_esm5.processed/default_config.d.ts +11 -0
  39. package/dist/_esm5.processed/default_config.js +11 -0
  40. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +1 -1
  41. package/dist/_esm5.processed/manifest/manifest.js +11 -2
  42. package/dist/_esm5.processed/manifest/representation.d.ts +12 -1
  43. package/dist/_esm5.processed/manifest/representation.js +1 -0
  44. package/dist/_esm5.processed/manifest/representation_index/static.d.ts +1 -1
  45. package/dist/_esm5.processed/manifest/representation_index/static.js +2 -2
  46. package/dist/_esm5.processed/manifest/representation_index/types.d.ts +32 -15
  47. package/dist/_esm5.processed/manifest/update_period_in_place.js +1 -0
  48. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/base.d.ts +10 -9
  49. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/base.js +11 -11
  50. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_init_segment.d.ts +1 -1
  51. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_init_segment.js +3 -3
  52. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_segments_from_timeline.d.ts +1 -1
  53. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_segments_from_timeline.js +4 -4
  54. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/list.d.ts +7 -7
  55. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/list.js +12 -8
  56. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.d.ts +5 -6
  57. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.js +16 -16
  58. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.d.ts +11 -10
  59. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.js +14 -13
  60. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/tokens.d.ts +3 -4
  61. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/tokens.js +4 -12
  62. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_mpd.js +2 -4
  63. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representation_index.js +1 -3
  64. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representations.js +6 -2
  65. package/dist/_esm5.processed/parsers/manifest/dash/common/resolve_base_urls.d.ts +1 -2
  66. package/dist/_esm5.processed/parsers/manifest/dash/common/resolve_base_urls.js +3 -8
  67. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/BaseURL.d.ts +1 -1
  68. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/BaseURL.js +2 -20
  69. package/dist/_esm5.processed/parsers/manifest/dash/node_parser_types.d.ts +0 -6
  70. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/BaseURL.js +0 -11
  71. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/types.d.ts +5 -1
  72. package/dist/_esm5.processed/parsers/manifest/local/parse_local_manifest.js +2 -1
  73. package/dist/_esm5.processed/parsers/manifest/local/representation_index.js +2 -2
  74. package/dist/_esm5.processed/parsers/manifest/metaplaylist/metaplaylist_parser.js +7 -1
  75. package/dist/_esm5.processed/parsers/manifest/smooth/create_parser.js +17 -11
  76. package/dist/_esm5.processed/parsers/manifest/smooth/representation_index.js +2 -2
  77. package/dist/_esm5.processed/parsers/manifest/types.d.ts +24 -0
  78. package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_extent.js +8 -1
  79. package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_origin.js +9 -1
  80. package/dist/_esm5.processed/parsers/texttracks/ttml/html/create_element.js +2 -1
  81. package/dist/_esm5.processed/transports/dash/construct_segment_url.d.ts +18 -0
  82. package/dist/_esm5.processed/transports/dash/construct_segment_url.js +21 -0
  83. package/dist/_esm5.processed/transports/dash/image_pipelines.d.ts +3 -2
  84. package/dist/_esm5.processed/transports/dash/image_pipelines.js +5 -3
  85. package/dist/_esm5.processed/transports/dash/segment_loader.js +4 -2
  86. package/dist/_esm5.processed/transports/dash/text_loader.js +4 -2
  87. package/dist/_esm5.processed/transports/dash/text_parser.js +3 -1
  88. package/dist/_esm5.processed/transports/local/segment_loader.d.ts +3 -2
  89. package/dist/_esm5.processed/transports/local/segment_loader.js +2 -2
  90. package/dist/_esm5.processed/transports/metaplaylist/pipelines.js +8 -8
  91. package/dist/_esm5.processed/transports/smooth/pipelines.js +11 -7
  92. package/dist/_esm5.processed/transports/smooth/utils.d.ts +4 -2
  93. package/dist/_esm5.processed/transports/smooth/utils.js +7 -1
  94. package/dist/_esm5.processed/transports/types.d.ts +5 -3
  95. package/dist/_esm5.processed/utils/event_emitter.d.ts +1 -2
  96. package/dist/_esm5.processed/utils/resolve_url.d.ts +7 -4
  97. package/dist/_esm5.processed/utils/resolve_url.js +11 -8
  98. package/dist/mpd-parser.wasm +0 -0
  99. package/dist/rx-player.js +5656 -13236
  100. package/dist/rx-player.min.js +1 -1
  101. package/jest.config.js +28 -23
  102. package/package.json +29 -29
  103. package/sonar-project.properties +1 -1
  104. package/src/compat/__tests__/can_reuse_media_keys.test.ts +54 -0
  105. package/src/compat/__tests__/enable_audio_track.test.ts +341 -0
  106. package/src/compat/__tests__/{should_renew_media_keys.test.ts → should_renew_media_key_system_access.test.ts} +7 -5
  107. package/src/compat/browser_detection.ts +10 -0
  108. package/src/compat/can_reuse_media_keys.ts +19 -0
  109. package/src/compat/enable_audio_track.ts +33 -0
  110. package/src/compat/index.ts +6 -2
  111. package/src/compat/{should_renew_media_keys.ts → should_renew_media_key_system_access.ts} +3 -3
  112. package/src/core/api/playback_observer.ts +97 -33
  113. package/src/core/api/public_api.ts +126 -74
  114. package/src/core/api/tracks_management/media_element_track_choice_manager.ts +3 -11
  115. package/src/core/decrypt/__tests__/__global__/media_keys.test.ts +182 -0
  116. package/src/core/decrypt/__tests__/__global__/utils.ts +2 -0
  117. package/src/core/decrypt/find_key_system.ts +3 -3
  118. package/src/core/decrypt/get_media_keys.ts +5 -1
  119. package/src/core/fetchers/cdn_prioritizer.ts +198 -0
  120. package/src/core/fetchers/manifest/manifest_fetcher.ts +7 -11
  121. package/src/core/fetchers/segment/segment_fetcher.ts +12 -10
  122. package/src/core/fetchers/segment/segment_fetcher_creator.ts +10 -1
  123. package/src/core/fetchers/utils/schedule_request.ts +482 -0
  124. package/src/core/init/content_time_boundaries_observer.ts +12 -12
  125. package/src/core/init/initialize_media_source.ts +31 -4
  126. package/src/core/init/load_on_media_source.ts +11 -2
  127. package/src/core/init/stall_avoider.ts +4 -1
  128. package/src/core/stream/orchestrator/stream_orchestrator.ts +0 -1
  129. package/src/default_config.ts +12 -0
  130. package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.ts +1 -0
  131. package/src/manifest/manifest.ts +11 -2
  132. package/src/manifest/representation.ts +15 -0
  133. package/src/manifest/representation_index/__tests__/static.test.ts +1 -1
  134. package/src/manifest/representation_index/static.ts +3 -3
  135. package/src/manifest/representation_index/types.ts +33 -15
  136. package/src/manifest/update_period_in_place.ts +1 -0
  137. package/src/parsers/manifest/dash/common/indexes/base.ts +22 -23
  138. package/src/parsers/manifest/dash/common/indexes/get_init_segment.ts +6 -4
  139. package/src/parsers/manifest/dash/common/indexes/get_segments_from_timeline.ts +5 -5
  140. package/src/parsers/manifest/dash/common/indexes/list.ts +19 -20
  141. package/src/parsers/manifest/dash/common/indexes/template.ts +23 -27
  142. package/src/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.ts +25 -23
  143. package/src/parsers/manifest/dash/common/indexes/tokens.ts +7 -18
  144. package/src/parsers/manifest/dash/common/parse_mpd.ts +2 -4
  145. package/src/parsers/manifest/dash/common/parse_representation_index.ts +1 -6
  146. package/src/parsers/manifest/dash/common/parse_representations.ts +9 -0
  147. package/src/parsers/manifest/dash/common/resolve_base_urls.ts +5 -9
  148. package/src/parsers/manifest/dash/js-parser/node_parsers/BaseURL.ts +2 -29
  149. package/src/parsers/manifest/dash/js-parser/node_parsers/__tests__/AdaptationSet.test.ts +7 -11
  150. package/src/parsers/manifest/dash/node_parser_types.ts +0 -7
  151. package/src/parsers/manifest/dash/wasm-parser/rs/events.rs +3 -1
  152. package/src/parsers/manifest/dash/wasm-parser/rs/processor/attributes.rs +1 -8
  153. package/src/parsers/manifest/dash/wasm-parser/ts/generators/BaseURL.ts +0 -13
  154. package/src/parsers/manifest/dash/wasm-parser/ts/types.ts +8 -0
  155. package/src/parsers/manifest/local/parse_local_manifest.ts +1 -0
  156. package/src/parsers/manifest/local/representation_index.ts +2 -2
  157. package/src/parsers/manifest/metaplaylist/metaplaylist_parser.ts +7 -1
  158. package/src/parsers/manifest/smooth/create_parser.ts +17 -13
  159. package/src/parsers/manifest/smooth/representation_index.ts +2 -2
  160. package/src/parsers/manifest/types.ts +26 -1
  161. package/src/parsers/manifest/utils/__tests__/get_first_time_from_adaptations.test.ts +15 -0
  162. package/src/parsers/manifest/utils/__tests__/get_last_time_from_adaptation.test.ts +15 -0
  163. package/src/parsers/texttracks/ttml/html/apply_extent.ts +8 -1
  164. package/src/parsers/texttracks/ttml/html/apply_origin.ts +9 -1
  165. package/src/parsers/texttracks/ttml/html/create_element.ts +2 -2
  166. package/src/transports/dash/construct_segment_url.ts +28 -0
  167. package/src/transports/dash/image_pipelines.ts +5 -2
  168. package/src/transports/dash/segment_loader.ts +5 -2
  169. package/src/transports/dash/text_loader.ts +5 -2
  170. package/src/transports/dash/text_parser.ts +3 -1
  171. package/src/transports/local/segment_loader.ts +3 -2
  172. package/src/transports/metaplaylist/pipelines.ts +28 -9
  173. package/src/transports/smooth/pipelines.ts +12 -6
  174. package/src/transports/smooth/utils.ts +13 -1
  175. package/src/transports/types.ts +6 -3
  176. package/src/utils/__tests__/event_emitter.test.ts +72 -67
  177. package/src/utils/__tests__/initialization_segment_cache.test.ts +7 -7
  178. package/src/utils/__tests__/resolve_url.test.ts +27 -23
  179. package/src/utils/event_emitter.ts +1 -3
  180. package/src/utils/resolve_url.ts +11 -8
  181. package/dist/_esm5.processed/core/fetchers/utils/try_urls_with_backoff.d.ts +0 -85
  182. package/dist/_esm5.processed/core/fetchers/utils/try_urls_with_backoff.js +0 -264
  183. package/dummy +0 -1
  184. package/src/core/fetchers/utils/try_urls_with_backoff.ts +0 -287
@@ -80,10 +80,36 @@ export interface IContentProtections {
80
80
  initData : IContentProtectionInitData[];
81
81
  }
82
82
 
83
+ /** Represents metadata of a CDN which can serve resources. */
84
+ export interface ICdnMetadata {
85
+ /**
86
+ * The base URL on which resources can be requested though this CDN.
87
+ * In most transports, you will want to add the wanted media resource's URL
88
+ * to that one to request it.
89
+ */
90
+ baseUrl : string;
91
+
92
+ /**
93
+ * Identifier that might be re-used in other documents.
94
+ */
95
+ id? : string | undefined;
96
+ }
97
+
83
98
  /** Representation of a "quality" available in an Adaptation. */
84
99
  export interface IParsedRepresentation {
85
100
  /** Maximum bitrate the Representation is available in, in bits per seconds. */
86
101
  bitrate : number;
102
+ /**
103
+ * Information on the CDN(s) on which requests should be done to request this
104
+ * Representation's initialization and media segments.
105
+ *
106
+ * `null` if there's no CDN involved here (e.g. resources are not
107
+ * requested through the network).
108
+ *
109
+ * An empty array means that no CDN are left to request the resource. As such,
110
+ * no resource can be loaded in that situation.
111
+ */
112
+ cdnMetadata : ICdnMetadata[] | null;
87
113
  /**
88
114
  * Interface to get information about segments associated with this
89
115
  * Representation,
@@ -352,4 +378,3 @@ export interface IParsedManifest {
352
378
  /** URIs where the manifest can be refreshed by order of importance. */
353
379
  uris? : string[] | undefined;
354
380
  }
355
-
@@ -49,12 +49,15 @@ describe("parsers utils - getFirstPositionFromAdaptation", function() {
49
49
  it("should return the first position if a single representation is present", () => {
50
50
  const representation1 = { id: "1",
51
51
  bitrate: 12,
52
+ cdnMetadata: [],
52
53
  index: generateRepresentationIndex(37) };
53
54
  const representation2 = { id: "1",
54
55
  bitrate: 12,
56
+ cdnMetadata: [],
55
57
  index: generateRepresentationIndex(undefined) };
56
58
  const representation3 = { id: "1",
57
59
  bitrate: 12,
60
+ cdnMetadata: [],
58
61
  index: generateRepresentationIndex(null) };
59
62
  expect(getFirstPositionFromAdaptation({ id: "0",
60
63
  type: "audio",
@@ -75,12 +78,15 @@ describe("parsers utils - getFirstPositionFromAdaptation", function() {
75
78
  /* eslint-enable max-len */
76
79
  const representation1 = { id: "1",
77
80
  bitrate: 12,
81
+ cdnMetadata: [],
78
82
  index: generateRepresentationIndex(37) };
79
83
  const representation2 = { id: "1",
80
84
  bitrate: 12,
85
+ cdnMetadata: [],
81
86
  index: generateRepresentationIndex(137) };
82
87
  const representation3 = { id: "1",
83
88
  bitrate: 12,
89
+ cdnMetadata: [],
84
90
  index: generateRepresentationIndex(57) };
85
91
  expect(getFirstPositionFromAdaptation({ id: "0",
86
92
  type: "audio",
@@ -93,12 +99,15 @@ describe("parsers utils - getFirstPositionFromAdaptation", function() {
93
99
  it("should return undefined if one of the first position is", () => {
94
100
  const representation1 = { id: "1",
95
101
  bitrate: 12,
102
+ cdnMetadata: [],
96
103
  index: generateRepresentationIndex(37) };
97
104
  const representation2 = { id: "1",
98
105
  bitrate: 12,
106
+ cdnMetadata: [],
99
107
  index: generateRepresentationIndex(137) };
100
108
  const representation3 = { id: "1",
101
109
  bitrate: 12,
110
+ cdnMetadata: [],
102
111
  index: generateRepresentationIndex(undefined) };
103
112
  expect(getFirstPositionFromAdaptation({ id: "0",
104
113
  type: "audio",
@@ -111,12 +120,15 @@ describe("parsers utils - getFirstPositionFromAdaptation", function() {
111
120
  it("should not consider null first positions if not all of them have one", () => {
112
121
  const representation1 = { id: "1",
113
122
  bitrate: 12,
123
+ cdnMetadata: [],
114
124
  index: generateRepresentationIndex(37) };
115
125
  const representation2 = { id: "1",
116
126
  bitrate: 12,
127
+ cdnMetadata: [],
117
128
  index: generateRepresentationIndex(137) };
118
129
  const representation3 = { id: "1",
119
130
  bitrate: 12,
131
+ cdnMetadata: [],
120
132
  index: generateRepresentationIndex(null) };
121
133
  expect(getFirstPositionFromAdaptation({ id: "0",
122
134
  type: "audio",
@@ -129,12 +141,15 @@ describe("parsers utils - getFirstPositionFromAdaptation", function() {
129
141
  it("should return null if every first positions are", () => {
130
142
  const representation1 = { id: "1",
131
143
  bitrate: 12,
144
+ cdnMetadata: [],
132
145
  index: generateRepresentationIndex(null) };
133
146
  const representation2 = { id: "1",
134
147
  bitrate: 12,
148
+ cdnMetadata: [],
135
149
  index: generateRepresentationIndex(null) };
136
150
  const representation3 = { id: "1",
137
151
  bitrate: 12,
152
+ cdnMetadata: [],
138
153
  index: generateRepresentationIndex(null) };
139
154
  expect(getFirstPositionFromAdaptation({ id: "0",
140
155
  type: "audio",
@@ -49,12 +49,15 @@ describe("parsers utils - getLastPositionFromAdaptation", function() {
49
49
  it("should return the last position if a single representation is present", () => {
50
50
  const representation1 = { id: "1",
51
51
  bitrate: 12,
52
+ cdnMetadata: [],
52
53
  index: generateRepresentationIndex(37) };
53
54
  const representation2 = { id: "1",
54
55
  bitrate: 12,
56
+ cdnMetadata: [],
55
57
  index: generateRepresentationIndex(undefined) };
56
58
  const representation3 = { id: "1",
57
59
  bitrate: 12,
60
+ cdnMetadata: [],
58
61
  index: generateRepresentationIndex(null) };
59
62
  expect(getLastPositionFromAdaptation({ id: "0",
60
63
  type: "audio",
@@ -75,12 +78,15 @@ describe("parsers utils - getLastPositionFromAdaptation", function() {
75
78
  /* eslint-enable max-len */
76
79
  const representation1 = { id: "1",
77
80
  bitrate: 12,
81
+ cdnMetadata: [],
78
82
  index: generateRepresentationIndex(37) };
79
83
  const representation2 = { id: "1",
80
84
  bitrate: 12,
85
+ cdnMetadata: [],
81
86
  index: generateRepresentationIndex(137) };
82
87
  const representation3 = { id: "1",
83
88
  bitrate: 12,
89
+ cdnMetadata: [],
84
90
  index: generateRepresentationIndex(57) };
85
91
  expect(getLastPositionFromAdaptation({ id: "0",
86
92
  type: "audio",
@@ -93,12 +99,15 @@ describe("parsers utils - getLastPositionFromAdaptation", function() {
93
99
  it("should return undefined if one of the first position is", () => {
94
100
  const representation1 = { id: "1",
95
101
  bitrate: 12,
102
+ cdnMetadata: [],
96
103
  index: generateRepresentationIndex(37) };
97
104
  const representation2 = { id: "1",
98
105
  bitrate: 12,
106
+ cdnMetadata: [],
99
107
  index: generateRepresentationIndex(137) };
100
108
  const representation3 = { id: "1",
101
109
  bitrate: 12,
110
+ cdnMetadata: [],
102
111
  index: generateRepresentationIndex(undefined) };
103
112
  expect(getLastPositionFromAdaptation({ id: "0",
104
113
  type: "audio",
@@ -111,12 +120,15 @@ describe("parsers utils - getLastPositionFromAdaptation", function() {
111
120
  it("should not consider null first positions if not all of them have one", () => {
112
121
  const representation1 = { id: "1",
113
122
  bitrate: 12,
123
+ cdnMetadata: [],
114
124
  index: generateRepresentationIndex(37) };
115
125
  const representation2 = { id: "1",
116
126
  bitrate: 12,
127
+ cdnMetadata: [],
117
128
  index: generateRepresentationIndex(137) };
118
129
  const representation3 = { id: "1",
119
130
  bitrate: 12,
131
+ cdnMetadata: [],
120
132
  index: generateRepresentationIndex(null) };
121
133
  expect(getLastPositionFromAdaptation({ id: "0",
122
134
  type: "audio",
@@ -129,12 +141,15 @@ describe("parsers utils - getLastPositionFromAdaptation", function() {
129
141
  it("should return null if every first positions are", () => {
130
142
  const representation1 = { id: "1",
131
143
  bitrate: 12,
144
+ cdnMetadata: [],
132
145
  index: generateRepresentationIndex(null) };
133
146
  const representation2 = { id: "1",
134
147
  bitrate: 12,
148
+ cdnMetadata: [],
135
149
  index: generateRepresentationIndex(null) };
136
150
  const representation3 = { id: "1",
137
151
  bitrate: 12,
152
+ cdnMetadata: [],
138
153
  index: generateRepresentationIndex(null) };
139
154
  expect(getLastPositionFromAdaptation({ id: "0",
140
155
  type: "audio",
@@ -54,7 +54,14 @@ export default function applyExtent(
54
54
  secondExtent[2] === "%" ||
55
55
  secondExtent[2] === "em")
56
56
  {
57
- element.style.height = secondExtent[1] + secondExtent[2];
57
+ const toNum = Number(secondExtent[1]);
58
+ if (secondExtent[2] === "%" && !isNaN(toNum) &&
59
+ (toNum < 0 || toNum > 100))
60
+ {
61
+ element.style.width = "80%";
62
+ } else {
63
+ element.style.height = secondExtent[1] + secondExtent[2];
64
+ }
58
65
  } else if (secondExtent[2] === "c") {
59
66
  addClassName(element, "proportional-style");
60
67
  element.setAttribute("data-proportional-height", secondExtent[1]);
@@ -53,7 +53,15 @@ export default function applyOrigin(
53
53
  secondOrigin[2] === "%" ||
54
54
  secondOrigin[2] === "em")
55
55
  {
56
- element.style.top = secondOrigin[1] + secondOrigin[2];
56
+ const toNum = Number(secondOrigin[1]);
57
+ if (secondOrigin[2] === "%" && !isNaN(toNum) &&
58
+ (toNum < 0 || toNum > 100))
59
+ {
60
+ element.style.bottom = "5%";
61
+ element.style.left = "10%";
62
+ } else {
63
+ element.style.top = secondOrigin[1] + secondOrigin[2];
64
+ }
57
65
  } else if (secondOrigin[2] === "c") {
58
66
  addClassName(element, "proportional-style");
59
67
  element.setAttribute("data-proportional-top", secondOrigin[1]);
@@ -361,7 +361,6 @@ function createTextElement(
361
361
  shouldTrimWhiteSpace : boolean
362
362
  ) : HTMLElement {
363
363
  const textElement = document.createElement("span");
364
-
365
364
  let textContent = el.textContent === null ? "" :
366
365
  el.textContent;
367
366
 
@@ -373,7 +372,8 @@ function createTextElement(
373
372
  textContent = trimmed;
374
373
  }
375
374
 
376
- textElement.innerHTML = textContent;
375
+ const textNode = document.createTextNode(textContent);
376
+ textElement.appendChild(textNode);
377
377
  textElement.className = "rxp-texttrack-span";
378
378
 
379
379
  applyTextStyle(textElement, style, shouldTrimWhiteSpace);
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Copyright 2015 CANAL+ Group
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { ISegment } from "../../manifest";
18
+ import { ICdnMetadata } from "../../parsers/manifest";
19
+ import resolveURL from "../../utils/resolve_url";
20
+
21
+ export default function constructSegmentUrl(
22
+ wantedCdn : ICdnMetadata | null,
23
+ segment : ISegment
24
+ ) : string | null {
25
+ return wantedCdn === null ? null :
26
+ segment.url === null ? wantedCdn.baseUrl :
27
+ resolveURL(wantedCdn.baseUrl, segment.url);
28
+ }
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  import features from "../../features";
18
+ import { ICdnMetadata } from "../../parsers/manifest";
18
19
  import request from "../../utils/request";
19
20
  import takeFirstSet from "../../utils/take_first_set";
20
21
  import { CancellationSignal } from "../../utils/task_canceller";
@@ -29,10 +30,11 @@ import {
29
30
  ISegmentParserParsedInitChunk,
30
31
  ISegmentParserParsedMediaChunk,
31
32
  } from "../types";
33
+ import constructSegmentUrl from "./construct_segment_url";
32
34
 
33
35
  /**
34
36
  * Loads an image segment.
35
- * @param {string|null} url
37
+ * @param {Object|null} wantedCdn
36
38
  * @param {Object} content
37
39
  * @param {Object} options
38
40
  * @param {Object} cancelSignal
@@ -40,7 +42,7 @@ import {
40
42
  * @returns {Promise}
41
43
  */
42
44
  export async function imageLoader(
43
- url : string | null,
45
+ wantedCdn : ICdnMetadata | null,
44
46
  content : ISegmentContext,
45
47
  options : ISegmentLoaderOptions,
46
48
  cancelSignal : CancellationSignal,
@@ -49,6 +51,7 @@ export async function imageLoader(
49
51
  ISegmentLoaderResultSegmentCreated<ILoadedImageSegmentFormat>>
50
52
  {
51
53
  const { segment } = content;
54
+ const url = constructSegmentUrl(wantedCdn, segment);
52
55
  if (segment.isInit || url === null) {
53
56
  return { resultType: "segment-created",
54
57
  resultData: null };
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  import { CustomLoaderError } from "../../errors";
18
+ import { ICdnMetadata } from "../../parsers/manifest";
18
19
  import { ISegmentLoader as ICustomSegmentLoader } from "../../public_types";
19
20
  import request, {
20
21
  fetchIsSupported,
@@ -37,6 +38,7 @@ import {
37
38
  import byteRange from "../utils/byte_range";
38
39
  import inferSegmentContainer from "../utils/infer_segment_container";
39
40
  import addSegmentIntegrityChecks from "./add_segment_integrity_checks_to_loader";
41
+ import constructSegmentUrl from "./construct_segment_url";
40
42
  import initSegmentLoader from "./init_segment_loader";
41
43
  import lowLatencySegmentLoader from "./low_latency_segment_loader";
42
44
 
@@ -104,11 +106,11 @@ export default function generateSegmentLoader(
104
106
  addSegmentIntegrityChecks(segmentLoader);
105
107
 
106
108
  /**
107
- * @param {Object} content
109
+ * @param {Object|null} wantedCdn
108
110
  * @returns {Observable}
109
111
  */
110
112
  function segmentLoader(
111
- url : string | null,
113
+ wantedCdn : ICdnMetadata | null,
112
114
  content : ISegmentContext,
113
115
  options : ISegmentLoaderOptions,
114
116
  cancelSignal : CancellationSignal,
@@ -117,6 +119,7 @@ export default function generateSegmentLoader(
117
119
  ISegmentLoaderResultSegmentCreated<ILoadedAudioVideoSegmentFormat> |
118
120
  ISegmentLoaderResultChunkedComplete>
119
121
  {
122
+ const url = constructSegmentUrl(wantedCdn, content.segment);
120
123
  if (url == null) {
121
124
  return Promise.resolve({ resultType: "segment-created",
122
125
  resultData: null });
@@ -14,6 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ import { ICdnMetadata } from "../../parsers/manifest";
17
18
  import request, {
18
19
  fetchIsSupported,
19
20
  } from "../../utils/request";
@@ -32,6 +33,7 @@ import {
32
33
  import byteRange from "../utils/byte_range";
33
34
  import inferSegmentContainer from "../utils/infer_segment_container";
34
35
  import addSegmentIntegrityChecks from "./add_segment_integrity_checks_to_loader";
36
+ import constructSegmentUrl from "./construct_segment_url";
35
37
  import initSegmentLoader from "./init_segment_loader";
36
38
  import lowLatencySegmentLoader from "./low_latency_segment_loader";
37
39
 
@@ -49,7 +51,7 @@ export default function generateTextTrackLoader(
49
51
  addSegmentIntegrityChecks(textTrackLoader);
50
52
 
51
53
  /**
52
- * @param {string|null} url
54
+ * @param {Object|null} wantedCdn
53
55
  * @param {Object} content
54
56
  * @param {Object} options
55
57
  * @param {Object} cancelSignal
@@ -57,7 +59,7 @@ export default function generateTextTrackLoader(
57
59
  * @returns {Promise}
58
60
  */
59
61
  function textTrackLoader(
60
- url : string | null,
62
+ wantedCdn : ICdnMetadata | null,
61
63
  content : ISegmentContext,
62
64
  options : ISegmentLoaderOptions,
63
65
  cancelSignal : CancellationSignal,
@@ -69,6 +71,7 @@ export default function generateTextTrackLoader(
69
71
  const { adaptation, representation, segment } = content;
70
72
  const { range } = segment;
71
73
 
74
+ const url = constructSegmentUrl(wantedCdn, segment);
72
75
  if (url === null) {
73
76
  return Promise.resolve({ resultType: "segment-created",
74
77
  resultData: null });
@@ -185,7 +185,9 @@ export default function generateTextTrackParser(
185
185
  ITextTrackSegmentData | null > {
186
186
  /**
187
187
  * Parse TextTrack data.
188
- * @param {Object} infos
188
+ * @param {Object} loadedSegment
189
+ * @param {Object} content
190
+ * @param {number|undefined} initTimescale
189
191
  * @returns {Observable.<Object>}
190
192
  */
191
193
  return function textTrackParser(
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  import { CustomLoaderError } from "../../errors";
18
+ import { ICdnMetadata } from "../../parsers/manifest";
18
19
  import {
19
20
  ILocalManifestInitSegmentLoader,
20
21
  ILocalManifestSegmentLoader,
@@ -180,14 +181,14 @@ function loadSegment(
180
181
 
181
182
  /**
182
183
  * Generic segment loader for the local Manifest.
183
- * @param {string | null} _url
184
+ * @param {string | null} _wantedCdn
184
185
  * @param {Object} content
185
186
  * @param {Object} cancelSignal
186
187
  * @param {Object} _callbacks
187
188
  * @returns {Promise}
188
189
  */
189
190
  export default function segmentLoader(
190
- _url : string | null,
191
+ _wantedCdn : ICdnMetadata | null,
191
192
  content : ISegmentContext,
192
193
  _loaderOptions : ISegmentLoaderOptions, // TODO use timeout?
193
194
  cancelSignal : CancellationSignal,
@@ -26,7 +26,10 @@ import Manifest, {
26
26
  import parseMetaPlaylist, {
27
27
  IParserResponse as IMPLParserResponse,
28
28
  } from "../../parsers/manifest/metaplaylist";
29
- import { IParsedManifest } from "../../parsers/manifest/types";
29
+ import {
30
+ ICdnMetadata,
31
+ IParsedManifest,
32
+ } from "../../parsers/manifest/types";
30
33
  import isNullOrUndefined from "../../utils/is_null_or_undefined";
31
34
  import objectAssign from "../../utils/object_assign";
32
35
  import { CancellationSignal } from "../../utils/task_canceller";
@@ -248,7 +251,7 @@ export default function(options : ITransportOptions): ITransportPipelines {
248
251
 
249
252
  const audioPipeline = {
250
253
  loadSegment(
251
- url : string | null,
254
+ wantedCdn : ICdnMetadata | null,
252
255
  content : ISegmentContext,
253
256
  loaderOptions : ISegmentLoaderOptions,
254
257
  cancelToken : CancellationSignal,
@@ -260,7 +263,11 @@ export default function(options : ITransportOptions): ITransportPipelines {
260
263
  const { segment } = content;
261
264
  const { audio } = getTransportPipelinesFromSegment(segment);
262
265
  const ogContent = getOriginalContent(segment);
263
- return audio.loadSegment(url, ogContent, loaderOptions, cancelToken, callbacks);
266
+ return audio.loadSegment(wantedCdn,
267
+ ogContent,
268
+ loaderOptions,
269
+ cancelToken,
270
+ callbacks);
264
271
  },
265
272
 
266
273
  parseSegment(
@@ -286,7 +293,7 @@ export default function(options : ITransportOptions): ITransportPipelines {
286
293
 
287
294
  const videoPipeline = {
288
295
  loadSegment(
289
- url : string | null,
296
+ wantedCdn : ICdnMetadata | null,
290
297
  content : ISegmentContext,
291
298
  loaderOptions : ISegmentLoaderOptions,
292
299
  cancelToken : CancellationSignal,
@@ -298,7 +305,11 @@ export default function(options : ITransportOptions): ITransportPipelines {
298
305
  const { segment } = content;
299
306
  const { video } = getTransportPipelinesFromSegment(segment);
300
307
  const ogContent = getOriginalContent(segment);
301
- return video.loadSegment(url, ogContent, loaderOptions, cancelToken, callbacks);
308
+ return video.loadSegment(wantedCdn,
309
+ ogContent,
310
+ loaderOptions,
311
+ cancelToken,
312
+ callbacks);
302
313
  },
303
314
 
304
315
  parseSegment(
@@ -324,7 +335,7 @@ export default function(options : ITransportOptions): ITransportPipelines {
324
335
 
325
336
  const textTrackPipeline = {
326
337
  loadSegment(
327
- url : string | null,
338
+ wantedCdn : ICdnMetadata | null,
328
339
  content : ISegmentContext,
329
340
  loaderOptions : ISegmentLoaderOptions,
330
341
  cancelToken : CancellationSignal,
@@ -336,7 +347,11 @@ export default function(options : ITransportOptions): ITransportPipelines {
336
347
  const { segment } = content;
337
348
  const { text } = getTransportPipelinesFromSegment(segment);
338
349
  const ogContent = getOriginalContent(segment);
339
- return text.loadSegment(url, ogContent, loaderOptions, cancelToken, callbacks);
350
+ return text.loadSegment(wantedCdn,
351
+ ogContent,
352
+ loaderOptions,
353
+ cancelToken,
354
+ callbacks);
340
355
  },
341
356
 
342
357
  parseSegment(
@@ -362,7 +377,7 @@ export default function(options : ITransportOptions): ITransportPipelines {
362
377
 
363
378
  const imageTrackPipeline = {
364
379
  loadSegment(
365
- url : string | null,
380
+ wantedCdn : ICdnMetadata | null,
366
381
  content : ISegmentContext,
367
382
  loaderOptions : ISegmentLoaderOptions,
368
383
  cancelToken : CancellationSignal,
@@ -374,7 +389,11 @@ export default function(options : ITransportOptions): ITransportPipelines {
374
389
  const { segment } = content;
375
390
  const { image } = getTransportPipelinesFromSegment(segment);
376
391
  const ogContent = getOriginalContent(segment);
377
- return image.loadSegment(url, ogContent, loaderOptions, cancelToken, callbacks);
392
+ return image.loadSegment(wantedCdn,
393
+ ogContent,
394
+ loaderOptions,
395
+ cancelToken,
396
+ callbacks);
378
397
  },
379
398
 
380
399
  parseSegment(
@@ -21,6 +21,7 @@ import Manifest, {
21
21
  ISegment,
22
22
  } from "../../manifest";
23
23
  import { getMDAT } from "../../parsers/containers/isobmff";
24
+ import { ICdnMetadata } from "../../parsers/manifest";
24
25
  import createSmoothManifestParser, {
25
26
  SmoothRepresentationIndex,
26
27
  } from "../../parsers/manifest/smooth";
@@ -59,6 +60,7 @@ import extractTimingsInfos, {
59
60
  import { patchSegment } from "./isobmff";
60
61
  import generateSegmentLoader from "./segment_loader";
61
62
  import {
63
+ constructSegmentUrl,
62
64
  extractISML,
63
65
  extractToken,
64
66
  isMP4EmbeddedTrack,
@@ -167,7 +169,7 @@ export default function(transportOptions : ITransportOptions) : ITransportPipeli
167
169
  const audioVideoPipeline = {
168
170
  /**
169
171
  * Load a Smooth audio/video segment.
170
- * @param {string|null} url
172
+ * @param {Object|null} wantedCdn
171
173
  * @param {Object} content
172
174
  * @param {Object} loaderOptions
173
175
  * @param {Object} cancelSignal
@@ -175,7 +177,7 @@ export default function(transportOptions : ITransportOptions) : ITransportPipeli
175
177
  * @returns {Promise}
176
178
  */
177
179
  loadSegment(
178
- url : string | null,
180
+ wantedCdn : ICdnMetadata | null,
179
181
  content : ISegmentContext,
180
182
  loaderOptions : ISegmentLoaderOptions,
181
183
  cancelSignal : CancellationSignal,
@@ -183,6 +185,7 @@ export default function(transportOptions : ITransportOptions) : ITransportPipeli
183
185
  ) : Promise<ISegmentLoaderResultSegmentLoaded<ILoadedAudioVideoSegmentFormat> |
184
186
  ISegmentLoaderResultSegmentCreated<ILoadedAudioVideoSegmentFormat>>
185
187
  {
188
+ const url = constructSegmentUrl(wantedCdn, content.segment);
186
189
  return segmentLoader(url, content, loaderOptions, cancelSignal, callbacks);
187
190
  },
188
191
 
@@ -257,7 +260,7 @@ export default function(transportOptions : ITransportOptions) : ITransportPipeli
257
260
 
258
261
  const textTrackPipeline = {
259
262
  loadSegment(
260
- url : string | null,
263
+ wantedCdn : ICdnMetadata | null,
261
264
  content : ISegmentContext,
262
265
  loaderOptions : ISegmentLoaderOptions,
263
266
  cancelSignal : CancellationSignal,
@@ -265,6 +268,7 @@ export default function(transportOptions : ITransportOptions) : ITransportPipeli
265
268
  ) : Promise<ISegmentLoaderResultSegmentLoaded<ILoadedTextSegmentFormat> |
266
269
  ISegmentLoaderResultSegmentCreated<ILoadedTextSegmentFormat>> {
267
270
  const { segment, representation } = content;
271
+ const url = constructSegmentUrl(wantedCdn, segment);
268
272
  if (segment.isInit || url === null) {
269
273
  return Promise.resolve({ resultType: "segment-created",
270
274
  resultData: null });
@@ -447,19 +451,21 @@ export default function(transportOptions : ITransportOptions) : ITransportPipeli
447
451
 
448
452
  const imageTrackPipeline = {
449
453
  async loadSegment(
450
- url : string | null,
454
+ wantedCdn : ICdnMetadata | null,
451
455
  content : ISegmentContext,
452
456
  loaderOptions : ISegmentLoaderOptions,
453
457
  cancelSignal : CancellationSignal,
454
458
  callbacks : ISegmentLoaderCallbacks<ILoadedImageSegmentFormat>
455
459
  ) : Promise<ISegmentLoaderResultSegmentLoaded<ILoadedImageSegmentFormat> |
456
460
  ISegmentLoaderResultSegmentCreated<ILoadedImageSegmentFormat>> {
457
- if (content.segment.isInit || url === null) {
461
+
462
+ const { segment } = content;
463
+ const url = constructSegmentUrl(wantedCdn, segment);
464
+ if (segment.isInit || url === null) {
458
465
  // image do not need an init segment. Passthrough directly to the parser
459
466
  return { resultType: "segment-created" as const,
460
467
  resultData: null };
461
468
  }
462
-
463
469
  const data = await request({ url,
464
470
  responseType: "arraybuffer",
465
471
  timeout: loaderOptions.timeout,
@@ -14,8 +14,10 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { Representation } from "../../manifest";
17
+ import { ISegment, Representation } from "../../manifest";
18
+ import { ICdnMetadata } from "../../parsers/manifest";
18
19
  import isNonEmptyString from "../../utils/is_non_empty_string";
20
+ import resolveURL from "../../utils/resolve_url";
19
21
  import warnOnce from "../../utils/warn_once";
20
22
 
21
23
  const ISM_REG = /(\.isml?)(\?token=\S+)?$/;
@@ -85,7 +87,17 @@ function isMP4EmbeddedTrack(representation : Representation) : boolean {
85
87
  representation.mimeType.indexOf("mp4") >= 0;
86
88
  }
87
89
 
90
+ function constructSegmentUrl(
91
+ wantedCdn : ICdnMetadata | null,
92
+ segment : ISegment
93
+ ) : string | null {
94
+ return wantedCdn === null ? null :
95
+ segment.url === null ? wantedCdn.baseUrl :
96
+ resolveURL(wantedCdn.baseUrl, segment.url);
97
+ }
98
+
88
99
  export {
100
+ constructSegmentUrl,
89
101
  extractISML,
90
102
  extractToken,
91
103
  isMP4EmbeddedTrack,