shaka-player 4.4.3 → 4.6.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.
- package/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
- package/.github/workflows/release-please.yaml +2 -27
- package/AUTHORS +2 -0
- package/CHANGELOG.md +156 -39
- package/CODE_OF_CONDUCT.md +1 -1
- package/CONTRIBUTORS +2 -0
- package/README.md +54 -42
- package/demo/asset_card.js +18 -21
- package/demo/cast_receiver/index.html +0 -1
- package/demo/close_button.js +0 -3
- package/demo/common/asset.js +33 -22
- package/demo/common/assets.js +249 -60
- package/demo/config.js +219 -253
- package/demo/custom.js +88 -133
- package/demo/front.js +7 -10
- package/demo/index.html +19 -22
- package/demo/input.js +6 -11
- package/demo/input_container.js +8 -9
- package/demo/main.js +62 -126
- package/demo/search.js +29 -34
- package/demo/service_worker.js +0 -3
- package/demo/tooltip.js +3 -5
- package/demo/visualizer.js +3 -5
- package/demo/visualizer_button.js +1 -20
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +211 -228
- package/dist/demo.compiled.debug.map +4 -4
- package/dist/demo.compiled.js +211 -228
- package/dist/demo.compiled.map +4 -4
- package/dist/deps.js +42 -37
- package/dist/locales.js +34 -30
- package/dist/receiver.compiled.debug.js +64 -77
- package/dist/receiver.compiled.debug.map +4 -4
- package/dist/receiver.compiled.js +64 -77
- package/dist/receiver.compiled.map +4 -4
- package/dist/shaka-player.compiled.d.ts +343 -151
- package/dist/shaka-player.compiled.debug.d.ts +343 -151
- package/dist/shaka-player.compiled.debug.externs.js +356 -117
- package/dist/shaka-player.compiled.debug.js +952 -811
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +356 -117
- package/dist/shaka-player.compiled.js +1165 -1078
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +359 -153
- package/dist/shaka-player.ui.debug.d.ts +359 -153
- package/dist/shaka-player.ui.debug.externs.js +382 -117
- package/dist/shaka-player.ui.debug.js +1084 -918
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +382 -117
- package/dist/shaka-player.ui.js +1377 -1274
- package/dist/shaka-player.ui.map +4 -4
- package/docs/design/lcevc-integration.md +14 -14
- package/docs/tutorials/ad_monetization.md +54 -0
- package/docs/tutorials/basic-usage.md +2 -1
- package/docs/tutorials/errors.md +2 -1
- package/docs/tutorials/faq.md +27 -55
- package/docs/tutorials/index.json +2 -1
- package/docs/tutorials/lcevc.md +118 -0
- package/docs/tutorials/offline.md +10 -8
- package/docs/tutorials/plugins.md +5 -0
- package/docs/tutorials/ui-customization.md +17 -0
- package/docs/tutorials/ui.md +2 -1
- package/docs/tutorials/upgrade.md +3 -0
- package/externs/css_style_declaration.js +19 -0
- package/externs/lcevc.js +37 -13
- package/externs/managedmediasource.js +24 -0
- package/externs/media_remote.js +68 -0
- package/externs/mediatailor.js +193 -0
- package/externs/pictureinpicture.js +11 -0
- package/externs/shaka/abr_manager.js +6 -2
- package/externs/shaka/ads.js +27 -0
- package/externs/shaka/cea.js +7 -0
- package/externs/shaka/codecs.js +5 -3
- package/externs/shaka/manifest.js +31 -10
- package/externs/shaka/manifest_parser.js +24 -1
- package/externs/shaka/net.js +2 -2
- package/externs/shaka/offline.js +13 -2
- package/externs/shaka/player.js +65 -8
- package/externs/shaka/text.js +3 -1
- package/externs/shaka/transmuxer.js +1 -1
- package/karma.conf.js +7 -3
- package/lib/abr/simple_abr_manager.js +66 -9
- package/lib/ads/ad_manager.js +104 -50
- package/lib/ads/media_tailor_ad.js +297 -0
- package/lib/ads/media_tailor_ad_manager.js +839 -0
- package/lib/cast/cast_receiver.js +1 -1
- package/lib/cea/cea_decoder.js +28 -0
- package/lib/cea/dummy_caption_decoder.js +5 -0
- package/lib/cea/ts_cea_parser.js +15 -2
- package/lib/config/codec_switching_strategy.js +24 -0
- package/lib/dash/content_protection.js +120 -2
- package/lib/dash/dash_parser.js +322 -93
- package/lib/dash/mpd_utils.js +62 -37
- package/lib/dash/segment_base.js +17 -10
- package/lib/dash/segment_list.js +18 -9
- package/lib/dash/segment_template.js +122 -107
- package/lib/dependencies/all.js +8 -7
- package/lib/hls/hls_classes.js +28 -43
- package/lib/hls/hls_parser.js +798 -658
- package/lib/hls/hls_utils.js +64 -5
- package/lib/hls/manifest_text_parser.js +7 -11
- package/lib/lcevc/lcevc_dec.js +220 -0
- package/lib/media/adaptation_set.js +32 -14
- package/lib/media/adaptation_set_criteria.js +86 -16
- package/lib/media/closed_caption_parser.js +13 -0
- package/lib/media/content_workarounds.js +6 -0
- package/lib/media/drm_engine.js +8 -13
- package/lib/media/manifest_parser.js +8 -113
- package/lib/media/media_source_capabilities.js +10 -3
- package/lib/media/media_source_engine.js +286 -44
- package/lib/media/play_rate_controller.js +8 -38
- package/lib/media/presentation_timeline.js +7 -1
- package/lib/media/quality_observer.js +1 -1
- package/lib/media/segment_index.js +6 -6
- package/lib/media/segment_prefetch.js +92 -24
- package/lib/media/segment_reference.js +73 -7
- package/lib/media/segment_utils.js +343 -0
- package/lib/media/stall_detector.js +0 -3
- package/lib/media/streaming_engine.js +73 -38
- package/lib/mss/mss_parser.js +19 -2
- package/lib/net/networking_engine.js +67 -12
- package/lib/net/networking_utils.js +95 -0
- package/lib/offline/indexeddb/v1_storage_cell.js +3 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +3 -0
- package/lib/offline/manifest_converter.js +3 -0
- package/lib/offline/offline_manifest_parser.js +10 -0
- package/lib/offline/storage.js +14 -7
- package/lib/player.js +1098 -1537
- package/lib/polyfill/mediasource.js +22 -1
- package/lib/text/cue.js +15 -0
- package/lib/text/mp4_ttml_parser.js +2 -2
- package/lib/text/srt_text_parser.js +2 -2
- package/lib/text/stub_text_displayer.js +51 -0
- package/lib/text/text_engine.js +3 -2
- package/lib/text/ttml_text_parser.js +45 -5
- package/lib/text/ui_text_displayer.js +8 -0
- package/lib/text/vtt_text_parser.js +40 -22
- package/lib/transmuxer/aac_transmuxer.js +1 -1
- package/lib/transmuxer/ac3_transmuxer.js +1 -1
- package/lib/transmuxer/ec3_transmuxer.js +1 -1
- package/lib/transmuxer/h264.js +5 -4
- package/lib/transmuxer/h265.js +863 -0
- package/lib/transmuxer/mp3_transmuxer.js +1 -1
- package/lib/transmuxer/mpeg_ts_transmuxer.js +4 -3
- package/lib/transmuxer/mss_transmuxer.js +1 -1
- package/lib/transmuxer/ts_transmuxer.js +187 -22
- package/lib/util/buffer_utils.js +26 -4
- package/lib/util/content_steering_manager.js +358 -0
- package/lib/util/error.js +30 -15
- package/lib/util/exp_golomb.js +30 -2
- package/lib/util/fairplay_utils.js +1 -1
- package/lib/util/fake_event.js +8 -1
- package/lib/util/id3_utils.js +50 -1
- package/lib/util/manifest_parser_utils.js +12 -8
- package/lib/util/mp4_generator.js +6 -8
- package/lib/util/mutex.js +59 -0
- package/lib/util/object_utils.js +1 -1
- package/lib/util/periods.js +156 -179
- package/lib/util/platform.js +44 -3
- package/lib/util/player_configuration.js +43 -6
- package/lib/util/state_history.js +6 -2
- package/lib/util/stream_utils.js +206 -283
- package/lib/util/ts_parser.js +335 -98
- package/lib/util/uint8array_utils.js +5 -1
- package/lib/util/xml_utils.js +5 -0
- package/maintained-branches.md +3 -2
- package/package.json +4 -6
- package/roadmap.md +25 -5
- package/shaka-player.uncompiled.js +2 -2
- package/support.html +0 -1
- package/test/abr/simple_abr_manager_unit.js +33 -33
- package/test/ads/ad_manager_unit.js +3 -2
- package/test/cast/cast_receiver_integration.js +50 -4
- package/test/cast/cast_utils_unit.js +2 -0
- package/test/cea/cea_decoder_unit.js +7 -0
- package/test/codec_switching/codec_switching_integration.js +182 -0
- package/test/dash/dash_parser_content_protection_unit.js +2 -0
- package/test/dash/dash_parser_integration.js +74 -0
- package/test/dash/dash_parser_live_unit.js +2 -19
- package/test/dash/dash_parser_manifest_unit.js +536 -2
- package/test/dash/dash_parser_segment_base_unit.js +2 -0
- package/test/dash/dash_parser_segment_list_unit.js +2 -0
- package/test/dash/dash_parser_segment_template_unit.js +2 -0
- package/test/dash/mpd_utils_unit.js +61 -30
- package/test/demo/demo_unit.js +0 -16
- package/test/hls/hls_live_unit.js +14 -3
- package/test/hls/hls_parser_unit.js +385 -33
- package/test/hls/manifest_text_parser_unit.js +32 -99
- package/test/media/adaptation_set_criteria_unit.js +284 -15
- package/test/media/adaptation_set_unit.js +2 -0
- package/test/media/content_workarounds_unit.js +1 -1
- package/test/media/drm_engine_unit.js +3 -3
- package/test/media/media_source_engine_unit.js +166 -2
- package/test/media/play_rate_controller_unit.js +0 -48
- package/test/media/segment_index_unit.js +5 -4
- package/test/media/segment_prefetch_unit.js +1 -1
- package/test/media/streaming_engine_unit.js +17 -17
- package/test/mss/mss_parser_unit.js +2 -0
- package/test/mss/mss_player_integration.js +3 -2
- package/test/net/networking_engine_unit.js +3 -3
- package/test/{media/manifest_parser_unit.js → net/networking_utils_unit.js} +2 -2
- package/test/offline/manifest_convert_unit.js +14 -0
- package/test/offline/offline_integration.js +2 -1
- package/test/offline/storage_integration.js +22 -13
- package/test/player_external.js +4 -2
- package/test/player_integration.js +15 -4
- package/test/player_load_graph_integration.js +47 -151
- package/test/player_src_equals_external.js +1 -0
- package/test/player_src_equals_integration.js +71 -4
- package/test/player_unit.js +182 -158
- package/test/test/assets/dash-aes-128/Fragments(video=0,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=20000000,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=40000000,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=60000000,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=i,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/dash.mpd +18 -0
- package/test/test/assets/dash-aes-128/license +1 -0
- package/test/test/assets/dash-multi-codec/audio_en_2c_128k_aac.mp4 +0 -0
- package/test/test/assets/dash-multi-codec/audio_es_2c_64k_opus.webm +0 -0
- package/test/test/assets/dash-multi-codec/dash.mpd +32 -0
- package/test/test/assets/dash-multi-codec/video_144p_108k_h264.mp4 +0 -0
- package/test/test/assets/hls-ts-h265/0.ts +0 -0
- package/test/test/assets/hls-ts-h265/hevc.m3u8 +6 -0
- package/test/test/assets/hls-ts-h265/index.m3u8 +7 -0
- package/test/test/assets/hls-ts-muxed-aac-h265/0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h265/1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h265/media.m3u8 +9 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/media.m3u8 +24 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00000.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00001.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00002.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00003.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00004.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00005.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0000.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0001.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0002.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0003.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/prog_index.m3u8 +14 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/index.m3u8 +23 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-1-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-2-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-3-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-4-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-5-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-6-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-7-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-8-v1-a1.ts +0 -0
- package/test/test/util/dash_parser_util.js +4 -0
- package/test/test/util/fake_ad_manager.js +20 -0
- package/test/test/util/fake_media_source_engine.js +13 -2
- package/test/test/util/fake_networking_engine.js +9 -1
- package/test/test/util/fake_segment_prefetch.js +3 -0
- package/test/test/util/manifest_generator.js +11 -3
- package/test/test/util/manifest_parser_util.js +14 -2
- package/test/test/util/mss_parser_util.js +4 -0
- package/test/test/util/offline_utils.js +2 -0
- package/test/test/util/simple_fakes.js +2 -2
- package/test/test/util/streaming_engine_util.js +10 -4
- package/test/test/util/test_scheme.js +6 -0
- package/test/test/util/ui_utils.js +4 -3
- package/test/text/mp4_ttml_parser_unit.js +4 -4
- package/test/text/srt_text_parser_unit.js +1 -1
- package/test/text/text_displayer_layout_unit.js +1 -1
- package/test/text/text_engine_unit.js +6 -0
- package/test/text/ttml_text_parser_unit.js +85 -2
- package/test/text/vtt_text_parser_unit.js +103 -31
- package/test/transmuxer/transmuxer_engine_integration.js +9 -0
- package/test/transmuxer/transmuxer_integration.js +150 -3
- package/test/ui/ad_ui_unit.js +2 -2
- package/test/ui/ui_customization_unit.js +17 -16
- package/test/ui/ui_integration.js +30 -20
- package/test/ui/ui_unit.js +28 -29
- package/test/util/buffer_utils_unit.js +1 -1
- package/test/util/content_steering_manager_unit.js +427 -0
- package/test/util/id3_utils_unit.js +52 -0
- package/test/util/stream_utils_unit.js +207 -169
- package/test/util/ts_parser_unit.js +3 -3
- package/third_party/closure-uri/uri.js +13 -1
- package/ui/audio_language_selection.js +9 -2
- package/ui/controls.js +125 -0
- package/ui/externs/ui.js +24 -2
- package/ui/language_utils.js +43 -8
- package/ui/less/range_elements.less +33 -0
- package/ui/locales/en.json +1 -0
- package/ui/locales/es-419.json +1 -0
- package/ui/locales/es.json +1 -0
- package/ui/locales/source.json +4 -0
- package/ui/localization.js +10 -0
- package/ui/pip_button.js +22 -120
- package/ui/remote_button.js +203 -0
- package/ui/resolution_selection.js +47 -10
- package/ui/seek_bar.js +296 -3
- package/ui/text_selection.js +2 -1
- package/ui/ui.js +11 -4
- package/demo/common/message_ids.js +0 -309
- package/demo/locales/en.json +0 -288
- package/demo/locales/source.json +0 -1146
- package/externs/mux.js +0 -69
- package/lib/lcevc/lcevc_dil.js +0 -152
- package/lib/routing/node.js +0 -23
- package/lib/routing/payload.js +0 -43
- package/lib/routing/walker.js +0 -587
- package/lib/transmuxer/muxjs_transmuxer.js +0 -242
- package/test/routing/walker_unit.js +0 -504
- package/test/transmuxer/muxjs_transmuxer_integration.js +0 -177
package/externs/shaka/net.js
CHANGED
|
@@ -226,7 +226,7 @@ shaka.extern.RequestContext;
|
|
|
226
226
|
* it before it is sent to the scheme plugin.
|
|
227
227
|
* The RequestType describes the basic type of the request (manifest, segment,
|
|
228
228
|
* etc). The optional RequestContext will be provided where applicable to
|
|
229
|
-
* provide additional
|
|
229
|
+
* provide additional information about the request. A request filter can run
|
|
230
230
|
* asynchronously by returning a promise; in this case, the request will not be
|
|
231
231
|
* sent until the promise is resolved.
|
|
232
232
|
*
|
|
@@ -244,7 +244,7 @@ shaka.extern.RequestFilter;
|
|
|
244
244
|
* it before it is returned.
|
|
245
245
|
* The RequestType describes the basic type of the request (manifest, segment,
|
|
246
246
|
* etc). The optional RequestContext will be provided where applicable to
|
|
247
|
-
* provide additional
|
|
247
|
+
* provide additional information about the request. A response filter can run
|
|
248
248
|
* asynchronously by returning a promise.
|
|
249
249
|
*
|
|
250
250
|
* @typedef {!function(shaka.net.NetworkingEngine.RequestType,
|
package/externs/shaka/offline.js
CHANGED
|
@@ -114,6 +114,7 @@ shaka.extern.ManifestDB;
|
|
|
114
114
|
* @typedef {{
|
|
115
115
|
* id: number,
|
|
116
116
|
* originalId: ?string,
|
|
117
|
+
* groupId: ?string,
|
|
117
118
|
* primary: boolean,
|
|
118
119
|
* type: string,
|
|
119
120
|
* mimeType: string,
|
|
@@ -121,6 +122,7 @@ shaka.extern.ManifestDB;
|
|
|
121
122
|
* frameRate: (number|undefined),
|
|
122
123
|
* pixelAspectRatio: (string|undefined),
|
|
123
124
|
* hdr: (string|undefined),
|
|
125
|
+
* videoLayout: (string|undefined),
|
|
124
126
|
* kind: (string|undefined),
|
|
125
127
|
* language: string,
|
|
126
128
|
* originalLanguage: (?string|undefined),
|
|
@@ -138,7 +140,8 @@ shaka.extern.ManifestDB;
|
|
|
138
140
|
* spatialAudio: boolean,
|
|
139
141
|
* closedCaptions: Map.<string, string>,
|
|
140
142
|
* tilesLayout: (string|undefined),
|
|
141
|
-
* external: boolean
|
|
143
|
+
* external: boolean,
|
|
144
|
+
* fastSwitching: boolean
|
|
142
145
|
* }}
|
|
143
146
|
*
|
|
144
147
|
* @property {number} id
|
|
@@ -146,6 +149,9 @@ shaka.extern.ManifestDB;
|
|
|
146
149
|
* @property {?string} originalId
|
|
147
150
|
* The original ID, if any, that appeared in the manifest. For example, in
|
|
148
151
|
* DASH, this is the "id" attribute of the Representation element.
|
|
152
|
+
* @property {?string} groupId
|
|
153
|
+
* The ID of the stream's parent element. In DASH, this will be a unique
|
|
154
|
+
* ID that represents the representation's parent adaptation element
|
|
149
155
|
* @property {boolean} primary
|
|
150
156
|
* Whether the stream set was primary.
|
|
151
157
|
* @property {string} type
|
|
@@ -160,6 +166,8 @@ shaka.extern.ManifestDB;
|
|
|
160
166
|
* The Stream's pixel aspect ratio
|
|
161
167
|
* @property {(string|undefined)} hdr
|
|
162
168
|
* The Stream's HDR info
|
|
169
|
+
* @property {(string|undefined)} videoLayout
|
|
170
|
+
* The Stream's video layout info.
|
|
163
171
|
* @property {(string|undefined)} kind
|
|
164
172
|
* The kind of text stream; undefined for audio/video.
|
|
165
173
|
* @property {string} language
|
|
@@ -195,7 +203,8 @@ shaka.extern.ManifestDB;
|
|
|
195
203
|
* A map containing the description of closed captions, with the caption
|
|
196
204
|
* channel number (CC1 | CC2 | CC3 | CC4) as the key and the language code
|
|
197
205
|
* as the value. If the channel number is not provided by the description,
|
|
198
|
-
* we'll set
|
|
206
|
+
* we'll set a 0-based index as the key. If the language code is not
|
|
207
|
+
* provided by the description we'll set the same value as channel number.
|
|
199
208
|
* Example: {'CC1': 'eng'; 'CC3': 'swe'}, or {'1', 'eng'; '2': 'swe'}, etc.
|
|
200
209
|
* @property {(string|undefined)} tilesLayout
|
|
201
210
|
* The value is a grid-item-dimension consisting of two positive decimal
|
|
@@ -204,6 +213,8 @@ shaka.extern.ManifestDB;
|
|
|
204
213
|
* @property {boolean} external
|
|
205
214
|
* Indicate if the stream was added externally.
|
|
206
215
|
* Eg: external text tracks.
|
|
216
|
+
* @property {boolean} fastSwitching
|
|
217
|
+
* Indicate if the stream should be used for fast switching.
|
|
207
218
|
*/
|
|
208
219
|
shaka.extern.StreamDB;
|
|
209
220
|
|
package/externs/shaka/player.js
CHANGED
|
@@ -216,6 +216,7 @@ shaka.extern.BufferedInfo;
|
|
|
216
216
|
* frameRate: ?number,
|
|
217
217
|
* pixelAspectRatio: ?string,
|
|
218
218
|
* hdr: ?string,
|
|
219
|
+
* videoLayout: ?string,
|
|
219
220
|
* mimeType: ?string,
|
|
220
221
|
* audioMimeType: ?string,
|
|
221
222
|
* videoMimeType: ?string,
|
|
@@ -280,6 +281,8 @@ shaka.extern.BufferedInfo;
|
|
|
280
281
|
* The video pixel aspect ratio provided in the manifest, if present.
|
|
281
282
|
* @property {?string} hdr
|
|
282
283
|
* The video HDR provided in the manifest, if present.
|
|
284
|
+
* @property {?string} videoLayout
|
|
285
|
+
* The video layout provided in the manifest, if present.
|
|
283
286
|
* @property {?string} mimeType
|
|
284
287
|
* The MIME type of the content provided in the manifest.
|
|
285
288
|
* @property {?string} audioMimeType
|
|
@@ -495,13 +498,17 @@ shaka.extern.MetadataRawFrame;
|
|
|
495
498
|
* @typedef {{
|
|
496
499
|
* key: string,
|
|
497
500
|
* data: (ArrayBuffer|string|number),
|
|
498
|
-
* description: string
|
|
501
|
+
* description: string,
|
|
502
|
+
* mimeType: ?string,
|
|
503
|
+
* pictureType: ?number
|
|
499
504
|
* }}
|
|
500
505
|
*
|
|
501
506
|
* @description metadata frame parsed.
|
|
502
507
|
* @property {string} key
|
|
503
508
|
* @property {ArrayBuffer|string|number} data
|
|
504
509
|
* @property {string} description
|
|
510
|
+
* @property {?string} mimeType
|
|
511
|
+
* @property {?number} pictureType
|
|
505
512
|
* @exportDoc
|
|
506
513
|
*/
|
|
507
514
|
shaka.extern.MetadataFrame;
|
|
@@ -573,7 +580,7 @@ shaka.extern.TimelineRegionInfo;
|
|
|
573
580
|
* @property {?number} channelsCount
|
|
574
581
|
* The number of audio channels, or null if unknown.
|
|
575
582
|
* @property {?string} pixelAspectRatio
|
|
576
|
-
* The pixel aspect ratio value; e.g "1:1".
|
|
583
|
+
* The pixel aspect ratio value; e.g. "1:1".
|
|
577
584
|
* @property {?number} width
|
|
578
585
|
* The video width in pixels.
|
|
579
586
|
* @exportDoc
|
|
@@ -754,7 +761,8 @@ shaka.extern.PersistentSessionMetadata;
|
|
|
754
761
|
* preferredKeySystems: !Array.<string>,
|
|
755
762
|
* keySystemsMapping: !Object.<string, string>,
|
|
756
763
|
* parseInbandPsshEnabled: boolean,
|
|
757
|
-
* minHdcpVersion: string
|
|
764
|
+
* minHdcpVersion: string,
|
|
765
|
+
* ignoreDuplicateInitData: boolean
|
|
758
766
|
* }}
|
|
759
767
|
*
|
|
760
768
|
* @property {shaka.extern.RetryParameters} retryParameters
|
|
@@ -810,7 +818,12 @@ shaka.extern.PersistentSessionMetadata;
|
|
|
810
818
|
* <i>By default (''), do not check the HDCP version.</i><br>
|
|
811
819
|
* Indicates the minimum version of HDCP to start the playback of encrypted
|
|
812
820
|
* streams. <b>May be ignored if not supported by the device.</b>
|
|
813
|
-
*
|
|
821
|
+
* @property {boolean} ignoreDuplicateInitData
|
|
822
|
+
* <i>Defaults to false on Tizen 2, and true for all other browsers.</i><br>
|
|
823
|
+
* When true indicate that the player doesn't ignore duplicate init data.
|
|
824
|
+
* Note: Tizen 2015 and 2016 models will send multiple webkitneedkey events
|
|
825
|
+
* with the same init data. If the duplicates are supressed, playback
|
|
826
|
+
* will stall without errors.
|
|
814
827
|
* @exportDoc
|
|
815
828
|
*/
|
|
816
829
|
shaka.extern.DrmConfiguration;
|
|
@@ -841,7 +854,8 @@ shaka.extern.InitDataTransform;
|
|
|
841
854
|
* ignoreMaxSegmentDuration: boolean,
|
|
842
855
|
* keySystemsByURI: !Object.<string, string>,
|
|
843
856
|
* manifestPreprocessor: function(!Element),
|
|
844
|
-
* sequenceMode: boolean
|
|
857
|
+
* sequenceMode: boolean,
|
|
858
|
+
* enableAudioGroups: boolean
|
|
845
859
|
* }}
|
|
846
860
|
*
|
|
847
861
|
* @property {string} clockSyncUri
|
|
@@ -899,6 +913,10 @@ shaka.extern.InitDataTransform;
|
|
|
899
913
|
* If true, the media segments are appended to the SourceBuffer in
|
|
900
914
|
* "sequence mode" (ignoring their internal timestamps).
|
|
901
915
|
* <i>Defaults to <code>false</code>.</i>
|
|
916
|
+
* @property {boolean} enableAudioGroups
|
|
917
|
+
* If set, audio streams will be grouped and filtered by their parent
|
|
918
|
+
* adaptation set ID.
|
|
919
|
+
* <i>Defaults to <code>false</code>.</i>
|
|
902
920
|
* @exportDoc
|
|
903
921
|
*/
|
|
904
922
|
shaka.extern.DashManifestConfiguration;
|
|
@@ -915,7 +933,9 @@ shaka.extern.DashManifestConfiguration;
|
|
|
915
933
|
* useSafariBehaviorForLive: boolean,
|
|
916
934
|
* liveSegmentsDelay: number,
|
|
917
935
|
* sequenceMode: boolean,
|
|
918
|
-
* ignoreManifestTimestampsInSegmentsMode: boolean
|
|
936
|
+
* ignoreManifestTimestampsInSegmentsMode: boolean,
|
|
937
|
+
* disableCodecGuessing: boolean,
|
|
938
|
+
* allowLowLatencyByteRangeOptimization: boolean
|
|
919
939
|
* }}
|
|
920
940
|
*
|
|
921
941
|
* @property {boolean} ignoreTextStreamFailures
|
|
@@ -968,6 +988,18 @@ shaka.extern.DashManifestConfiguration;
|
|
|
968
988
|
* to the SourceBuffer, even if the manifest and segment times disagree.
|
|
969
989
|
* Only applies when sequenceMode is <code>false</code>.
|
|
970
990
|
* <i>Defaults to <code>false</code>.</i>
|
|
991
|
+
* @property {boolean} disableCodecGuessing
|
|
992
|
+
* If set to true, the HLS parser won't automatically guess or assume default
|
|
993
|
+
* codec for playlists with no "CODECS" attribute. Instead, it will attempt to
|
|
994
|
+
* extract the missing information from the media segment.
|
|
995
|
+
* As a consequence, lazy-loading media playlists won't be possible for this
|
|
996
|
+
* use case, which may result in longer video startup times.
|
|
997
|
+
* <i>Defaults to <code>false</code>.</i>
|
|
998
|
+
* @property {boolean} allowLowLatencyByteRangeOptimization
|
|
999
|
+
* If set to true, the HLS parser will optimize operation with LL and partial
|
|
1000
|
+
* byte range segments. More info in
|
|
1001
|
+
* https://www.akamai.com/blog/performance/-using-ll-hls-with-byte-range-addressing-to-achieve-interoperabi
|
|
1002
|
+
* <i>Defaults to <code>true</code>.</i>
|
|
971
1003
|
* @exportDoc
|
|
972
1004
|
*/
|
|
973
1005
|
shaka.extern.HlsManifestConfiguration;
|
|
@@ -1050,7 +1082,7 @@ shaka.extern.MssManifestConfiguration;
|
|
|
1050
1082
|
* @property {shaka.extern.MssManifestConfiguration} mss
|
|
1051
1083
|
* Advanced parameters used by the MSS manifest parser.
|
|
1052
1084
|
* @property {boolean} raiseFatalErrorOnManifestUpdateRequestFailure
|
|
1053
|
-
* If true, manifest update request failures will cause a fatal
|
|
1085
|
+
* If true, manifest update request failures will cause a fatal error.
|
|
1054
1086
|
* Defaults to <code>false</code> if not provided.
|
|
1055
1087
|
*
|
|
1056
1088
|
* @exportDoc
|
|
@@ -1089,7 +1121,9 @@ shaka.extern.ManifestConfiguration;
|
|
|
1089
1121
|
* segmentPrefetchLimit: number,
|
|
1090
1122
|
* liveSync: boolean,
|
|
1091
1123
|
* liveSyncMaxLatency: number,
|
|
1092
|
-
* liveSyncPlaybackRate: number
|
|
1124
|
+
* liveSyncPlaybackRate: number,
|
|
1125
|
+
* liveSyncMinLatency: number,
|
|
1126
|
+
* liveSyncMinPlaybackRate: number
|
|
1093
1127
|
* }}
|
|
1094
1128
|
*
|
|
1095
1129
|
* @description
|
|
@@ -1218,6 +1252,13 @@ shaka.extern.ManifestConfiguration;
|
|
|
1218
1252
|
* Playback rate used for latency chasing. It is recommended to use a value
|
|
1219
1253
|
* between 1 and 2. Effective only if liveSync is true. Defaults to
|
|
1220
1254
|
* <code>1.1</code>.
|
|
1255
|
+
* @property {number} liveSyncMinLatency
|
|
1256
|
+
* Minimun acceptable latency, in seconds. Effective only if liveSync is
|
|
1257
|
+
* true. Defaults to <code>0</code>.
|
|
1258
|
+
* @property {number} liveSyncMinPlaybackRate
|
|
1259
|
+
* Minimun playback rate used for latency chasing. It is recommended to use a
|
|
1260
|
+
* value between 0 and 1. Effective only if liveSync is true. Defaults to
|
|
1261
|
+
* <code>1</code>.
|
|
1221
1262
|
* @exportDoc
|
|
1222
1263
|
*/
|
|
1223
1264
|
shaka.extern.StreamingConfiguration;
|
|
@@ -1225,6 +1266,7 @@ shaka.extern.StreamingConfiguration;
|
|
|
1225
1266
|
|
|
1226
1267
|
/**
|
|
1227
1268
|
* @typedef {{
|
|
1269
|
+
* codecSwitchingStrategy: shaka.config.CodecSwitchingStrategy,
|
|
1228
1270
|
* sourceBufferExtraFeatures: string,
|
|
1229
1271
|
* forceTransmux: boolean,
|
|
1230
1272
|
* insertFakeEncryptionInInit: boolean
|
|
@@ -1233,6 +1275,11 @@ shaka.extern.StreamingConfiguration;
|
|
|
1233
1275
|
* @description
|
|
1234
1276
|
* Media source configuration.
|
|
1235
1277
|
*
|
|
1278
|
+
* @property {shaka.config.CodecSwitchingStrategy} codecSwitchingStrategy
|
|
1279
|
+
* Allow codec switching strategy. SMOOTH loading uses
|
|
1280
|
+
* SourceBuffer.changeType. RELOAD uses cycling of MediaSource.
|
|
1281
|
+
* Defaults to SMOOTH if SMOOTH codec switching is supported, RELOAD
|
|
1282
|
+
* overwise.
|
|
1236
1283
|
* @property {string} sourceBufferExtraFeatures
|
|
1237
1284
|
* Some platforms may need to pass features when initializing the
|
|
1238
1285
|
* sourceBuffer.
|
|
@@ -1518,6 +1565,7 @@ shaka.extern.OfflineConfiguration;
|
|
|
1518
1565
|
* preferredAudioCodecs: !Array.<string>,
|
|
1519
1566
|
* preferredAudioChannelCount: number,
|
|
1520
1567
|
* preferredVideoHdrLevel: string,
|
|
1568
|
+
* preferredVideoLayout: string,
|
|
1521
1569
|
* preferredDecodingAttributes: !Array.<string>,
|
|
1522
1570
|
* preferForcedSubs: boolean,
|
|
1523
1571
|
* restrictions: shaka.extern.Restrictions,
|
|
@@ -1578,6 +1626,12 @@ shaka.extern.OfflineConfiguration;
|
|
|
1578
1626
|
* Defaults to 'AUTO'.
|
|
1579
1627
|
* Note that one some platforms, such as Chrome, attempting to play PQ content
|
|
1580
1628
|
* may cause problems.
|
|
1629
|
+
* @property {string} preferredVideoLayout
|
|
1630
|
+
* The preferred video layout of the video.
|
|
1631
|
+
* Can be 'CH-STEREO', 'CH-MONO', or '' for no preference.
|
|
1632
|
+
* If the content is predominantly stereoscopic you should use 'CH-STEREO'.
|
|
1633
|
+
* If the content is predominantly monoscopic you should use 'CH-MONO'.
|
|
1634
|
+
* Defaults to ''.
|
|
1581
1635
|
* @property {!Array.<string>} preferredDecodingAttributes
|
|
1582
1636
|
* The list of preferred attributes of decodingInfo, in the order of their
|
|
1583
1637
|
* priorities.
|
|
@@ -1626,6 +1680,7 @@ shaka.extern.LanguageRole;
|
|
|
1626
1680
|
|
|
1627
1681
|
/**
|
|
1628
1682
|
* @typedef {{
|
|
1683
|
+
* segment: shaka.media.SegmentReference,
|
|
1629
1684
|
* imageHeight: number,
|
|
1630
1685
|
* imageWidth: number,
|
|
1631
1686
|
* height: number,
|
|
@@ -1638,6 +1693,8 @@ shaka.extern.LanguageRole;
|
|
|
1638
1693
|
* sprite: boolean
|
|
1639
1694
|
* }}
|
|
1640
1695
|
*
|
|
1696
|
+
* @property {shaka.media.SegmentReference} segment
|
|
1697
|
+
* The segment of this thumbnail.
|
|
1641
1698
|
* @property {number} imageHeight
|
|
1642
1699
|
* The image height in px. The image height could be different to height if
|
|
1643
1700
|
* the layout is different to 1x1.
|
package/externs/shaka/text.js
CHANGED
|
@@ -36,11 +36,13 @@ shaka.extern.TextParser = class {
|
|
|
36
36
|
* @param {shaka.extern.TextParser.TimeContext} timeContext
|
|
37
37
|
* The time information that should be used to adjust the times values
|
|
38
38
|
* for each cue.
|
|
39
|
+
* @param {?(string|undefined)} uri
|
|
40
|
+
* The media uri.
|
|
39
41
|
* @return {!Array.<!shaka.text.Cue>}
|
|
40
42
|
*
|
|
41
43
|
* @exportDoc
|
|
42
44
|
*/
|
|
43
|
-
parseMedia(data, timeContext) {}
|
|
45
|
+
parseMedia(data, timeContext, uri) {}
|
|
44
46
|
|
|
45
47
|
/**
|
|
46
48
|
* Notifies the stream if the manifest is in sequence mode or not.
|
package/karma.conf.js
CHANGED
|
@@ -191,9 +191,6 @@ module.exports = (config) => {
|
|
|
191
191
|
// Babel polyfill, required for async/await
|
|
192
192
|
'node_modules/@babel/polyfill/dist/polyfill.js',
|
|
193
193
|
|
|
194
|
-
// muxjs module next
|
|
195
|
-
'node_modules/mux.js/dist/mux.min.js',
|
|
196
|
-
|
|
197
194
|
// codem-isoboxer module next
|
|
198
195
|
'node_modules/codem-isoboxer/dist/iso_boxer.min.js',
|
|
199
196
|
|
|
@@ -236,7 +233,9 @@ module.exports = (config) => {
|
|
|
236
233
|
{pattern: 'third_party/**/*.js', included: false},
|
|
237
234
|
{pattern: 'test/**/*.js', included: false},
|
|
238
235
|
{pattern: 'test/test/assets/*', included: false},
|
|
236
|
+
{pattern: 'test/test/assets/dash-multi-codec/*', included: false},
|
|
239
237
|
{pattern: 'test/test/assets/3675/*', included: false},
|
|
238
|
+
{pattern: 'test/test/assets/dash-aes-128/*', included: false},
|
|
240
239
|
{pattern: 'test/test/assets/hls-raw-aac/*', included: false},
|
|
241
240
|
{pattern: 'test/test/assets/hls-raw-ac3/*', included: false},
|
|
242
241
|
{pattern: 'test/test/assets/hls-raw-ec3/*', included: false},
|
|
@@ -245,8 +244,13 @@ module.exports = (config) => {
|
|
|
245
244
|
{pattern: 'test/test/assets/hls-ts-ac3/*', included: false},
|
|
246
245
|
{pattern: 'test/test/assets/hls-ts-ec3/*', included: false},
|
|
247
246
|
{pattern: 'test/test/assets/hls-ts-h264/*', included: false},
|
|
247
|
+
{pattern: 'test/test/assets/hls-ts-h265/*', included: false},
|
|
248
248
|
{pattern: 'test/test/assets/hls-ts-mp3/*', included: false},
|
|
249
249
|
{pattern: 'test/test/assets/hls-ts-muxed-aac-h264/*', included: false},
|
|
250
|
+
{pattern: 'test/test/assets/hls-ts-muxed-aac-h265/*', included: false},
|
|
251
|
+
{pattern: 'test/test/assets/hls-ts-muxed-ac3-h264/*', included: false},
|
|
252
|
+
{pattern: 'test/test/assets/hls-ts-muxed-mp3-h264/*', included: false},
|
|
253
|
+
{pattern: 'test/test/assets/hls-ts-muxed-ec3-h264/*', included: false},
|
|
250
254
|
{pattern: 'dist/shaka-player.ui.js', included: false},
|
|
251
255
|
{pattern: 'dist/locales.js', included: false},
|
|
252
256
|
{pattern: 'demo/**/*.js', included: false},
|
|
@@ -63,7 +63,7 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
63
63
|
this.bandwidthEstimator_.configure(this.config_.advanced);
|
|
64
64
|
}
|
|
65
65
|
const chosenVariant = this.chooseVariant();
|
|
66
|
-
if (chosenVariant) {
|
|
66
|
+
if (chosenVariant && navigator.onLine) {
|
|
67
67
|
this.switch_(chosenVariant, this.config_.clearBufferSwitch,
|
|
68
68
|
this.config_.safeMarginSwitch);
|
|
69
69
|
}
|
|
@@ -165,10 +165,12 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
165
165
|
|
|
166
166
|
|
|
167
167
|
/**
|
|
168
|
+
* @param {boolean=} preferFastSwitching
|
|
169
|
+
* @return {shaka.extern.Variant}
|
|
168
170
|
* @override
|
|
169
171
|
* @export
|
|
170
172
|
*/
|
|
171
|
-
chooseVariant() {
|
|
173
|
+
chooseVariant(preferFastSwitching = false) {
|
|
172
174
|
const SimpleAbrManager = shaka.abr.SimpleAbrManager;
|
|
173
175
|
|
|
174
176
|
let maxHeight = Infinity;
|
|
@@ -184,19 +186,51 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
184
186
|
if (this.resizeObserver_ && this.config_.restrictToElementSize) {
|
|
185
187
|
const devicePixelRatio =
|
|
186
188
|
this.config_.ignoreDevicePixelRatio ? 1 : window.devicePixelRatio;
|
|
187
|
-
maxHeight =
|
|
188
|
-
|
|
189
|
+
maxHeight = Math.min(
|
|
190
|
+
maxHeight, this.mediaElement_.clientHeight * devicePixelRatio);
|
|
191
|
+
maxWidth = Math.min(
|
|
192
|
+
maxWidth, this.mediaElement_.clientWidth * devicePixelRatio);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
let normalVariants = this.variants_.filter((variant) => {
|
|
196
|
+
return !shaka.util.StreamUtils.isFastSwitching(variant);
|
|
197
|
+
});
|
|
198
|
+
if (!normalVariants.length) {
|
|
199
|
+
normalVariants = this.variants_;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
let variants = normalVariants;
|
|
203
|
+
if (preferFastSwitching &&
|
|
204
|
+
normalVariants.length != this.variants_.length) {
|
|
205
|
+
variants = this.variants_.filter((variant) => {
|
|
206
|
+
return shaka.util.StreamUtils.isFastSwitching(variant);
|
|
207
|
+
});
|
|
189
208
|
}
|
|
190
209
|
|
|
191
210
|
// Get sorted Variants.
|
|
192
211
|
let sortedVariants = SimpleAbrManager.filterAndSortVariants_(
|
|
193
|
-
this.config_.restrictions,
|
|
212
|
+
this.config_.restrictions, variants,
|
|
213
|
+
/* maxHeight= */ Infinity, /* maxWidth= */ Infinity);
|
|
214
|
+
|
|
215
|
+
if (maxHeight != Infinity || maxWidth != Infinity) {
|
|
216
|
+
const resolutions = SimpleAbrManager.getResolutionList_(sortedVariants);
|
|
217
|
+
for (const resolution of resolutions) {
|
|
218
|
+
if (resolution.height >= maxHeight && resolution.width >= maxWidth) {
|
|
219
|
+
maxHeight = resolution.height;
|
|
220
|
+
maxWidth = resolution.width;
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
sortedVariants = SimpleAbrManager.filterAndSortVariants_(
|
|
226
|
+
this.config_.restrictions, variants, maxHeight, maxWidth);
|
|
227
|
+
}
|
|
194
228
|
|
|
195
229
|
const defaultBandwidthEstimate = this.getDefaultBandwidth_();
|
|
196
230
|
const currentBandwidth = this.bandwidthEstimator_.getBandwidthEstimate(
|
|
197
231
|
defaultBandwidthEstimate);
|
|
198
232
|
|
|
199
|
-
if (
|
|
233
|
+
if (variants.length && !sortedVariants.length) {
|
|
200
234
|
// If we couldn't meet the ABR restrictions, we should still play
|
|
201
235
|
// something.
|
|
202
236
|
// These restrictions are not "hard" restrictions in the way that
|
|
@@ -205,7 +239,7 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
205
239
|
shaka.log.warning('No variants met the ABR restrictions. ' +
|
|
206
240
|
'Choosing a variant by lowest bandwidth.');
|
|
207
241
|
sortedVariants = SimpleAbrManager.filterAndSortVariants_(
|
|
208
|
-
/* restrictions= */ null,
|
|
242
|
+
/* restrictions= */ null, variants,
|
|
209
243
|
/* maxHeight= */ Infinity, /* maxWidth= */ Infinity);
|
|
210
244
|
sortedVariants = [sortedVariants[0]];
|
|
211
245
|
}
|
|
@@ -268,7 +302,7 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
268
302
|
* @override
|
|
269
303
|
* @export
|
|
270
304
|
*/
|
|
271
|
-
segmentDownloaded(deltaTimeMs, numBytes) {
|
|
305
|
+
segmentDownloaded(deltaTimeMs, numBytes, allowSwitch) {
|
|
272
306
|
shaka.log.v2('Segment downloaded:',
|
|
273
307
|
'deltaTimeMs=' + deltaTimeMs,
|
|
274
308
|
'numBytes=' + numBytes,
|
|
@@ -277,7 +311,7 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
277
311
|
goog.asserts.assert(deltaTimeMs >= 0, 'expected a non-negative duration');
|
|
278
312
|
this.bandwidthEstimator_.sample(deltaTimeMs, numBytes);
|
|
279
313
|
|
|
280
|
-
if ((this.lastTimeChosenMs_ != null) && this.enabled_) {
|
|
314
|
+
if (allowSwitch && (this.lastTimeChosenMs_ != null) && this.enabled_) {
|
|
281
315
|
this.suggestStreams_();
|
|
282
316
|
}
|
|
283
317
|
}
|
|
@@ -435,6 +469,29 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
435
469
|
return v1.bandwidth - v2.bandwidth;
|
|
436
470
|
});
|
|
437
471
|
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* @param {!Array.<shaka.extern.Variant>} variants
|
|
475
|
+
* @return {!Array.<{height: number, width: number}>}
|
|
476
|
+
* @private
|
|
477
|
+
*/
|
|
478
|
+
static getResolutionList_(variants) {
|
|
479
|
+
const resolutions = [];
|
|
480
|
+
for (const variant of variants) {
|
|
481
|
+
const video = variant.video;
|
|
482
|
+
if (!video || !video.height || !video.width) {
|
|
483
|
+
continue;
|
|
484
|
+
}
|
|
485
|
+
resolutions.push({
|
|
486
|
+
height: video.height,
|
|
487
|
+
width: video.width,
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
return resolutions.sort((v1, v2) => {
|
|
492
|
+
return v1.width - v2.width;
|
|
493
|
+
});
|
|
494
|
+
}
|
|
438
495
|
};
|
|
439
496
|
|
|
440
497
|
|