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
|
@@ -40,7 +40,18 @@ shaka.polyfill.MediaSource = class {
|
|
|
40
40
|
} else if (safariVersion) {
|
|
41
41
|
// NOTE: shaka.Player.isBrowserSupported() has its own restrictions on
|
|
42
42
|
// Safari version.
|
|
43
|
-
if (safariVersion <=
|
|
43
|
+
if (safariVersion <= 10) {
|
|
44
|
+
// Safari 8 does not implement appendWindowEnd.
|
|
45
|
+
// Safari 9 & 10 do not correctly implement abort() on SourceBuffer.
|
|
46
|
+
// Bug filed: https://bugs.webkit.org/show_bug.cgi?id=160316
|
|
47
|
+
// Blacklist these very outdated versions.
|
|
48
|
+
// Bug filed: https://bugs.webkit.org/show_bug.cgi?id=165342
|
|
49
|
+
// Safari 10 fires spurious 'updateend' events after endOfStream().
|
|
50
|
+
// Bug filed: https://bugs.webkit.org/show_bug.cgi?id=165336
|
|
51
|
+
|
|
52
|
+
shaka.log.info('Blacklisting MSE on Safari <= 10.');
|
|
53
|
+
shaka.polyfill.MediaSource.blacklist_();
|
|
54
|
+
} else if (safariVersion <= 12) {
|
|
44
55
|
shaka.log.info('Patching Safari 11 & 12 MSE bugs.');
|
|
45
56
|
// Safari 11 & 12 do not correctly implement abort() on SourceBuffer.
|
|
46
57
|
// Calling abort() before appending a segment causes that segment to be
|
|
@@ -89,6 +100,16 @@ shaka.polyfill.MediaSource = class {
|
|
|
89
100
|
}
|
|
90
101
|
}
|
|
91
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Blacklist the current browser by making
|
|
105
|
+
* MediaSourceEngine.isBrowserSupported fail later.
|
|
106
|
+
*
|
|
107
|
+
* @private
|
|
108
|
+
*/
|
|
109
|
+
static blacklist_() {
|
|
110
|
+
window['MediaSource'] = null;
|
|
111
|
+
}
|
|
112
|
+
|
|
92
113
|
/**
|
|
93
114
|
* Stub out abort(). On some buggy MSE implementations, calling abort()
|
|
94
115
|
* causes various problems.
|
package/lib/text/cue.js
CHANGED
|
@@ -222,6 +222,13 @@ shaka.text.Cue = class {
|
|
|
222
222
|
*/
|
|
223
223
|
this.opacity = 1;
|
|
224
224
|
|
|
225
|
+
/**
|
|
226
|
+
* Text combine upright as a CSS text-combine-upright value.
|
|
227
|
+
* @type {string}
|
|
228
|
+
* @export
|
|
229
|
+
*/
|
|
230
|
+
this.textCombineUpright = '';
|
|
231
|
+
|
|
225
232
|
/**
|
|
226
233
|
* Text decoration. A combination of underline, overline
|
|
227
234
|
* and line through. Empty array means no decoration.
|
|
@@ -292,6 +299,14 @@ shaka.text.Cue = class {
|
|
|
292
299
|
*/
|
|
293
300
|
this.lineBreak = false;
|
|
294
301
|
|
|
302
|
+
/**
|
|
303
|
+
* Used to indicate the type of ruby tag that should be used when rendering
|
|
304
|
+
* the cue. Valid values: ruby, rp, rt.
|
|
305
|
+
* @type {?string}
|
|
306
|
+
* @export
|
|
307
|
+
*/
|
|
308
|
+
this.rubyTag = null;
|
|
309
|
+
|
|
295
310
|
/**
|
|
296
311
|
* The number of horizontal and vertical cells into which the Root Container
|
|
297
312
|
* Region area is divided.
|
|
@@ -75,7 +75,7 @@ shaka.text.Mp4TtmlParser = class {
|
|
|
75
75
|
* @override
|
|
76
76
|
* @export
|
|
77
77
|
*/
|
|
78
|
-
parseMedia(data, time) {
|
|
78
|
+
parseMedia(data, time, uri) {
|
|
79
79
|
const Mp4Parser = shaka.util.Mp4Parser;
|
|
80
80
|
|
|
81
81
|
let sawMDAT = false;
|
|
@@ -86,7 +86,7 @@ shaka.text.Mp4TtmlParser = class {
|
|
|
86
86
|
sawMDAT = true;
|
|
87
87
|
// Join this to any previous payload, in case the mp4 has multiple
|
|
88
88
|
// mdats.
|
|
89
|
-
payload = payload.concat(this.parser_.parseMedia(data, time));
|
|
89
|
+
payload = payload.concat(this.parser_.parseMedia(data, time, uri));
|
|
90
90
|
}));
|
|
91
91
|
parser.parse(data, /* partialOkay= */ false);
|
|
92
92
|
|
|
@@ -55,7 +55,7 @@ shaka.text.SrtTextParser = class {
|
|
|
55
55
|
* @override
|
|
56
56
|
* @export
|
|
57
57
|
*/
|
|
58
|
-
parseMedia(data, time) {
|
|
58
|
+
parseMedia(data, time, uri) {
|
|
59
59
|
const SrtTextParser = shaka.text.SrtTextParser;
|
|
60
60
|
const BufferUtils = shaka.util.BufferUtils;
|
|
61
61
|
const StringUtils = shaka.util.StringUtils;
|
|
@@ -67,7 +67,7 @@ shaka.text.SrtTextParser = class {
|
|
|
67
67
|
|
|
68
68
|
const newData = BufferUtils.toUint8(StringUtils.toUTF8(vvtText));
|
|
69
69
|
|
|
70
|
-
return this.parser_.parseMedia(newData, time);
|
|
70
|
+
return this.parser_.parseMedia(newData, time, uri);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
/**
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2023 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
goog.provide('shaka.text.StubTextDisplayer');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A stub text displayer plugin that does nothing
|
|
11
|
+
*
|
|
12
|
+
* @implements {shaka.extern.TextDisplayer}
|
|
13
|
+
* @export
|
|
14
|
+
*/
|
|
15
|
+
shaka.text.StubTextDisplayer = class {
|
|
16
|
+
/**
|
|
17
|
+
* @override
|
|
18
|
+
* @export
|
|
19
|
+
*/
|
|
20
|
+
remove(start, end) {
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @override
|
|
25
|
+
* @export
|
|
26
|
+
*/
|
|
27
|
+
append(cues) {
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @override
|
|
32
|
+
* @export
|
|
33
|
+
*/
|
|
34
|
+
destroy() {
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @override
|
|
39
|
+
* @export
|
|
40
|
+
*/
|
|
41
|
+
isTextVisible() {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @override
|
|
47
|
+
* @export
|
|
48
|
+
*/
|
|
49
|
+
setTextVisibility(on) {
|
|
50
|
+
}
|
|
51
|
+
};
|
package/lib/text/text_engine.js
CHANGED
|
@@ -166,9 +166,10 @@ shaka.text.TextEngine = class {
|
|
|
166
166
|
* @param {BufferSource} buffer
|
|
167
167
|
* @param {?number} startTime relative to the start of the presentation
|
|
168
168
|
* @param {?number} endTime relative to the start of the presentation
|
|
169
|
+
* @param {?string=} uri
|
|
169
170
|
* @return {!Promise}
|
|
170
171
|
*/
|
|
171
|
-
async appendBuffer(buffer, startTime, endTime) {
|
|
172
|
+
async appendBuffer(buffer, startTime, endTime, uri) {
|
|
172
173
|
goog.asserts.assert(
|
|
173
174
|
this.parser_, 'The parser should already be initialized');
|
|
174
175
|
|
|
@@ -198,7 +199,7 @@ shaka.text.TextEngine = class {
|
|
|
198
199
|
|
|
199
200
|
// Parse the buffer and add the new cues.
|
|
200
201
|
const allCues = this.parser_.parseMedia(
|
|
201
|
-
shaka.util.BufferUtils.toUint8(buffer), time);
|
|
202
|
+
shaka.util.BufferUtils.toUint8(buffer), time, uri);
|
|
202
203
|
const cuesToAppend = allCues.filter((cue) => {
|
|
203
204
|
return cue.startTime >= this.appendWindowStart_ &&
|
|
204
205
|
cue.startTime < this.appendWindowEnd_;
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
goog.provide('shaka.text.TtmlTextParser');
|
|
8
8
|
|
|
9
9
|
goog.require('goog.asserts');
|
|
10
|
+
goog.require('goog.Uri');
|
|
10
11
|
goog.require('shaka.log');
|
|
11
12
|
goog.require('shaka.text.Cue');
|
|
12
13
|
goog.require('shaka.text.CueRegion');
|
|
@@ -50,7 +51,7 @@ shaka.text.TtmlTextParser = class {
|
|
|
50
51
|
* @override
|
|
51
52
|
* @export
|
|
52
53
|
*/
|
|
53
|
-
parseMedia(data, time) {
|
|
54
|
+
parseMedia(data, time, uri) {
|
|
54
55
|
const TtmlTextParser = shaka.text.TtmlTextParser;
|
|
55
56
|
const XmlUtils = shaka.util.XmlUtils;
|
|
56
57
|
const ttpNs = TtmlTextParser.parameterNs_;
|
|
@@ -147,7 +148,7 @@ shaka.text.TtmlTextParser = class {
|
|
|
147
148
|
body, time, rateInfo, metadataElements, styles,
|
|
148
149
|
regionElements, cueRegions, whitespaceTrim,
|
|
149
150
|
cellResolutionInfo, /* parentCueElement= */ null,
|
|
150
|
-
/* isContent= */ false);
|
|
151
|
+
/* isContent= */ false, uri);
|
|
151
152
|
if (cue) {
|
|
152
153
|
// According to the TTML spec, backgrounds default to transparent.
|
|
153
154
|
// So default the background of the top-level element to transparent.
|
|
@@ -175,12 +176,14 @@ shaka.text.TtmlTextParser = class {
|
|
|
175
176
|
* @param {?{columns: number, rows: number}} cellResolution
|
|
176
177
|
* @param {?Element} parentCueElement
|
|
177
178
|
* @param {boolean} isContent
|
|
179
|
+
* @param {?(string|undefined)} uri
|
|
178
180
|
* @return {shaka.text.Cue}
|
|
179
181
|
* @private
|
|
180
182
|
*/
|
|
181
183
|
static parseCue_(
|
|
182
184
|
cueNode, timeContext, rateInfo, metadataElements, styles, regionElements,
|
|
183
|
-
cueRegions, whitespaceTrim, cellResolution, parentCueElement, isContent
|
|
185
|
+
cueRegions, whitespaceTrim, cellResolution, parentCueElement, isContent,
|
|
186
|
+
uri) {
|
|
184
187
|
/** @type {Element} */
|
|
185
188
|
let cueElement;
|
|
186
189
|
/** @type {Element} */
|
|
@@ -222,7 +225,21 @@ shaka.text.TtmlTextParser = class {
|
|
|
222
225
|
}
|
|
223
226
|
}
|
|
224
227
|
|
|
225
|
-
|
|
228
|
+
let imageUri = null;
|
|
229
|
+
const backgroundImage = shaka.util.XmlUtils.getAttributeNSList(
|
|
230
|
+
cueElement,
|
|
231
|
+
shaka.text.TtmlTextParser.smpteNsList_,
|
|
232
|
+
'backgroundImage');
|
|
233
|
+
if (uri && backgroundImage && !backgroundImage.startsWith('#')) {
|
|
234
|
+
const baseUri = new goog.Uri(uri);
|
|
235
|
+
const relativeUri = new goog.Uri(backgroundImage);
|
|
236
|
+
const newUri = baseUri.resolve(relativeUri).toString();
|
|
237
|
+
if (newUri) {
|
|
238
|
+
imageUri = newUri;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (cueNode.nodeName == 'p' || imageElement || imageUri) {
|
|
226
243
|
isContent = true;
|
|
227
244
|
}
|
|
228
245
|
|
|
@@ -255,6 +272,7 @@ shaka.text.TtmlTextParser = class {
|
|
|
255
272
|
cellResolution,
|
|
256
273
|
cueElement,
|
|
257
274
|
isContent,
|
|
275
|
+
uri,
|
|
258
276
|
);
|
|
259
277
|
|
|
260
278
|
// This node may or may not generate a nested cue.
|
|
@@ -388,6 +406,7 @@ shaka.text.TtmlTextParser = class {
|
|
|
388
406
|
cueElement,
|
|
389
407
|
regionElementForStyle,
|
|
390
408
|
imageElement,
|
|
409
|
+
imageUri,
|
|
391
410
|
styles,
|
|
392
411
|
/** isNested= */ parentIsContent, // "nested in a <div>" doesn't count.
|
|
393
412
|
/** isLeaf= */ (nestedCues.length == 0));
|
|
@@ -490,13 +509,15 @@ shaka.text.TtmlTextParser = class {
|
|
|
490
509
|
* @param {!Element} cueElement
|
|
491
510
|
* @param {Element} region
|
|
492
511
|
* @param {Element} imageElement
|
|
512
|
+
* @param {?string} imageUri
|
|
493
513
|
* @param {!Array.<!Element>} styles
|
|
494
514
|
* @param {boolean} isNested
|
|
495
515
|
* @param {boolean} isLeaf
|
|
496
516
|
* @private
|
|
497
517
|
*/
|
|
498
518
|
static addStyle_(
|
|
499
|
-
cue, cueElement, region, imageElement,
|
|
519
|
+
cue, cueElement, region, imageElement, imageUri, styles,
|
|
520
|
+
isNested, isLeaf) {
|
|
500
521
|
const TtmlTextParser = shaka.text.TtmlTextParser;
|
|
501
522
|
const Cue = shaka.text.Cue;
|
|
502
523
|
|
|
@@ -664,6 +685,8 @@ shaka.text.TtmlTextParser = class {
|
|
|
664
685
|
backgroundImageData) {
|
|
665
686
|
cue.backgroundImage = 'data:image/png;base64,' + backgroundImageData;
|
|
666
687
|
}
|
|
688
|
+
} else if (imageUri) {
|
|
689
|
+
cue.backgroundImage = imageUri;
|
|
667
690
|
}
|
|
668
691
|
|
|
669
692
|
const textOutline = TtmlTextParser.getStyleAttribute_(
|
|
@@ -724,6 +747,23 @@ shaka.text.TtmlTextParser = class {
|
|
|
724
747
|
if (textDecorationElement) {
|
|
725
748
|
TtmlTextParser.addTextDecoration_(cue, textDecorationElement);
|
|
726
749
|
}
|
|
750
|
+
|
|
751
|
+
const textCombine = TtmlTextParser.getStyleAttribute_(
|
|
752
|
+
cueElement, region, styles, 'textCombine', shouldInheritRegionStyles);
|
|
753
|
+
if (textCombine) {
|
|
754
|
+
cue.textCombineUpright = textCombine;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
const ruby = TtmlTextParser.getStyleAttribute_(
|
|
758
|
+
cueElement, region, styles, 'ruby', shouldInheritRegionStyles);
|
|
759
|
+
switch (ruby) {
|
|
760
|
+
case 'container':
|
|
761
|
+
cue.rubyTag = 'ruby';
|
|
762
|
+
break;
|
|
763
|
+
case 'text':
|
|
764
|
+
cue.rubyTag = 'rt';
|
|
765
|
+
break;
|
|
766
|
+
}
|
|
727
767
|
}
|
|
728
768
|
|
|
729
769
|
/**
|
|
@@ -452,6 +452,9 @@ shaka.text.UITextDisplayer = class {
|
|
|
452
452
|
if (cue.lineBreak) {
|
|
453
453
|
type = 'br';
|
|
454
454
|
}
|
|
455
|
+
if (cue.rubyTag) {
|
|
456
|
+
type = cue.rubyTag;
|
|
457
|
+
}
|
|
455
458
|
|
|
456
459
|
const needWrapper = !isNested && cue.nestedCues.length > 0;
|
|
457
460
|
|
|
@@ -561,6 +564,7 @@ shaka.text.UITextDisplayer = class {
|
|
|
561
564
|
style.paddingRight =
|
|
562
565
|
shaka.text.UITextDisplayer.convertLengthValue_(
|
|
563
566
|
cue.linePadding, cue, this.videoContainer_);
|
|
567
|
+
style.textCombineUpright = cue.textCombineUpright;
|
|
564
568
|
style.textShadow = cue.textShadow;
|
|
565
569
|
|
|
566
570
|
if (cue.backgroundImage) {
|
|
@@ -600,6 +604,10 @@ shaka.text.UITextDisplayer = class {
|
|
|
600
604
|
// Only do this for the text itself.
|
|
601
605
|
elem.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
|
|
602
606
|
}
|
|
607
|
+
const fontFamily = inherit((c) => c.fontFamily);
|
|
608
|
+
if (fontFamily) {
|
|
609
|
+
elem.style.fontFamily = fontFamily;
|
|
610
|
+
}
|
|
603
611
|
}
|
|
604
612
|
if (text) {
|
|
605
613
|
elem.textContent = text;
|
|
@@ -333,6 +333,10 @@ shaka.text.VttTextParser = class {
|
|
|
333
333
|
validStyle = true;
|
|
334
334
|
cue.opacity = parseFloat(value);
|
|
335
335
|
break;
|
|
336
|
+
case 'text-combine-upright':
|
|
337
|
+
validStyle = true;
|
|
338
|
+
cue.textCombineUpright = value;
|
|
339
|
+
break;
|
|
336
340
|
case 'text-shadow':
|
|
337
341
|
validStyle = true;
|
|
338
342
|
cue.textShadow = value;
|
|
@@ -417,8 +421,6 @@ shaka.text.VttTextParser = class {
|
|
|
417
421
|
cue = new shaka.text.Cue(start, end, '');
|
|
418
422
|
}
|
|
419
423
|
|
|
420
|
-
VttTextParser.parseCueStyles(payload, cue, styles);
|
|
421
|
-
|
|
422
424
|
// Parse optional settings.
|
|
423
425
|
parser.skipWhitespace();
|
|
424
426
|
let word = parser.readWord();
|
|
@@ -432,6 +434,8 @@ shaka.text.VttTextParser = class {
|
|
|
432
434
|
word = parser.readWord();
|
|
433
435
|
}
|
|
434
436
|
|
|
437
|
+
VttTextParser.parseCueStyles(payload, cue, styles);
|
|
438
|
+
|
|
435
439
|
if (id != null) {
|
|
436
440
|
cue.id = id;
|
|
437
441
|
}
|
|
@@ -456,8 +460,6 @@ shaka.text.VttTextParser = class {
|
|
|
456
460
|
const xmlPayload = '<span>' + payload + '</span>';
|
|
457
461
|
const element = shaka.util.XmlUtils.parseXmlString(xmlPayload, 'span');
|
|
458
462
|
if (element) {
|
|
459
|
-
/** @type {!Array.<!shaka.text.Cue>} */
|
|
460
|
-
const cues = [];
|
|
461
463
|
const childNodes = element.childNodes;
|
|
462
464
|
if (childNodes.length == 1) {
|
|
463
465
|
const childNode = childNodes[0];
|
|
@@ -468,10 +470,8 @@ shaka.text.VttTextParser = class {
|
|
|
468
470
|
}
|
|
469
471
|
}
|
|
470
472
|
for (const childNode of childNodes) {
|
|
471
|
-
VttTextParser.generateCueFromElement_(
|
|
472
|
-
childNode, rootCue, cues, styles);
|
|
473
|
+
VttTextParser.generateCueFromElement_(childNode, rootCue, styles);
|
|
473
474
|
}
|
|
474
|
-
rootCue.nestedCues = cues;
|
|
475
475
|
} else {
|
|
476
476
|
shaka.log.warning('The cue\'s markup could not be parsed: ', payload);
|
|
477
477
|
rootCue.payload = VttTextParser.htmlUnescape_(payload);
|
|
@@ -688,6 +688,8 @@ shaka.text.VttTextParser = class {
|
|
|
688
688
|
cue.fontWeight = refCue.fontWeight;
|
|
689
689
|
cue.fontStyle = refCue.fontStyle;
|
|
690
690
|
cue.opacity = refCue.opacity;
|
|
691
|
+
cue.rubyTag = refCue.rubyTag;
|
|
692
|
+
cue.textCombineUpright = refCue.textCombineUpright;
|
|
691
693
|
cue.textShadow = refCue.textShadow;
|
|
692
694
|
cue.wrapLine = refCue.wrapLine;
|
|
693
695
|
}
|
|
@@ -695,13 +697,21 @@ shaka.text.VttTextParser = class {
|
|
|
695
697
|
/**
|
|
696
698
|
* @param {!Node} element
|
|
697
699
|
* @param {!shaka.text.Cue} rootCue
|
|
698
|
-
* @param {Array.<!shaka.text.Cue>} cues
|
|
699
700
|
* @param {!Map.<string, shaka.text.Cue>} styles
|
|
700
701
|
* @private
|
|
701
702
|
*/
|
|
702
|
-
static generateCueFromElement_(element, rootCue,
|
|
703
|
+
static generateCueFromElement_(element, rootCue, styles) {
|
|
703
704
|
const VttTextParser = shaka.text.VttTextParser;
|
|
704
705
|
const nestedCue = rootCue.clone();
|
|
706
|
+
// We don't want propagate some properties.
|
|
707
|
+
nestedCue.nestedCues = [];
|
|
708
|
+
nestedCue.payload = '';
|
|
709
|
+
nestedCue.rubyTag = '';
|
|
710
|
+
// We don't want propagate some position settings
|
|
711
|
+
nestedCue.line = null;
|
|
712
|
+
nestedCue.region = new shaka.text.CueRegion();
|
|
713
|
+
nestedCue.position = null;
|
|
714
|
+
nestedCue.size = 0;
|
|
705
715
|
if (element.nodeType === Node.ELEMENT_NODE && element.nodeName) {
|
|
706
716
|
const bold = shaka.text.Cue.fontWeight.BOLD;
|
|
707
717
|
const italic = shaka.text.Cue.fontStyle.ITALIC;
|
|
@@ -724,10 +734,10 @@ shaka.text.VttTextParser = class {
|
|
|
724
734
|
}
|
|
725
735
|
switch (tag) {
|
|
726
736
|
case 'br': {
|
|
727
|
-
const lineBreakCue =
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
737
|
+
const lineBreakCue = shaka.text.Cue.lineBreak(
|
|
738
|
+
nestedCue.startTime, nestedCue.endTime);
|
|
739
|
+
rootCue.nestedCues.push(lineBreakCue);
|
|
740
|
+
return;
|
|
731
741
|
}
|
|
732
742
|
case 'b':
|
|
733
743
|
nestedCue.fontWeight = bold;
|
|
@@ -758,34 +768,42 @@ shaka.text.VttTextParser = class {
|
|
|
758
768
|
}
|
|
759
769
|
break;
|
|
760
770
|
}
|
|
771
|
+
case 'ruby':
|
|
772
|
+
case 'rp':
|
|
773
|
+
case 'rt':
|
|
774
|
+
nestedCue.rubyTag = tag;
|
|
775
|
+
break;
|
|
761
776
|
default:
|
|
762
777
|
break;
|
|
763
778
|
}
|
|
764
779
|
}
|
|
765
780
|
}
|
|
766
|
-
|
|
767
|
-
|
|
781
|
+
|
|
782
|
+
const isTextNode = (item) => shaka.util.XmlUtils.isText(item);
|
|
783
|
+
const childNodes = element.childNodes;
|
|
784
|
+
if (isTextNode(element) ||
|
|
785
|
+
(childNodes.length == 1 && isTextNode(childNodes[0]))) {
|
|
768
786
|
// Trailing line breaks may lost when convert cue to HTML tag
|
|
769
787
|
// Need to insert line break cue to preserve line breaks
|
|
770
788
|
const textArr = element.textContent.split('\n');
|
|
771
789
|
let isFirst = true;
|
|
772
790
|
for (const text of textArr) {
|
|
773
791
|
if (!isFirst) {
|
|
774
|
-
const lineBreakCue =
|
|
775
|
-
|
|
776
|
-
|
|
792
|
+
const lineBreakCue = shaka.text.Cue.lineBreak(
|
|
793
|
+
nestedCue.startTime, nestedCue.endTime);
|
|
794
|
+
rootCue.nestedCues.push(lineBreakCue);
|
|
777
795
|
}
|
|
778
796
|
if (text.length > 0) {
|
|
779
797
|
const textCue = nestedCue.clone();
|
|
780
798
|
textCue.payload = VttTextParser.htmlUnescape_(text);
|
|
781
|
-
|
|
799
|
+
rootCue.nestedCues.push(textCue);
|
|
782
800
|
}
|
|
783
801
|
isFirst = false;
|
|
784
802
|
}
|
|
785
803
|
} else {
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
804
|
+
rootCue.nestedCues.push(nestedCue);
|
|
805
|
+
for (const childNode of childNodes) {
|
|
806
|
+
VttTextParser.generateCueFromElement_(childNode, nestedCue, styles);
|
|
789
807
|
}
|
|
790
808
|
}
|
|
791
809
|
}
|
package/lib/transmuxer/h264.js
CHANGED
|
@@ -175,7 +175,7 @@ shaka.transmuxer.H264 = class {
|
|
|
175
175
|
static parseFrame(nalus) {
|
|
176
176
|
const H264 = shaka.transmuxer.H264;
|
|
177
177
|
let isKeyframe = false;
|
|
178
|
-
|
|
178
|
+
const nalusData = [];
|
|
179
179
|
const spsNalu = nalus.find((nalu) => {
|
|
180
180
|
return nalu.type == H264.NALU_TYPE_SPS_;
|
|
181
181
|
});
|
|
@@ -240,13 +240,14 @@ shaka.transmuxer.H264 = class {
|
|
|
240
240
|
naluLength[1] = (size >> 16) & 0xff;
|
|
241
241
|
naluLength[2] = (size >> 8) & 0xff;
|
|
242
242
|
naluLength[3] = size & 0xff;
|
|
243
|
-
|
|
244
|
-
|
|
243
|
+
nalusData.push(shaka.util.Uint8ArrayUtils.concat(
|
|
244
|
+
naluLength, nalu.fullData));
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
|
-
if (!
|
|
247
|
+
if (!nalusData.length) {
|
|
248
248
|
return null;
|
|
249
249
|
}
|
|
250
|
+
const data = shaka.util.Uint8ArrayUtils.concat(...nalusData);
|
|
250
251
|
return {
|
|
251
252
|
data,
|
|
252
253
|
isKeyframe,
|