shaka-player 4.4.2 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/.github/workflows/release-please.yaml +2 -27
  2. package/CHANGELOG.md +67 -25
  3. package/README.md +16 -10
  4. package/demo/asset_card.js +18 -21
  5. package/demo/cast_receiver/index.html +0 -1
  6. package/demo/close_button.js +0 -3
  7. package/demo/common/asset.js +27 -5
  8. package/demo/common/assets.js +150 -52
  9. package/demo/config.js +192 -253
  10. package/demo/custom.js +39 -98
  11. package/demo/front.js +7 -10
  12. package/demo/index.html +19 -22
  13. package/demo/input.js +6 -11
  14. package/demo/input_container.js +8 -9
  15. package/demo/main.js +52 -124
  16. package/demo/search.js +23 -35
  17. package/demo/service_worker.js +0 -3
  18. package/demo/tooltip.js +3 -5
  19. package/demo/visualizer.js +3 -5
  20. package/demo/visualizer_button.js +1 -20
  21. package/dist/demo.compiled.debug.js +187 -211
  22. package/dist/demo.compiled.debug.map +4 -4
  23. package/dist/demo.compiled.js +187 -211
  24. package/dist/demo.compiled.map +4 -4
  25. package/dist/deps.js +27 -24
  26. package/dist/locales.js +31 -31
  27. package/dist/receiver.compiled.debug.js +42 -61
  28. package/dist/receiver.compiled.debug.map +4 -4
  29. package/dist/receiver.compiled.js +42 -61
  30. package/dist/receiver.compiled.map +4 -4
  31. package/dist/shaka-player.compiled.d.ts +728 -365
  32. package/dist/shaka-player.compiled.debug.d.ts +728 -365
  33. package/dist/shaka-player.compiled.debug.externs.js +475 -51
  34. package/dist/shaka-player.compiled.debug.js +576 -480
  35. package/dist/shaka-player.compiled.debug.map +4 -4
  36. package/dist/shaka-player.compiled.externs.js +475 -51
  37. package/dist/shaka-player.compiled.js +1117 -1056
  38. package/dist/shaka-player.compiled.map +4 -4
  39. package/dist/shaka-player.ui.d.ts +783 -410
  40. package/dist/shaka-player.ui.debug.d.ts +783 -410
  41. package/dist/shaka-player.ui.debug.externs.js +496 -51
  42. package/dist/shaka-player.ui.debug.js +647 -542
  43. package/dist/shaka-player.ui.debug.map +4 -4
  44. package/dist/shaka-player.ui.externs.js +496 -51
  45. package/dist/shaka-player.ui.js +1260 -1194
  46. package/dist/shaka-player.ui.map +4 -4
  47. package/docs/design/lcevc-integration.md +14 -14
  48. package/docs/tutorials/faq.md +27 -55
  49. package/docs/tutorials/index.json +2 -1
  50. package/docs/tutorials/lcevc.md +118 -0
  51. package/docs/tutorials/offline.md +1 -1
  52. package/docs/tutorials/ui-customization.md +4 -0
  53. package/externs/css_style_declaration.js +19 -0
  54. package/externs/lcevc.js +37 -13
  55. package/externs/media_remote.js +68 -0
  56. package/externs/mediatailor.js +193 -0
  57. package/externs/pictureinpicture.js +11 -0
  58. package/externs/shaka/ads.js +27 -0
  59. package/externs/shaka/manifest.js +10 -5
  60. package/externs/shaka/manifest_parser.js +7 -1
  61. package/externs/shaka/offline.js +4 -0
  62. package/externs/shaka/player.js +12 -1
  63. package/karma.conf.js +7 -3
  64. package/lib/abr/simple_abr_manager.js +43 -3
  65. package/lib/ads/ad_manager.js +104 -50
  66. package/lib/ads/media_tailor_ad.js +297 -0
  67. package/lib/ads/media_tailor_ad_manager.js +828 -0
  68. package/lib/cea/ts_cea_parser.js +15 -2
  69. package/lib/config/codec_switching_strategy.js +24 -0
  70. package/lib/dash/content_protection.js +120 -2
  71. package/lib/dash/dash_parser.js +79 -13
  72. package/lib/dash/mpd_utils.js +10 -6
  73. package/lib/dash/segment_base.js +13 -5
  74. package/lib/dash/segment_list.js +13 -5
  75. package/lib/dash/segment_template.js +43 -85
  76. package/lib/dependencies/all.js +8 -7
  77. package/lib/hls/hls_parser.js +101 -37
  78. package/lib/lcevc/lcevc_dec.js +220 -0
  79. package/lib/media/adaptation_set.js +22 -11
  80. package/lib/media/adaptation_set_criteria.js +25 -7
  81. package/lib/media/media_source_engine.js +215 -27
  82. package/lib/media/segment_index.js +5 -5
  83. package/lib/media/segment_reference.js +10 -5
  84. package/lib/media/streaming_engine.js +44 -39
  85. package/lib/mss/mss_parser.js +1 -0
  86. package/lib/net/networking_engine.js +1 -0
  87. package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
  88. package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
  89. package/lib/offline/manifest_converter.js +1 -0
  90. package/lib/offline/storage.js +3 -0
  91. package/lib/player.js +142 -72
  92. package/lib/routing/payload.js +5 -1
  93. package/lib/text/cue.js +62 -47
  94. package/lib/text/ttml_text_parser.js +17 -0
  95. package/lib/text/ui_text_displayer.js +4 -0
  96. package/lib/text/vtt_text_parser.js +35 -22
  97. package/lib/transmuxer/h265.js +862 -0
  98. package/lib/transmuxer/mpeg_ts_transmuxer.js +3 -2
  99. package/lib/transmuxer/ts_transmuxer.js +160 -15
  100. package/lib/util/cmcd_manager.js +6 -1
  101. package/lib/util/error.js +28 -9
  102. package/lib/util/exp_golomb.js +30 -2
  103. package/lib/util/fake_event.js +3 -0
  104. package/lib/util/manifest_parser_utils.js +10 -4
  105. package/lib/util/mp4_generator.js +4 -4
  106. package/lib/util/periods.js +2 -0
  107. package/lib/util/platform.js +54 -0
  108. package/lib/util/player_configuration.js +8 -0
  109. package/lib/util/state_history.js +6 -2
  110. package/lib/util/stream_utils.js +133 -217
  111. package/lib/util/ts_parser.js +229 -43
  112. package/maintained-branches.md +3 -2
  113. package/package.json +4 -6
  114. package/roadmap.md +15 -5
  115. package/shaka-player.uncompiled.js +2 -1
  116. package/support.html +0 -1
  117. package/test/cast/cast_receiver_integration.js +47 -0
  118. package/test/codec_switching/codec_switching_integration.js +181 -0
  119. package/test/dash/dash_parser_content_protection_unit.js +2 -0
  120. package/test/dash/dash_parser_integration.js +73 -0
  121. package/test/dash/dash_parser_live_unit.js +2 -0
  122. package/test/dash/dash_parser_manifest_unit.js +47 -0
  123. package/test/dash/dash_parser_segment_base_unit.js +7 -0
  124. package/test/dash/dash_parser_segment_list_unit.js +23 -17
  125. package/test/dash/dash_parser_segment_template_unit.js +49 -0
  126. package/test/demo/demo_unit.js +0 -16
  127. package/test/hls/hls_live_unit.js +35 -0
  128. package/test/hls/hls_parser_unit.js +8 -61
  129. package/test/media/adaptation_set_criteria_unit.js +118 -0
  130. package/test/media/adaptation_set_unit.js +1 -0
  131. package/test/media/media_source_engine_unit.js +165 -1
  132. package/test/media/segment_index_unit.js +4 -4
  133. package/test/media/segment_prefetch_unit.js +1 -1
  134. package/test/media/streaming_engine_unit.js +17 -17
  135. package/test/mss/mss_parser_unit.js +2 -0
  136. package/test/offline/manifest_convert_unit.js +5 -0
  137. package/test/offline/storage_integration.js +1 -4
  138. package/test/player_unit.js +102 -131
  139. package/test/routing/walker_unit.js +1 -0
  140. package/test/test/assets/dash-aes-128/Fragments(video=0,format=mpd-time-csf) +0 -0
  141. package/test/test/assets/dash-aes-128/Fragments(video=20000000,format=mpd-time-csf) +0 -0
  142. package/test/test/assets/dash-aes-128/Fragments(video=40000000,format=mpd-time-csf) +0 -0
  143. package/test/test/assets/dash-aes-128/Fragments(video=60000000,format=mpd-time-csf) +0 -0
  144. package/test/test/assets/dash-aes-128/Fragments(video=i,format=mpd-time-csf) +0 -0
  145. package/test/test/assets/dash-aes-128/dash.mpd +18 -0
  146. package/test/test/assets/dash-aes-128/license +1 -0
  147. package/test/test/assets/dash-multi-codec/audio_en_2c_128k_aac.mp4 +0 -0
  148. package/test/test/assets/dash-multi-codec/audio_es_2c_64k_opus.webm +0 -0
  149. package/test/test/assets/dash-multi-codec/dash.mpd +32 -0
  150. package/test/test/assets/dash-multi-codec/video_144p_108k_h264.mp4 +0 -0
  151. package/test/test/assets/hls-ts-h265/0.ts +0 -0
  152. package/test/test/assets/hls-ts-h265/hevc.m3u8 +6 -0
  153. package/test/test/assets/hls-ts-h265/index.m3u8 +7 -0
  154. package/test/test/assets/hls-ts-muxed-aac-h265/0.ts +0 -0
  155. package/test/test/assets/hls-ts-muxed-aac-h265/1.ts +0 -0
  156. package/test/test/assets/hls-ts-muxed-aac-h265/media.m3u8 +9 -0
  157. package/test/test/assets/hls-ts-muxed-ac3-h264/media.m3u8 +24 -0
  158. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00000.ts +0 -0
  159. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00001.ts +0 -0
  160. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00002.ts +0 -0
  161. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00003.ts +0 -0
  162. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00004.ts +0 -0
  163. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00005.ts +0 -0
  164. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0000.ts +0 -0
  165. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0001.ts +0 -0
  166. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0002.ts +0 -0
  167. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0003.ts +0 -0
  168. package/test/test/assets/hls-ts-muxed-ec3-h264/prog_index.m3u8 +14 -0
  169. package/test/test/assets/hls-ts-muxed-mp3-h264/index.m3u8 +23 -0
  170. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-1-v1-a1.ts +0 -0
  171. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-2-v1-a1.ts +0 -0
  172. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-3-v1-a1.ts +0 -0
  173. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-4-v1-a1.ts +0 -0
  174. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-5-v1-a1.ts +0 -0
  175. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-6-v1-a1.ts +0 -0
  176. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-7-v1-a1.ts +0 -0
  177. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-8-v1-a1.ts +0 -0
  178. package/test/test/util/dash_parser_util.js +20 -7
  179. package/test/test/util/fake_ad_manager.js +20 -0
  180. package/test/test/util/fake_media_source_engine.js +8 -2
  181. package/test/test/util/manifest_generator.js +7 -3
  182. package/test/test/util/mss_parser_util.js +4 -0
  183. package/test/test/util/offline_utils.js +1 -0
  184. package/test/test/util/streaming_engine_util.js +7 -4
  185. package/test/text/ttml_text_parser_unit.js +52 -0
  186. package/test/text/vtt_text_parser_unit.js +105 -48
  187. package/test/transmuxer/transmuxer_integration.js +121 -4
  188. package/test/ui/ui_unit.js +3 -10
  189. package/test/util/stream_utils_unit.js +208 -74
  190. package/test/util/ts_parser_unit.js +1 -1
  191. package/ui/controls.js +125 -0
  192. package/ui/externs/ui.js +8 -1
  193. package/ui/pip_button.js +22 -120
  194. package/ui/remote_button.js +201 -0
  195. package/ui/ui.js +5 -2
  196. package/demo/common/message_ids.js +0 -309
  197. package/demo/locales/en.json +0 -287
  198. package/demo/locales/source.json +0 -1142
  199. package/externs/mux.js +0 -69
  200. package/lib/lcevc/lcevc_dil.js +0 -152
  201. package/lib/transmuxer/muxjs_transmuxer.js +0 -242
  202. package/test/transmuxer/muxjs_transmuxer_integration.js +0 -177
@@ -0,0 +1,220 @@
1
+ /*! @license
2
+ * Shaka Player
3
+ * Copyright 2016 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ goog.provide('shaka.lcevc.Dec');
8
+ goog.require('shaka.log');
9
+ goog.require('shaka.Deprecate');
10
+ goog.require('shaka.util.IReleasable');
11
+
12
+ /**
13
+ * @summary
14
+ * lcevcDec - (MPEG-5 Part 2 LCEVC - Decoder) provides
15
+ * all the operations related to the enhancement and rendering
16
+ * of LCEVC enabled streams and on to a canvas.
17
+ * @implements {shaka.util.IReleasable}
18
+ * @export
19
+ */
20
+ shaka.lcevc.Dec = class {
21
+ /**
22
+ * @param {HTMLVideoElement} media The video element that will be attached to
23
+ * LCEVC Decoder for input.
24
+ * @param {HTMLCanvasElement} canvas The canvas element that will be attached
25
+ * to LCEVC Decoder to render the enhanced frames.
26
+ * @param {shaka.extern.LcevcConfiguration} lcevcConfig LCEVC configuration
27
+ * object to initialize the LCEVC Decoder.
28
+ */
29
+ constructor(media, canvas, lcevcConfig) {
30
+ /**
31
+ * LCEVC Decoder library based on availability, to check if either
32
+ * lcevc_dil or lcevc_dec is present.
33
+ * @private {LCEVCmodule}
34
+ */
35
+ this.lcevcLib_;
36
+
37
+ /** @private {?LCEVCdec.LCEVCdec} */
38
+ this.dec_ = null;
39
+
40
+ /** @private {number} */
41
+ this.variantId_ = -1;
42
+
43
+ /** @private {HTMLVideoElement} */
44
+ this.media_ = media;
45
+
46
+ /** @private {HTMLCanvasElement} */
47
+ this.canvas_ = canvas;
48
+
49
+ /** @private {shaka.extern.LcevcConfiguration} */
50
+ this.decConfig_ = lcevcConfig;
51
+
52
+ /** @private {boolean} */
53
+ this.toBeDeprecated_ = false;
54
+
55
+ this.create_();
56
+ }
57
+
58
+ /**
59
+ * Append data to the LCEVC Dec.
60
+ * @param {BufferSource} data
61
+ * @param {number} timestampOffset
62
+ */
63
+ appendBuffer(data, timestampOffset) {
64
+ if (this.dec_) {
65
+ // Timestamp offset describes how much offset should be applied to the
66
+ // LCEVC enhancement to match the decoded video frame, as such it needs
67
+ // to be negated.
68
+ this.dec_.appendBuffer(data, 'video', this.variantId_, -timestampOffset);
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Hide the canvas specifically in the case of a DRM Content
74
+ */
75
+ hideCanvas() {
76
+ if (this.dec_) {
77
+ this.canvas_.classList.add('shaka-hidden');
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Create LCEVC Decoder.
83
+ * @private
84
+ */
85
+ create_() {
86
+ if (this.isSupported_() && !this.dec_) {
87
+ if (this.lcevcLib_.SupportObject.webGLSupport(this.canvas_)) {
88
+ // Make sure the canvas is not hidden from a previous playback session.
89
+ this.canvas_.classList.remove('shaka-hidden');
90
+ // Initiate LCEVC Dec Library based on the type of module available.
91
+ if (this.toBeDeprecated_) {
92
+ this.dec_ = new this.lcevcLib_.LcevcDil(
93
+ this.media_,
94
+ this.canvas_,
95
+ this.decConfig_);
96
+ } else {
97
+ this.dec_ = new this.lcevcLib_.LCEVCdec(
98
+ this.media_,
99
+ this.canvas_,
100
+ this.decConfig_);
101
+ }
102
+ }
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Close LCEVC Decoder.
108
+ * @override
109
+ * @export
110
+ */
111
+ release() {
112
+ if (this.dec_) {
113
+ this.dec_.close();
114
+ this.dec_ = null;
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Check if the LCEVC Decoder lib is present and is supported by the browser.
120
+ * @return {boolean}
121
+ * @private
122
+ */
123
+ isSupported_() {
124
+ if (typeof libDPIModule === 'undefined') {
125
+ shaka.log.alwaysWarn(
126
+ 'Could not find LCEVC Library dependencies on this page');
127
+ }
128
+
129
+ // This is a check to make the LCEVC Dec Integration is backwards compatible
130
+ // with previous Integration. This logic checks for both implementations
131
+ // and uses the one available.
132
+ if (typeof LCEVCdec !== 'undefined') {
133
+ this.lcevcLib_ = LCEVCdec;
134
+ } else {
135
+ if (typeof LcevcDil !== 'undefined') {
136
+ this.lcevcLib_ = LcevcDil;
137
+ this.toBeDeprecated_ = true;
138
+ shaka.Deprecate.deprecateFeature(5,
139
+ 'LcevcDil',
140
+ 'lcevc_dil.js is deprecated, please use lcevc_dec.js instead');
141
+ } else {
142
+ shaka.log.alwaysWarn('Could not find LCEVC Library on this page');
143
+ return false;
144
+ }
145
+ }
146
+
147
+ // Making Sure if there is a valid LCEVC Dec Library exists.
148
+ if (typeof this.lcevcLib_.SupportObject === 'undefined') {
149
+ shaka.log.alwaysWarn('Could not find LCEVC Library on this page');
150
+ return false;
151
+ } else {
152
+ if (!this.lcevcLib_.SupportObject.SupportStatus) {
153
+ shaka.log.alwaysWarn(this.lcevcLib_.SupportObject.SupportError);
154
+ }
155
+ }
156
+
157
+ return typeof this.lcevcLib_ !== 'undefined' &&
158
+ typeof libDPIModule !== 'undefined' &&
159
+ this.canvas_ instanceof HTMLCanvasElement &&
160
+ this.lcevcLib_.SupportObject.SupportStatus;
161
+ }
162
+
163
+ /**
164
+ * Update current active variant
165
+ * @param {shaka.extern.Track} track
166
+ */
167
+ updateVariant(track, manifestType) {
168
+ let containerFormat = shaka.lcevc.Dec.ContainerFormat.MPEG2_TS;
169
+ let streamingFormat = shaka.lcevc.Dec.StreamingFormat.OTHER;
170
+ switch (track.mimeType) {
171
+ case 'video/webm': {
172
+ containerFormat = shaka.lcevc.Dec.ContainerFormat.WEBM;
173
+ break;
174
+ }
175
+ case 'video/mp4': {
176
+ containerFormat = shaka.lcevc.Dec.ContainerFormat.MP4;
177
+ break;
178
+ }
179
+ }
180
+ switch (manifestType) {
181
+ case 'DASH': {
182
+ streamingFormat = shaka.lcevc.Dec.StreamingFormat.DASH;
183
+ break;
184
+ }
185
+ case 'HLS': {
186
+ streamingFormat = shaka.lcevc.Dec.StreamingFormat.HLS;
187
+ break;
188
+ }
189
+ }
190
+ if (this.dec_) {
191
+ this.variantId_ = track.id;
192
+ this.dec_.setLevelSwitching(track.id, true);
193
+ this.dec_.setContainerFormat(containerFormat);
194
+ // This functionality is only available on the LCEVC Dec Library.
195
+ if (!this.toBeDeprecated_) {
196
+ this.dec_.setStreamingFormat(streamingFormat);
197
+ }
198
+ }
199
+ }
200
+ };
201
+
202
+ /**
203
+ * Container Formats.
204
+ * @const @enum {number}
205
+ */
206
+ shaka.lcevc.Dec.ContainerFormat = {
207
+ MPEG2_TS: 0,
208
+ WEBM: 1,
209
+ MP4: 2,
210
+ };
211
+
212
+ /**
213
+ * Streaming Formats.
214
+ * @const @enum {number}
215
+ */
216
+ shaka.lcevc.Dec.StreamingFormat = {
217
+ HLS: 0,
218
+ DASH: 1,
219
+ OTHER: -1,
220
+ };
@@ -43,10 +43,11 @@ shaka.media.AdaptationSet = class {
43
43
 
44
44
  /**
45
45
  * @param {shaka.extern.Variant} variant
46
+ * @param {boolean=} compareCodecs
46
47
  * @return {boolean}
47
48
  */
48
- add(variant) {
49
- if (this.canInclude(variant)) {
49
+ add(variant, compareCodecs = true) {
50
+ if (this.canInclude(variant, compareCodecs)) {
50
51
  this.variants_.add(variant);
51
52
  return true;
52
53
  }
@@ -62,18 +63,21 @@ shaka.media.AdaptationSet = class {
62
63
  * |false|, calling |add| will result in it being ignored.
63
64
  *
64
65
  * @param {shaka.extern.Variant} variant
66
+ * @param {boolean=} compareCodecs
65
67
  * @return {boolean}
66
68
  */
67
- canInclude(variant) {
68
- return shaka.media.AdaptationSet.areAdaptable(this.root_, variant);
69
+ canInclude(variant, compareCodecs = true) {
70
+ return shaka.media.AdaptationSet
71
+ .areAdaptable(this.root_, variant, compareCodecs);
69
72
  }
70
73
 
71
74
  /**
72
75
  * @param {shaka.extern.Variant} a
73
76
  * @param {shaka.extern.Variant} b
77
+ * @param {boolean=} compareCodecs
74
78
  * @return {boolean}
75
79
  */
76
- static areAdaptable(a, b) {
80
+ static areAdaptable(a, b, compareCodecs = true) {
77
81
  const AdaptationSet = shaka.media.AdaptationSet;
78
82
 
79
83
  // All variants should have audio or should all not have audio.
@@ -95,7 +99,7 @@ shaka.media.AdaptationSet = class {
95
99
  !!a.audio == !!b.audio,
96
100
  'Both should either have audio or not have audio.');
97
101
  if (a.audio && b.audio &&
98
- !AdaptationSet.areAudiosCompatible_(a.audio, b.audio)) {
102
+ !AdaptationSet.areAudiosCompatible_(a.audio, b.audio, compareCodecs)) {
99
103
  return false;
100
104
  }
101
105
 
@@ -103,7 +107,7 @@ shaka.media.AdaptationSet = class {
103
107
  !!a.video == !!b.video,
104
108
  'Both should either have video or not have video.');
105
109
  if (a.video && b.video &&
106
- !AdaptationSet.areVideosCompatible_(a.video, b.video)) {
110
+ !AdaptationSet.areVideosCompatible_(a.video, b.video, compareCodecs)) {
107
111
  return false;
108
112
  }
109
113
 
@@ -122,10 +126,11 @@ shaka.media.AdaptationSet = class {
122
126
  *
123
127
  * @param {shaka.extern.Stream} a
124
128
  * @param {shaka.extern.Stream} b
129
+ * @param {boolean} compareCodecs
125
130
  * @return {boolean}
126
131
  * @private
127
132
  */
128
- static areAudiosCompatible_(a, b) {
133
+ static areAudiosCompatible_(a, b, compareCodecs) {
129
134
  const AdaptationSet = shaka.media.AdaptationSet;
130
135
 
131
136
  // Don't adapt between channel counts, which could annoy the user
@@ -139,7 +144,7 @@ shaka.media.AdaptationSet = class {
139
144
  }
140
145
 
141
146
  // We can only adapt between base-codecs.
142
- if (!AdaptationSet.canTransitionBetween_(a, b)) {
147
+ if (compareCodecs && !AdaptationSet.canTransitionBetween_(a, b)) {
143
148
  return false;
144
149
  }
145
150
 
@@ -148,6 +153,11 @@ shaka.media.AdaptationSet = class {
148
153
  return false;
149
154
  }
150
155
 
156
+ // We can only adapt between the same groupId.
157
+ if (a.groupId !== b.groupId) {
158
+ return false;
159
+ }
160
+
151
161
  return true;
152
162
  }
153
163
 
@@ -156,14 +166,15 @@ shaka.media.AdaptationSet = class {
156
166
  *
157
167
  * @param {shaka.extern.Stream} a
158
168
  * @param {shaka.extern.Stream} b
169
+ * @param {boolean} compareCodecs
159
170
  * @return {boolean}
160
171
  * @private
161
172
  */
162
- static areVideosCompatible_(a, b) {
173
+ static areVideosCompatible_(a, b, compareCodecs) {
163
174
  const AdaptationSet = shaka.media.AdaptationSet;
164
175
 
165
176
  // We can only adapt between base-codecs.
166
- if (!AdaptationSet.canTransitionBetween_(a, b)) {
177
+ if (compareCodecs && !AdaptationSet.canTransitionBetween_(a, b)) {
167
178
  return false;
168
179
  }
169
180
 
@@ -8,8 +8,10 @@ goog.provide('shaka.media.AdaptationSetCriteria');
8
8
  goog.provide('shaka.media.ExampleBasedCriteria');
9
9
  goog.provide('shaka.media.PreferenceBasedCriteria');
10
10
 
11
+ goog.require('shaka.config.CodecSwitchingStrategy');
11
12
  goog.require('shaka.log');
12
13
  goog.require('shaka.media.AdaptationSet');
14
+ goog.require('shaka.media.Capabilities');
13
15
  goog.require('shaka.util.LanguageUtils');
14
16
  goog.require('shaka.util.StreamUtils');
15
17
 
@@ -40,10 +42,14 @@ shaka.media.AdaptationSetCriteria = class {
40
42
  shaka.media.ExampleBasedCriteria = class {
41
43
  /**
42
44
  * @param {shaka.extern.Variant} example
45
+ * @param {shaka.config.CodecSwitchingStrategy=} codecSwitchingStrategy
43
46
  */
44
- constructor(example) {
47
+ constructor(example,
48
+ codecSwitchingStrategy = shaka.config.CodecSwitchingStrategy.RELOAD) {
45
49
  /** @private {shaka.extern.Variant} */
46
50
  this.example_ = example;
51
+ /** @private {shaka.config.CodecSwitchingStrategy} */
52
+ this.codecSwitchingStrategy_ = codecSwitchingStrategy;
47
53
 
48
54
  // We can't know if role and label are really important, so we don't use
49
55
  // role and label for this.
@@ -56,15 +62,20 @@ shaka.media.ExampleBasedCriteria = class {
56
62
 
57
63
  /** @private {!shaka.media.AdaptationSetCriteria} */
58
64
  this.fallback_ = new shaka.media.PreferenceBasedCriteria(
59
- example.language, role, channelCount, hdrLevel, label);
65
+ example.language, role, channelCount, hdrLevel, label,
66
+ codecSwitchingStrategy);
60
67
  }
61
68
 
62
69
  /** @override */
63
70
  create(variants) {
71
+ const supportsSmoothCodecTransitions = this.codecSwitchingStrategy_ ==
72
+ shaka.config.CodecSwitchingStrategy.SMOOTH &&
73
+ shaka.media.Capabilities.isChangeTypeSupported();
64
74
  // We can't assume that the example is in |variants| because it could
65
75
  // actually be from another period.
66
76
  const shortList = variants.filter((variant) => {
67
- return shaka.media.AdaptationSet.areAdaptable(this.example_, variant);
77
+ return shaka.media.AdaptationSet.areAdaptable(this.example_, variant,
78
+ !supportsSmoothCodecTransitions);
68
79
  });
69
80
 
70
81
  if (shortList.length) {
@@ -90,8 +101,10 @@ shaka.media.PreferenceBasedCriteria = class {
90
101
  * @param {number} channelCount
91
102
  * @param {string} hdrLevel
92
103
  * @param {string=} label
104
+ * @param {shaka.config.CodecSwitchingStrategy=} codecSwitchingStrategy
93
105
  */
94
- constructor(language, role, channelCount, hdrLevel, label = '') {
106
+ constructor(language, role, channelCount, hdrLevel, label = '',
107
+ codecSwitchingStrategy = shaka.config.CodecSwitchingStrategy.RELOAD) {
95
108
  /** @private {string} */
96
109
  this.language_ = language;
97
110
  /** @private {string} */
@@ -102,6 +115,8 @@ shaka.media.PreferenceBasedCriteria = class {
102
115
  this.hdrLevel_ = hdrLevel;
103
116
  /** @private {string} */
104
117
  this.label_ = label;
118
+ /** @private {shaka.config.CodecSwitchingStrategy} */
119
+ this.codecSwitchingStrategy_ = codecSwitchingStrategy;
105
120
  }
106
121
 
107
122
  /** @override */
@@ -162,12 +177,15 @@ shaka.media.PreferenceBasedCriteria = class {
162
177
  }
163
178
  }
164
179
 
180
+ const supportsSmoothCodecTransitions = this.codecSwitchingStrategy_ ==
181
+ shaka.config.CodecSwitchingStrategy.SMOOTH &&
182
+ shaka.media.Capabilities.isChangeTypeSupported();
183
+
165
184
  // Make sure we only return a valid adaptation set.
166
185
  const set = new shaka.media.AdaptationSet(current[0]);
167
186
  for (const variant of current) {
168
- if (set.canInclude(variant)) {
169
- set.add(variant);
170
- }
187
+ // `add` checks combatability by calling `canInclude` internally.
188
+ set.add(variant, !supportsSmoothCodecTransitions);
171
189
  }
172
190
 
173
191
  return set;