shaka-player 4.5.0 → 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/AUTHORS +2 -0
- package/CHANGELOG.md +98 -0
- package/CODE_OF_CONDUCT.md +1 -1
- package/CONTRIBUTORS +2 -0
- package/README.md +38 -32
- package/demo/common/asset.js +11 -17
- package/demo/common/assets.js +117 -11
- package/demo/config.js +28 -1
- package/demo/custom.js +52 -38
- package/demo/main.js +11 -3
- package/demo/search.js +7 -0
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +133 -124
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +133 -124
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +20 -18
- package/dist/locales.js +35 -31
- package/dist/receiver.compiled.debug.js +58 -50
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +58 -50
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +440 -390
- package/dist/shaka-player.compiled.debug.d.ts +440 -390
- package/dist/shaka-player.compiled.debug.externs.js +162 -77
- package/dist/shaka-player.compiled.debug.js +786 -736
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +162 -77
- package/dist/shaka-player.compiled.js +1154 -1121
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +491 -437
- package/dist/shaka-player.ui.debug.d.ts +491 -437
- package/dist/shaka-player.ui.debug.externs.js +167 -77
- package/dist/shaka-player.ui.debug.js +877 -811
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +167 -77
- package/dist/shaka-player.ui.js +1362 -1318
- package/dist/shaka-player.ui.map +4 -4
- 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/offline.md +10 -8
- package/docs/tutorials/plugins.md +5 -0
- package/docs/tutorials/ui-customization.md +13 -0
- package/docs/tutorials/ui.md +2 -1
- package/docs/tutorials/upgrade.md +3 -0
- package/externs/managedmediasource.js +24 -0
- package/externs/shaka/abr_manager.js +6 -2
- package/externs/shaka/cea.js +7 -0
- package/externs/shaka/codecs.js +5 -3
- package/externs/shaka/manifest.js +21 -5
- package/externs/shaka/manifest_parser.js +17 -0
- package/externs/shaka/net.js +2 -2
- package/externs/shaka/offline.js +9 -2
- package/externs/shaka/player.js +53 -7
- package/externs/shaka/text.js +3 -1
- package/externs/shaka/transmuxer.js +1 -1
- package/lib/abr/simple_abr_manager.js +25 -8
- package/lib/ads/media_tailor_ad_manager.js +14 -3
- 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/dash/dash_parser.js +249 -83
- package/lib/dash/mpd_utils.js +52 -31
- package/lib/dash/segment_base.js +4 -5
- package/lib/dash/segment_list.js +5 -4
- package/lib/dash/segment_template.js +83 -26
- package/lib/hls/hls_classes.js +28 -43
- package/lib/hls/hls_parser.js +761 -649
- package/lib/hls/hls_utils.js +64 -5
- package/lib/hls/manifest_text_parser.js +7 -11
- package/lib/media/adaptation_set.js +20 -13
- package/lib/media/adaptation_set_criteria.js +70 -18
- 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 +75 -21
- 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 +5 -5
- package/lib/media/segment_prefetch.js +92 -24
- package/lib/media/segment_reference.js +67 -1
- package/lib/media/segment_utils.js +343 -0
- package/lib/media/stall_detector.js +0 -3
- package/lib/media/streaming_engine.js +41 -21
- package/lib/mss/mss_parser.js +18 -2
- package/lib/net/networking_engine.js +66 -12
- package/lib/net/networking_utils.js +95 -0
- package/lib/offline/indexeddb/v1_storage_cell.js +2 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +2 -0
- package/lib/offline/manifest_converter.js +2 -0
- package/lib/offline/offline_manifest_parser.js +10 -0
- package/lib/offline/storage.js +11 -7
- package/lib/player.js +993 -1502
- package/lib/polyfill/mediasource.js +22 -1
- 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 +28 -5
- package/lib/text/ui_text_displayer.js +4 -0
- package/lib/text/vtt_text_parser.js +7 -2
- 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 +5 -4
- package/lib/transmuxer/mp3_transmuxer.js +1 -1
- package/lib/transmuxer/mpeg_ts_transmuxer.js +1 -1
- package/lib/transmuxer/mss_transmuxer.js +1 -1
- package/lib/transmuxer/ts_transmuxer.js +33 -13
- package/lib/util/buffer_utils.js +26 -4
- package/lib/util/content_steering_manager.js +358 -0
- package/lib/util/error.js +2 -6
- package/lib/util/fairplay_utils.js +1 -1
- package/lib/util/fake_event.js +5 -1
- package/lib/util/id3_utils.js +50 -1
- package/lib/util/manifest_parser_utils.js +12 -8
- package/lib/util/mp4_generator.js +2 -4
- package/lib/util/mutex.js +59 -0
- package/lib/util/object_utils.js +1 -1
- package/lib/util/periods.js +154 -179
- package/lib/util/platform.js +4 -3
- package/lib/util/player_configuration.js +35 -6
- package/lib/util/stream_utils.js +105 -98
- package/lib/util/ts_parser.js +124 -73
- package/lib/util/uint8array_utils.js +5 -1
- package/lib/util/xml_utils.js +5 -0
- package/maintained-branches.md +2 -2
- package/package.json +1 -1
- package/roadmap.md +15 -5
- package/shaka-player.uncompiled.js +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 +3 -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 +2 -1
- package/test/dash/dash_parser_integration.js +2 -1
- package/test/dash/dash_parser_live_unit.js +0 -19
- package/test/dash/dash_parser_manifest_unit.js +494 -2
- package/test/dash/mpd_utils_unit.js +61 -30
- package/test/hls/hls_live_unit.js +12 -3
- package/test/hls/hls_parser_unit.js +377 -27
- package/test/hls/manifest_text_parser_unit.js +32 -99
- package/test/media/adaptation_set_criteria_unit.js +172 -21
- package/test/media/adaptation_set_unit.js +1 -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 +1 -1
- package/test/media/play_rate_controller_unit.js +0 -48
- package/test/media/segment_index_unit.js +2 -1
- 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 +9 -0
- package/test/offline/offline_integration.js +2 -1
- package/test/offline/storage_integration.js +21 -9
- 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 +80 -27
- package/test/test/util/fake_media_source_engine.js +5 -0
- 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 +4 -0
- package/test/test/util/manifest_parser_util.js +14 -2
- package/test/test/util/offline_utils.js +1 -0
- package/test/test/util/simple_fakes.js +2 -2
- package/test/test/util/streaming_engine_util.js +3 -0
- 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 +33 -2
- package/test/transmuxer/transmuxer_engine_integration.js +9 -0
- package/test/transmuxer/transmuxer_integration.js +33 -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 +25 -19
- 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 +17 -113
- 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/externs/ui.js +17 -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/remote_button.js +3 -1
- 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 +6 -2
- package/lib/routing/node.js +0 -23
- package/lib/routing/payload.js +0 -47
- package/lib/routing/walker.js +0 -587
- package/test/routing/walker_unit.js +0 -505
|
@@ -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.
|
|
@@ -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_(
|
|
@@ -604,6 +604,10 @@ shaka.text.UITextDisplayer = class {
|
|
|
604
604
|
// Only do this for the text itself.
|
|
605
605
|
elem.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
|
|
606
606
|
}
|
|
607
|
+
const fontFamily = inherit((c) => c.fontFamily);
|
|
608
|
+
if (fontFamily) {
|
|
609
|
+
elem.style.fontFamily = fontFamily;
|
|
610
|
+
}
|
|
607
611
|
}
|
|
608
612
|
if (text) {
|
|
609
613
|
elem.textContent = text;
|
|
@@ -421,8 +421,6 @@ shaka.text.VttTextParser = class {
|
|
|
421
421
|
cue = new shaka.text.Cue(start, end, '');
|
|
422
422
|
}
|
|
423
423
|
|
|
424
|
-
VttTextParser.parseCueStyles(payload, cue, styles);
|
|
425
|
-
|
|
426
424
|
// Parse optional settings.
|
|
427
425
|
parser.skipWhitespace();
|
|
428
426
|
let word = parser.readWord();
|
|
@@ -436,6 +434,8 @@ shaka.text.VttTextParser = class {
|
|
|
436
434
|
word = parser.readWord();
|
|
437
435
|
}
|
|
438
436
|
|
|
437
|
+
VttTextParser.parseCueStyles(payload, cue, styles);
|
|
438
|
+
|
|
439
439
|
if (id != null) {
|
|
440
440
|
cue.id = id;
|
|
441
441
|
}
|
|
@@ -707,6 +707,11 @@ shaka.text.VttTextParser = class {
|
|
|
707
707
|
nestedCue.nestedCues = [];
|
|
708
708
|
nestedCue.payload = '';
|
|
709
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;
|
|
710
715
|
if (element.nodeType === Node.ELEMENT_NODE && element.nodeName) {
|
|
711
716
|
const bold = shaka.text.Cue.fontWeight.BOLD;
|
|
712
717
|
const italic = shaka.text.Cue.fontStyle.ITALIC;
|
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,
|
package/lib/transmuxer/h265.js
CHANGED
|
@@ -590,7 +590,7 @@ shaka.transmuxer.H265 = class {
|
|
|
590
590
|
static parseFrame(nalus) {
|
|
591
591
|
const H265 = shaka.transmuxer.H265;
|
|
592
592
|
let isKeyframe = false;
|
|
593
|
-
|
|
593
|
+
const nalusData = [];
|
|
594
594
|
let hvcSample = false;
|
|
595
595
|
for (const nalu of nalus) {
|
|
596
596
|
let push = false;
|
|
@@ -636,13 +636,14 @@ shaka.transmuxer.H265 = class {
|
|
|
636
636
|
naluLength[1] = (size >> 16) & 0xff;
|
|
637
637
|
naluLength[2] = (size >> 8) & 0xff;
|
|
638
638
|
naluLength[3] = size & 0xff;
|
|
639
|
-
|
|
640
|
-
|
|
639
|
+
nalusData.push(shaka.util.Uint8ArrayUtils.concat(
|
|
640
|
+
naluLength, nalu.fullData));
|
|
641
641
|
}
|
|
642
642
|
}
|
|
643
|
-
if (!
|
|
643
|
+
if (!nalusData.length) {
|
|
644
644
|
return null;
|
|
645
645
|
}
|
|
646
|
+
const data = shaka.util.Uint8ArrayUtils.concat(...nalusData);
|
|
646
647
|
return {
|
|
647
648
|
data,
|
|
648
649
|
isKeyframe,
|
|
@@ -75,7 +75,11 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
75
75
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
76
76
|
const MimeUtils = shaka.util.MimeUtils;
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
let convertedMimeType = mimeType;
|
|
79
|
+
if (contentType) {
|
|
80
|
+
convertedMimeType = this.convertCodecs(contentType, mimeType);
|
|
81
|
+
}
|
|
82
|
+
const codecs = MimeUtils.getCodecs(convertedMimeType);
|
|
79
83
|
const allCodecs = MimeUtils.splitCodecs(codecs);
|
|
80
84
|
|
|
81
85
|
const audioCodec = shaka.util.ManifestParserUtils.guessCodecsSafe(
|
|
@@ -134,7 +138,8 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
134
138
|
// MediaSource.isTypeSupported('audio/mp4; codecs="mp4a.40.34"') -> false
|
|
135
139
|
// MediaSource.isTypeSupported('audio/mp4; codecs="mp3"') -> true
|
|
136
140
|
const codecs = shaka.util.MimeUtils.getCodecs(mimeType)
|
|
137
|
-
.replace('mp4a.40.34', 'mp3')
|
|
141
|
+
.replace('mp4a.40.34', 'mp3').split(',')
|
|
142
|
+
.map(this.getCorrectVideoCodecs_).join(',');
|
|
138
143
|
if (contentType == ContentType.AUDIO) {
|
|
139
144
|
return `audio/mp4; codecs="${codecs}"`;
|
|
140
145
|
}
|
|
@@ -144,11 +149,34 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
144
149
|
}
|
|
145
150
|
|
|
146
151
|
|
|
152
|
+
/**
|
|
153
|
+
* @param {string} codec
|
|
154
|
+
* @return {string}
|
|
155
|
+
* @private
|
|
156
|
+
*/
|
|
157
|
+
getCorrectVideoCodecs_(codec) {
|
|
158
|
+
if (codec.includes('avc1')) {
|
|
159
|
+
// Convert avc1 codec string from RFC-4281 to RFC-6381 for
|
|
160
|
+
// MediaSource.isTypeSupported
|
|
161
|
+
// Example, convert avc1.66.30 to avc1.42001e (0x42 == 66 and 0x1e == 30)
|
|
162
|
+
const avcdata = codec.split('.');
|
|
163
|
+
if (avcdata.length == 3) {
|
|
164
|
+
let result = avcdata.shift() + '.';
|
|
165
|
+
result += parseInt(avcdata.shift(), 10).toString(16);
|
|
166
|
+
result +=
|
|
167
|
+
('000' + parseInt(avcdata.shift(), 10).toString(16)).slice(-4);
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return codec;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
|
|
147
175
|
/**
|
|
148
176
|
* @override
|
|
149
177
|
* @export
|
|
150
178
|
*/
|
|
151
|
-
|
|
179
|
+
getOriginalMimeType() {
|
|
152
180
|
return this.originalMimeType_;
|
|
153
181
|
}
|
|
154
182
|
|
|
@@ -678,11 +706,7 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
678
706
|
const videoData = tsParser.getVideoData();
|
|
679
707
|
for (let i = 0; i < videoData.length; i++) {
|
|
680
708
|
const pes = videoData[i];
|
|
681
|
-
|
|
682
|
-
if (i + 1 < videoData.length) {
|
|
683
|
-
nextPes = videoData[i + 1];
|
|
684
|
-
}
|
|
685
|
-
const dataNalus = tsParser.parseNalus(pes, nextPes);
|
|
709
|
+
const dataNalus = pes.nalus;
|
|
686
710
|
nalus = nalus.concat(dataNalus);
|
|
687
711
|
const frame = H264.parseFrame(dataNalus);
|
|
688
712
|
if (!frame) {
|
|
@@ -768,11 +792,7 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
768
792
|
const videoData = tsParser.getVideoData();
|
|
769
793
|
for (let i = 0; i < videoData.length; i++) {
|
|
770
794
|
const pes = videoData[i];
|
|
771
|
-
|
|
772
|
-
if (i + 1 < videoData.length) {
|
|
773
|
-
nextPes = videoData[i + 1];
|
|
774
|
-
}
|
|
775
|
-
const dataNalus = tsParser.parseNalus(pes, nextPes);
|
|
795
|
+
const dataNalus = pes.nalus;
|
|
776
796
|
nalus = nalus.concat(dataNalus);
|
|
777
797
|
const frame = H265.parseFrame(dataNalus);
|
|
778
798
|
if (!frame) {
|
package/lib/util/buffer_utils.js
CHANGED
|
@@ -110,6 +110,23 @@ shaka.util.BufferUtils = class {
|
|
|
110
110
|
return shaka.util.BufferUtils.view_(data, offset, length, Uint8Array);
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Creates a new Uint16Array view on the same buffer. This clamps the values
|
|
115
|
+
* to be within the same view (i.e. you can't use this to move past the end
|
|
116
|
+
* of the view, even if the underlying buffer is larger). However, you can
|
|
117
|
+
* pass a negative offset to access the data before the view.
|
|
118
|
+
*
|
|
119
|
+
* @param {BufferSource} data
|
|
120
|
+
* @param {number=} offset The offset from the beginning of this data's view
|
|
121
|
+
* to start the new view at.
|
|
122
|
+
* @param {number=} length The byte length of the new view.
|
|
123
|
+
* @return {!Uint16Array}
|
|
124
|
+
* @export
|
|
125
|
+
*/
|
|
126
|
+
static toUint16(data, offset = 0, length = Infinity) {
|
|
127
|
+
return shaka.util.BufferUtils.view_(data, offset, length, Uint16Array);
|
|
128
|
+
}
|
|
129
|
+
|
|
113
130
|
/**
|
|
114
131
|
* Creates a DataView over the given buffer.
|
|
115
132
|
*
|
|
@@ -135,15 +152,20 @@ shaka.util.BufferUtils = class {
|
|
|
135
152
|
*/
|
|
136
153
|
static view_(data, offset, length, Type) {
|
|
137
154
|
const buffer = shaka.util.BufferUtils.unsafeGetArrayBuffer_(data);
|
|
155
|
+
let bytesPerElement = 1;
|
|
156
|
+
if ('BYTES_PER_ELEMENT' in Type) {
|
|
157
|
+
bytesPerElement = Type.BYTES_PER_ELEMENT;
|
|
158
|
+
}
|
|
138
159
|
// Absolute end of the |data| view within |buffer|.
|
|
139
160
|
/** @suppress {strictMissingProperties} */
|
|
140
|
-
const dataEnd = (data.byteOffset || 0) + data.byteLength
|
|
161
|
+
const dataEnd = ((data.byteOffset || 0) + data.byteLength) /
|
|
162
|
+
bytesPerElement;
|
|
141
163
|
// Absolute start of the result within |buffer|.
|
|
142
164
|
/** @suppress {strictMissingProperties} */
|
|
143
|
-
const rawStart = (data.byteOffset || 0) + offset;
|
|
144
|
-
const start = Math.max(0, Math.min(rawStart, dataEnd));
|
|
165
|
+
const rawStart = ((data.byteOffset || 0) + offset) / bytesPerElement;
|
|
166
|
+
const start = Math.floor(Math.max(0, Math.min(rawStart, dataEnd)));
|
|
145
167
|
// Absolute end of the result within |buffer|.
|
|
146
|
-
const end = Math.min(start + Math.max(length, 0), dataEnd);
|
|
168
|
+
const end = Math.floor(Math.min(start + Math.max(length, 0), dataEnd));
|
|
147
169
|
return new Type(buffer, start, end - start);
|
|
148
170
|
}
|
|
149
171
|
};
|