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
package/lib/util/stream_utils.js
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
goog.provide('shaka.util.StreamUtils');
|
|
8
8
|
|
|
9
9
|
goog.require('goog.asserts');
|
|
10
|
-
goog.require('shaka.config.CodecSwitchingStrategy');
|
|
11
10
|
goog.require('shaka.log');
|
|
12
11
|
goog.require('shaka.media.Capabilities');
|
|
13
12
|
goog.require('shaka.text.TextEngine');
|
|
@@ -32,12 +31,10 @@ shaka.util.StreamUtils = class {
|
|
|
32
31
|
* @param {!shaka.extern.Manifest} manifest
|
|
33
32
|
* @param {!Array.<string>} preferredVideoCodecs
|
|
34
33
|
* @param {!Array.<string>} preferredAudioCodecs
|
|
35
|
-
* @param {number} preferredAudioChannelCount
|
|
36
34
|
* @param {!Array.<string>} preferredDecodingAttributes
|
|
37
35
|
*/
|
|
38
36
|
static chooseCodecsAndFilterManifest(manifest, preferredVideoCodecs,
|
|
39
|
-
preferredAudioCodecs,
|
|
40
|
-
preferredDecodingAttributes) {
|
|
37
|
+
preferredAudioCodecs, preferredDecodingAttributes) {
|
|
41
38
|
const StreamUtils = shaka.util.StreamUtils;
|
|
42
39
|
const MimeUtils = shaka.util.MimeUtils;
|
|
43
40
|
|
|
@@ -76,11 +73,6 @@ shaka.util.StreamUtils = class {
|
|
|
76
73
|
variants = bestVariants;
|
|
77
74
|
}
|
|
78
75
|
|
|
79
|
-
if (preferredAudioChannelCount) {
|
|
80
|
-
variants = StreamUtils.filterVariantsByAudioChannelCount(
|
|
81
|
-
variants, preferredAudioChannelCount);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
76
|
const audioStreamsSet = new Set();
|
|
85
77
|
const videoStreamsSet = new Set();
|
|
86
78
|
for (const variant of variants) {
|
|
@@ -95,23 +87,34 @@ shaka.util.StreamUtils = class {
|
|
|
95
87
|
const audioStreams = Array.from(audioStreamsSet).sort((v1, v2) => {
|
|
96
88
|
return v1.bandwidth - v2.bandwidth;
|
|
97
89
|
});
|
|
98
|
-
const
|
|
90
|
+
const validAudioIds = [];
|
|
91
|
+
const validAudioStreamsMap = new Map();
|
|
99
92
|
const getAudioId = (stream) => {
|
|
100
93
|
return stream.language + (stream.channelsCount || 0) +
|
|
101
|
-
stream.roles.join(',') +
|
|
94
|
+
(stream.audioSamplingRate || 0) + stream.roles.join(',') +
|
|
95
|
+
stream.label + stream.groupId + stream.fastSwitching;
|
|
102
96
|
};
|
|
103
97
|
for (const stream of audioStreams) {
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
98
|
+
const groupId = getAudioId(stream);
|
|
99
|
+
const validAudioStreams = validAudioStreamsMap.get(groupId) || [];
|
|
100
|
+
if (!validAudioStreams.length) {
|
|
101
|
+
validAudioStreams.push(stream);
|
|
102
|
+
validAudioIds.push(stream.id);
|
|
107
103
|
} else {
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
104
|
+
const previousStream = validAudioStreams[validAudioStreams.length - 1];
|
|
105
|
+
const previousCodec =
|
|
106
|
+
MimeUtils.getNormalizedCodec(previousStream.codecs);
|
|
107
|
+
const currentCodec =
|
|
108
|
+
MimeUtils.getNormalizedCodec(stream.codecs);
|
|
109
|
+
if (previousCodec == currentCodec) {
|
|
110
|
+
if (stream.bandwidth > previousStream.bandwidth) {
|
|
111
|
+
validAudioStreams.push(stream);
|
|
112
|
+
validAudioIds.push(stream.id);
|
|
113
|
+
}
|
|
111
114
|
}
|
|
112
115
|
}
|
|
116
|
+
validAudioStreamsMap.set(groupId, validAudioStreams);
|
|
113
117
|
}
|
|
114
|
-
const validAudioStreams = [...audioStreamsMap.values()];
|
|
115
118
|
|
|
116
119
|
const videoStreams = Array.from(videoStreamsSet)
|
|
117
120
|
.sort((v1, v2) => {
|
|
@@ -124,10 +127,18 @@ shaka.util.StreamUtils = class {
|
|
|
124
127
|
const isChangeTypeSupported =
|
|
125
128
|
shaka.media.Capabilities.isChangeTypeSupported();
|
|
126
129
|
|
|
127
|
-
const
|
|
130
|
+
const validVideoIds = [];
|
|
131
|
+
const validVideoStreamsMap = new Map();
|
|
132
|
+
const getVideoGroupId = (stream) => {
|
|
133
|
+
return Math.round(stream.frameRate || 0) + (stream.hdr || '') +
|
|
134
|
+
stream.fastSwitching;
|
|
135
|
+
};
|
|
128
136
|
for (const stream of videoStreams) {
|
|
137
|
+
const groupId = getVideoGroupId(stream);
|
|
138
|
+
const validVideoStreams = validVideoStreamsMap.get(groupId) || [];
|
|
129
139
|
if (!validVideoStreams.length) {
|
|
130
140
|
validVideoStreams.push(stream);
|
|
141
|
+
validVideoIds.push(stream.id);
|
|
131
142
|
} else {
|
|
132
143
|
const previousStream = validVideoStreams[validVideoStreams.length - 1];
|
|
133
144
|
if (!isChangeTypeSupported) {
|
|
@@ -142,6 +153,7 @@ shaka.util.StreamUtils = class {
|
|
|
142
153
|
if (stream.width > previousStream.width ||
|
|
143
154
|
stream.height > previousStream.height) {
|
|
144
155
|
validVideoStreams.push(stream);
|
|
156
|
+
validVideoIds.push(stream.id);
|
|
145
157
|
} else if (stream.width == previousStream.width &&
|
|
146
158
|
stream.height == previousStream.height) {
|
|
147
159
|
const previousCodec =
|
|
@@ -151,17 +163,14 @@ shaka.util.StreamUtils = class {
|
|
|
151
163
|
if (previousCodec == currentCodec) {
|
|
152
164
|
if (stream.bandwidth < previousStream.bandwidth) {
|
|
153
165
|
validVideoStreams.push(stream);
|
|
166
|
+
validVideoIds.push(stream.id);
|
|
154
167
|
}
|
|
155
168
|
}
|
|
156
169
|
}
|
|
157
170
|
}
|
|
171
|
+
validVideoStreamsMap.set(groupId, validVideoStreams);
|
|
158
172
|
}
|
|
159
173
|
|
|
160
|
-
const validAudioIds =
|
|
161
|
-
validAudioStreams.map((audioStream) => audioStream.id);
|
|
162
|
-
const validVideoIds =
|
|
163
|
-
validVideoStreams.map((videoStream) => videoStream.id);
|
|
164
|
-
|
|
165
174
|
// Filter out any variants that don't match, forcing AbrManager to choose
|
|
166
175
|
// from a single video codec and a single audio codec possible.
|
|
167
176
|
manifest.variants = manifest.variants.filter((variant) => {
|
|
@@ -319,14 +328,11 @@ shaka.util.StreamUtils = class {
|
|
|
319
328
|
* Alters the given Manifest to filter out any unplayable streams.
|
|
320
329
|
*
|
|
321
330
|
* @param {shaka.media.DrmEngine} drmEngine
|
|
322
|
-
* @param {?shaka.extern.Variant} currentVariant
|
|
323
331
|
* @param {shaka.extern.Manifest} manifest
|
|
324
|
-
* @param {shaka.config.CodecSwitchingStrategy=} codecSwitchingStrategy
|
|
325
332
|
*/
|
|
326
|
-
static async filterManifest(drmEngine,
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
manifest.offlineSessionIds.length > 0);
|
|
333
|
+
static async filterManifest(drmEngine, manifest) {
|
|
334
|
+
await shaka.util.StreamUtils.filterManifestByMediaCapabilities(
|
|
335
|
+
drmEngine, manifest, manifest.offlineSessionIds.length > 0);
|
|
330
336
|
shaka.util.StreamUtils.filterTextStreams_(manifest);
|
|
331
337
|
await shaka.util.StreamUtils.filterImageStreams_(manifest);
|
|
332
338
|
}
|
|
@@ -336,30 +342,53 @@ shaka.util.StreamUtils = class {
|
|
|
336
342
|
* Alters the given Manifest to filter out any streams unsupported by the
|
|
337
343
|
* platform via MediaCapabilities.decodingInfo() API.
|
|
338
344
|
*
|
|
345
|
+
* @param {shaka.media.DrmEngine} drmEngine
|
|
339
346
|
* @param {shaka.extern.Manifest} manifest
|
|
340
347
|
* @param {boolean} usePersistentLicenses
|
|
341
348
|
*/
|
|
342
349
|
static async filterManifestByMediaCapabilities(
|
|
343
|
-
manifest, usePersistentLicenses) {
|
|
350
|
+
drmEngine, manifest, usePersistentLicenses) {
|
|
344
351
|
goog.asserts.assert(navigator.mediaCapabilities,
|
|
345
352
|
'MediaCapabilities should be valid.');
|
|
346
353
|
|
|
347
354
|
await shaka.util.StreamUtils.getDecodingInfosForVariants(
|
|
348
355
|
manifest.variants, usePersistentLicenses, /* srcEquals= */ false,
|
|
349
356
|
/** preferredKeySystems= */ []);
|
|
357
|
+
|
|
358
|
+
let keySystem = null;
|
|
359
|
+
if (drmEngine) {
|
|
360
|
+
const drmInfo = drmEngine.getDrmInfo();
|
|
361
|
+
if (drmInfo) {
|
|
362
|
+
keySystem = drmInfo.keySystem;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
367
|
+
const Capabilities = shaka.media.Capabilities;
|
|
368
|
+
const ManifestParserUtils = shaka.util.ManifestParserUtils;
|
|
369
|
+
const MimeUtils = shaka.util.MimeUtils;
|
|
370
|
+
const StreamUtils = shaka.util.StreamUtils;
|
|
371
|
+
const isXboxOne = shaka.util.Platform.isXboxOne();
|
|
372
|
+
|
|
350
373
|
manifest.variants = manifest.variants.filter((variant) => {
|
|
351
374
|
// See: https://github.com/shaka-project/shaka-player/issues/3860
|
|
352
375
|
const video = variant.video;
|
|
376
|
+
const videoWidth = (video && video.width) || 0;
|
|
377
|
+
const videoHeight = (video && video.height) || 0;
|
|
353
378
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
379
|
+
// See: https://github.com/shaka-project/shaka-player/issues/3380
|
|
380
|
+
// Note: it makes sense to drop early
|
|
381
|
+
if (isXboxOne && video &&
|
|
382
|
+
(videoWidth > 1920 || videoHeight > 1080) &&
|
|
383
|
+
(video.codecs.includes('avc1.') || video.codecs.includes('avc3.'))
|
|
384
|
+
) {
|
|
385
|
+
shaka.log.debug('Dropping variant - not compatible with platform',
|
|
386
|
+
StreamUtils.getVariantSummaryString_(variant));
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
359
389
|
|
|
360
390
|
if (video) {
|
|
361
391
|
let videoCodecs = StreamUtils.getCorrectVideoCodecs_(video.codecs);
|
|
362
|
-
|
|
363
392
|
// For multiplexed streams. Here we must check the audio of the
|
|
364
393
|
// stream to see if it is compatible.
|
|
365
394
|
if (video.codecs.includes(',')) {
|
|
@@ -368,7 +397,6 @@ shaka.util.StreamUtils = class {
|
|
|
368
397
|
videoCodecs = ManifestParserUtils.guessCodecs(
|
|
369
398
|
ContentType.VIDEO, allCodecs);
|
|
370
399
|
videoCodecs = StreamUtils.getCorrectVideoCodecs_(videoCodecs);
|
|
371
|
-
|
|
372
400
|
let audioCodecs = ManifestParserUtils.guessCodecs(
|
|
373
401
|
ContentType.AUDIO, allCodecs);
|
|
374
402
|
audioCodecs = StreamUtils.getCorrectAudioCodecs_(audioCodecs);
|
|
@@ -410,19 +438,19 @@ shaka.util.StreamUtils = class {
|
|
|
410
438
|
audio.codecs = codecs;
|
|
411
439
|
}
|
|
412
440
|
|
|
413
|
-
// See: https://github.com/shaka-project/shaka-player/issues/3380
|
|
414
|
-
if (shaka.util.Platform.isXboxOne() && video &&
|
|
415
|
-
((video.width && video.width > 1920) ||
|
|
416
|
-
(video.height && video.height > 1080)) &&
|
|
417
|
-
(video.codecs.includes('avc1.') ||
|
|
418
|
-
video.codecs.includes('avc3.'))) {
|
|
419
|
-
shaka.log.debug('Dropping variant - not compatible with platform',
|
|
420
|
-
StreamUtils.getVariantSummaryString_(variant));
|
|
421
|
-
return false;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
441
|
const supported = variant.decodingInfos.some((decodingInfo) => {
|
|
425
|
-
|
|
442
|
+
if (!decodingInfo.supported) {
|
|
443
|
+
return false;
|
|
444
|
+
}
|
|
445
|
+
if (keySystem) {
|
|
446
|
+
const keySystemAccess = decodingInfo.keySystemAccess;
|
|
447
|
+
if (keySystemAccess) {
|
|
448
|
+
if (keySystemAccess.keySystem != keySystem) {
|
|
449
|
+
return false;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return true;
|
|
426
454
|
});
|
|
427
455
|
// Filter out all unsupported variants.
|
|
428
456
|
if (!supported) {
|
|
@@ -930,7 +958,10 @@ shaka.util.StreamUtils = class {
|
|
|
930
958
|
static async filterImageStreams_(manifest) {
|
|
931
959
|
const imageStreams = [];
|
|
932
960
|
for (const stream of manifest.imageStreams) {
|
|
933
|
-
|
|
961
|
+
let mimeType = stream.mimeType;
|
|
962
|
+
if (mimeType == 'application/mp4' && stream.codecs == 'mjpg') {
|
|
963
|
+
mimeType = 'image/jpg';
|
|
964
|
+
}
|
|
934
965
|
if (!shaka.util.StreamUtils.supportedImageMimeTypes_.has(mimeType)) {
|
|
935
966
|
const minImage = shaka.util.StreamUtils.minImage_.get(mimeType);
|
|
936
967
|
if (minImage) {
|
|
@@ -1080,6 +1111,7 @@ shaka.util.StreamUtils = class {
|
|
|
1080
1111
|
frameRate: null,
|
|
1081
1112
|
pixelAspectRatio: null,
|
|
1082
1113
|
hdr: null,
|
|
1114
|
+
videoLayout: null,
|
|
1083
1115
|
mimeType: mimeType,
|
|
1084
1116
|
audioMimeType: audioMimeType,
|
|
1085
1117
|
videoMimeType: videoMimeType,
|
|
@@ -1115,6 +1147,7 @@ shaka.util.StreamUtils = class {
|
|
|
1115
1147
|
track.pixelAspectRatio = video.pixelAspectRatio || null;
|
|
1116
1148
|
track.videoBandwidth = video.bandwidth || null;
|
|
1117
1149
|
track.hdr = video.hdr || null;
|
|
1150
|
+
track.videoLayout = video.videoLayout || null;
|
|
1118
1151
|
}
|
|
1119
1152
|
|
|
1120
1153
|
if (audio) {
|
|
@@ -1155,6 +1188,7 @@ shaka.util.StreamUtils = class {
|
|
|
1155
1188
|
frameRate: null,
|
|
1156
1189
|
pixelAspectRatio: null,
|
|
1157
1190
|
hdr: null,
|
|
1191
|
+
videoLayout: null,
|
|
1158
1192
|
mimeType: stream.mimeType,
|
|
1159
1193
|
audioMimeType: null,
|
|
1160
1194
|
videoMimeType: null,
|
|
@@ -1231,10 +1265,11 @@ shaka.util.StreamUtils = class {
|
|
|
1231
1265
|
frameRate: null,
|
|
1232
1266
|
pixelAspectRatio: null,
|
|
1233
1267
|
hdr: null,
|
|
1268
|
+
videoLayout: null,
|
|
1234
1269
|
mimeType: stream.mimeType,
|
|
1235
1270
|
audioMimeType: null,
|
|
1236
1271
|
videoMimeType: null,
|
|
1237
|
-
codecs: null,
|
|
1272
|
+
codecs: stream.codecs || null,
|
|
1238
1273
|
audioCodec: null,
|
|
1239
1274
|
videoCodec: null,
|
|
1240
1275
|
primary: false,
|
|
@@ -1358,6 +1393,7 @@ shaka.util.StreamUtils = class {
|
|
|
1358
1393
|
frameRate: null,
|
|
1359
1394
|
pixelAspectRatio: null,
|
|
1360
1395
|
hdr: null,
|
|
1396
|
+
videoLayout: null,
|
|
1361
1397
|
mimeType: null,
|
|
1362
1398
|
audioMimeType: null,
|
|
1363
1399
|
videoMimeType: null,
|
|
@@ -1412,52 +1448,6 @@ shaka.util.StreamUtils = class {
|
|
|
1412
1448
|
}
|
|
1413
1449
|
|
|
1414
1450
|
|
|
1415
|
-
/**
|
|
1416
|
-
* Filters variants according to the given audio channel count config.
|
|
1417
|
-
*
|
|
1418
|
-
* @param {!Array.<shaka.extern.Variant>} variants
|
|
1419
|
-
* @param {number} preferredAudioChannelCount
|
|
1420
|
-
* @return {!Array.<!shaka.extern.Variant>}
|
|
1421
|
-
*/
|
|
1422
|
-
static filterVariantsByAudioChannelCount(
|
|
1423
|
-
variants, preferredAudioChannelCount) {
|
|
1424
|
-
// Group variants by their audio channel counts.
|
|
1425
|
-
const variantsWithChannelCounts =
|
|
1426
|
-
variants.filter((v) => v.audio && v.audio.channelsCount);
|
|
1427
|
-
|
|
1428
|
-
/** @type {!Map.<number, !Array.<shaka.extern.Variant>>} */
|
|
1429
|
-
const variantsByChannelCount = new Map();
|
|
1430
|
-
const capableVariants = [];
|
|
1431
|
-
for (const variant of variantsWithChannelCounts) {
|
|
1432
|
-
const count = variant.audio.channelsCount;
|
|
1433
|
-
goog.asserts.assert(count != null, 'Must have count after filtering!');
|
|
1434
|
-
if (!variantsByChannelCount.has(count)) {
|
|
1435
|
-
variantsByChannelCount.set(count, []);
|
|
1436
|
-
}
|
|
1437
|
-
variantsByChannelCount.get(count).push(variant);
|
|
1438
|
-
if (count <= preferredAudioChannelCount) {
|
|
1439
|
-
capableVariants.push(variant);
|
|
1440
|
-
}
|
|
1441
|
-
}
|
|
1442
|
-
|
|
1443
|
-
// return all capable channelcounts
|
|
1444
|
-
if (capableVariants.length) {
|
|
1445
|
-
return capableVariants;
|
|
1446
|
-
}
|
|
1447
|
-
|
|
1448
|
-
/** @type {!Array.<number>} */
|
|
1449
|
-
const channelCounts = Array.from(variantsByChannelCount.keys());
|
|
1450
|
-
|
|
1451
|
-
// If no variant has audio channel count info, return the original variants.
|
|
1452
|
-
if (channelCounts.length == 0) {
|
|
1453
|
-
return variants;
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
|
-
// If all variants have more audio channels than the config, choose the
|
|
1457
|
-
// variants with the fewest audio channels.
|
|
1458
|
-
return variantsByChannelCount.get(Math.min(...channelCounts));
|
|
1459
|
-
}
|
|
1460
|
-
|
|
1461
1451
|
/**
|
|
1462
1452
|
* Chooses streams according to the given config.
|
|
1463
1453
|
* Works both for Stream and Track types due to their similarities.
|
|
@@ -1608,6 +1598,23 @@ shaka.util.StreamUtils = class {
|
|
|
1608
1598
|
}
|
|
1609
1599
|
|
|
1610
1600
|
|
|
1601
|
+
/**
|
|
1602
|
+
* Indicates if some of the variant's streams are fastSwitching.
|
|
1603
|
+
*
|
|
1604
|
+
* @param {shaka.extern.Variant} variant
|
|
1605
|
+
* @return {boolean}
|
|
1606
|
+
*/
|
|
1607
|
+
static isFastSwitching(variant) {
|
|
1608
|
+
if (variant.audio && variant.audio.fastSwitching) {
|
|
1609
|
+
return true;
|
|
1610
|
+
}
|
|
1611
|
+
if (variant.video && variant.video.fastSwitching) {
|
|
1612
|
+
return true;
|
|
1613
|
+
}
|
|
1614
|
+
return false;
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
|
|
1611
1618
|
/**
|
|
1612
1619
|
* Returns a string of a variant, with the attribute values of its audio
|
|
1613
1620
|
* and/or video streams for log printing.
|
package/lib/util/ts_parser.js
CHANGED
|
@@ -35,6 +35,9 @@ shaka.util.TsParser = class {
|
|
|
35
35
|
/** @private {!Array.<Uint8Array>} */
|
|
36
36
|
this.videoData_ = [];
|
|
37
37
|
|
|
38
|
+
/** @private {!Array.<shaka.extern.MPEG_PES>} */
|
|
39
|
+
this.videoPes_ = [];
|
|
40
|
+
|
|
38
41
|
/** @private {?number} */
|
|
39
42
|
this.audioPid_ = null;
|
|
40
43
|
|
|
@@ -44,6 +47,9 @@ shaka.util.TsParser = class {
|
|
|
44
47
|
/** @private {!Array.<Uint8Array>} */
|
|
45
48
|
this.audioData_ = [];
|
|
46
49
|
|
|
50
|
+
/** @private {!Array.<shaka.extern.MPEG_PES>} */
|
|
51
|
+
this.audioPes_ = [];
|
|
52
|
+
|
|
47
53
|
/** @private {?number} */
|
|
48
54
|
this.id3Pid_ = null;
|
|
49
55
|
|
|
@@ -58,7 +64,9 @@ shaka.util.TsParser = class {
|
|
|
58
64
|
*/
|
|
59
65
|
clearData() {
|
|
60
66
|
this.videoData_ = [];
|
|
67
|
+
this.videoPes_ = [];
|
|
61
68
|
this.audioData_ = [];
|
|
69
|
+
this.audioPes_ = [];
|
|
62
70
|
this.id3Data_ = [];
|
|
63
71
|
}
|
|
64
72
|
|
|
@@ -360,6 +368,7 @@ shaka.util.TsParser = class {
|
|
|
360
368
|
packetLength: ((data[4] << 8) | data[5]),
|
|
361
369
|
pts: null,
|
|
362
370
|
dts: null,
|
|
371
|
+
nalus: [],
|
|
363
372
|
};
|
|
364
373
|
|
|
365
374
|
// if PES parsed length is not zero and greater than total received length,
|
|
@@ -430,7 +439,7 @@ shaka.util.TsParser = class {
|
|
|
430
439
|
shaka.Deprecate.deprecateFeature(5,
|
|
431
440
|
'TsParser',
|
|
432
441
|
'Please use parseNalus function instead.');
|
|
433
|
-
return this.parseNalus(pes
|
|
442
|
+
return this.parseNalus(pes);
|
|
434
443
|
}
|
|
435
444
|
|
|
436
445
|
/**
|
|
@@ -440,12 +449,11 @@ shaka.util.TsParser = class {
|
|
|
440
449
|
* Credit to https://github.com/video-dev/hls.js/blob/master/src/demux/tsdemuxer.ts
|
|
441
450
|
*
|
|
442
451
|
* @param {shaka.extern.MPEG_PES} pes
|
|
443
|
-
* @param {?shaka.extern.MPEG_PES=} nextPes
|
|
444
452
|
* @param {?shaka.extern.VideoNalu=} lastNalu
|
|
445
453
|
* @return {!Array.<shaka.extern.VideoNalu>}
|
|
446
454
|
* @export
|
|
447
455
|
*/
|
|
448
|
-
parseNalus(pes,
|
|
456
|
+
parseNalus(pes, lastNalu) {
|
|
449
457
|
const timescale = shaka.util.TsParser.Timescale;
|
|
450
458
|
const time = pes.pts ? pes.pts / timescale : null;
|
|
451
459
|
const data = pes.data;
|
|
@@ -479,21 +487,21 @@ shaka.util.TsParser = class {
|
|
|
479
487
|
const value = data[i];
|
|
480
488
|
if (!value) {
|
|
481
489
|
numZeros++;
|
|
482
|
-
} else if (numZeros >= 2 && value == 1 && lastNalu) {
|
|
483
|
-
// If we are scanning the next PES, we need append the data to the
|
|
484
|
-
// previous Nalu and don't scan for more nalus.
|
|
485
|
-
const startCodeSize = numZeros > 3 ? 3 : numZeros;
|
|
486
|
-
const lastByteToKeep = i - startCodeSize;
|
|
487
|
-
// Optimization
|
|
488
|
-
if (lastByteToKeep == 0) {
|
|
489
|
-
return [];
|
|
490
|
-
}
|
|
491
|
-
lastNalu.data = shaka.util.Uint8ArrayUtils.concat(
|
|
492
|
-
lastNalu.data, data.subarray(0, lastByteToKeep));
|
|
493
|
-
lastNalu.fullData = shaka.util.Uint8ArrayUtils.concat(
|
|
494
|
-
lastNalu.fullData, data.subarray(0, lastByteToKeep));
|
|
495
|
-
return [];
|
|
496
490
|
} else if (numZeros >= 2 && value == 1) {
|
|
491
|
+
if (lastNalu && !nalus.length && lastNaluStart == -1) {
|
|
492
|
+
// If we are scanning the next PES, we need append the data to the
|
|
493
|
+
// previous Nalu and don't scan for more nalus.
|
|
494
|
+
const startCodeSize = numZeros > 3 ? 3 : numZeros;
|
|
495
|
+
const lastByteToKeep = i - startCodeSize;
|
|
496
|
+
// Optimization
|
|
497
|
+
if (lastByteToKeep != 0) {
|
|
498
|
+
const prevData = data.subarray(0, lastByteToKeep);
|
|
499
|
+
lastNalu.data = shaka.util.Uint8ArrayUtils.concat(
|
|
500
|
+
lastNalu.data, prevData);
|
|
501
|
+
lastNalu.fullData = shaka.util.Uint8ArrayUtils.concat(
|
|
502
|
+
lastNalu.fullData, prevData);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
497
505
|
// We just read a start code. Consume the NALU we passed, if any.
|
|
498
506
|
if (lastNaluStart >= 0) {
|
|
499
507
|
// Because the start position includes the header size.
|
|
@@ -513,11 +521,14 @@ shaka.util.TsParser = class {
|
|
|
513
521
|
time: time,
|
|
514
522
|
};
|
|
515
523
|
nalus.push(nalu);
|
|
516
|
-
} else if (lastNalu) {
|
|
524
|
+
} else if (lastNalu && !nalus.length) {
|
|
517
525
|
const overflow = i - numZeros;
|
|
518
526
|
if (overflow > 0) {
|
|
527
|
+
const prevData = data.subarray(0, overflow);
|
|
519
528
|
lastNalu.data = shaka.util.Uint8ArrayUtils.concat(
|
|
520
|
-
lastNalu.data,
|
|
529
|
+
lastNalu.data, prevData);
|
|
530
|
+
lastNalu.fullData = shaka.util.Uint8ArrayUtils.concat(
|
|
531
|
+
lastNalu.fullData, prevData);
|
|
521
532
|
}
|
|
522
533
|
}
|
|
523
534
|
|
|
@@ -553,9 +564,6 @@ shaka.util.TsParser = class {
|
|
|
553
564
|
type: lastNaluType,
|
|
554
565
|
time: time,
|
|
555
566
|
};
|
|
556
|
-
if (nextPes) {
|
|
557
|
-
this.parseNalus(nextPes, /* nextPes= */ null, infoOfLastNalu);
|
|
558
|
-
}
|
|
559
567
|
}
|
|
560
568
|
}
|
|
561
569
|
|
|
@@ -602,73 +610,122 @@ shaka.util.TsParser = class {
|
|
|
602
610
|
* @export
|
|
603
611
|
*/
|
|
604
612
|
getAudioData() {
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
const
|
|
608
|
-
|
|
609
|
-
|
|
613
|
+
if (this.audioData_.length && !this.audioPes_.length) {
|
|
614
|
+
let sort = false;
|
|
615
|
+
for (const audioData of this.audioData_) {
|
|
616
|
+
const pes = this.parsePES_(audioData);
|
|
617
|
+
if (pes && pes.pts != null && pes.dts != null) {
|
|
618
|
+
if (this.audioPes_.length &&
|
|
619
|
+
pes.dts < (this.audioPes_[this.audioPes_.length - 1].dts || 0)) {
|
|
620
|
+
sort = true;
|
|
621
|
+
}
|
|
622
|
+
this.audioPes_.push(pes);
|
|
623
|
+
} else if (this.audioPes_.length) {
|
|
624
|
+
const data = pes ? pes.data : audioData;
|
|
625
|
+
if (!data) {
|
|
626
|
+
continue;
|
|
627
|
+
}
|
|
628
|
+
const previousPes = this.audioPes_.pop();
|
|
629
|
+
previousPes.data =
|
|
630
|
+
shaka.util.Uint8ArrayUtils.concat(previousPes.data, data);
|
|
631
|
+
this.audioPes_.push(previousPes);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
if (sort) {
|
|
635
|
+
this.audioPes_ = this.audioPes_.sort((a, b) => {
|
|
636
|
+
const deltadts = (a.dts || 0) - (b.dts || 0);
|
|
637
|
+
const deltapts = (a.pts || 0) - (b.pts || 0);
|
|
638
|
+
return deltadts || deltapts;
|
|
639
|
+
});
|
|
610
640
|
}
|
|
611
641
|
}
|
|
612
|
-
return
|
|
642
|
+
return this.audioPes_;
|
|
613
643
|
}
|
|
614
644
|
|
|
615
645
|
/**
|
|
616
646
|
* Return the audio data
|
|
617
647
|
*
|
|
648
|
+
* @param {boolean=} naluProcessing
|
|
618
649
|
* @return {!Array.<shaka.extern.MPEG_PES>}
|
|
619
650
|
* @export
|
|
620
651
|
*/
|
|
621
|
-
getVideoData() {
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
652
|
+
getVideoData(naluProcessing = true) {
|
|
653
|
+
if (this.videoData_.length && !this.videoPes_.length) {
|
|
654
|
+
let sort = false;
|
|
655
|
+
for (const videoData of this.videoData_) {
|
|
656
|
+
const pes = this.parsePES_(videoData);
|
|
657
|
+
if (pes && pes.pts != null && pes.dts != null) {
|
|
658
|
+
if (this.videoPes_.length &&
|
|
659
|
+
pes.dts < (this.videoPes_[this.videoPes_.length - 1].dts || 0)) {
|
|
660
|
+
sort = true;
|
|
661
|
+
}
|
|
662
|
+
this.videoPes_.push(pes);
|
|
663
|
+
} else if (this.videoPes_.length) {
|
|
664
|
+
const data = pes ? pes.data : videoData;
|
|
665
|
+
if (!data) {
|
|
666
|
+
continue;
|
|
667
|
+
}
|
|
668
|
+
const previousPes = this.videoPes_.pop();
|
|
669
|
+
previousPes.data =
|
|
670
|
+
shaka.util.Uint8ArrayUtils.concat(previousPes.data, data);
|
|
671
|
+
this.videoPes_.push(previousPes);
|
|
632
672
|
}
|
|
633
|
-
const previousPes = video.pop();
|
|
634
|
-
previousPes.data =
|
|
635
|
-
Uint8ArrayUtils.concat(previousPes.data, data);
|
|
636
|
-
video.push(previousPes);
|
|
637
673
|
}
|
|
674
|
+
if (naluProcessing) {
|
|
675
|
+
let lastNalu;
|
|
676
|
+
for (const pes of this.videoPes_) {
|
|
677
|
+
pes.nalus = this.parseNalus(pes, lastNalu);
|
|
678
|
+
if (pes.nalus.length) {
|
|
679
|
+
lastNalu = pes.nalus[pes.nalus.length - 1];
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
this.videoPes_ = this.videoPes_.filter((pes) => {
|
|
683
|
+
return pes.nalus.length;
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
if (sort) {
|
|
687
|
+
this.videoPes_ = this.videoPes_.sort((a, b) => {
|
|
688
|
+
const deltadts = (a.dts || 0) - (b.dts || 0);
|
|
689
|
+
const deltapts = (a.pts || 0) - (b.pts || 0);
|
|
690
|
+
return deltadts || deltapts;
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
if (!naluProcessing) {
|
|
695
|
+
const prevVideoPes = this.videoPes_;
|
|
696
|
+
this.videoPes_ = [];
|
|
697
|
+
return prevVideoPes;
|
|
638
698
|
}
|
|
639
|
-
return
|
|
699
|
+
return this.videoPes_;
|
|
640
700
|
}
|
|
641
701
|
|
|
642
702
|
/**
|
|
643
703
|
* Return the start time for the audio and video
|
|
644
704
|
*
|
|
645
|
-
* @
|
|
705
|
+
* @param {string} contentType
|
|
706
|
+
* @return {?number}
|
|
646
707
|
* @export
|
|
647
708
|
*/
|
|
648
|
-
getStartTime() {
|
|
709
|
+
getStartTime(contentType) {
|
|
649
710
|
const timescale = shaka.util.TsParser.Timescale;
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
}
|
|
711
|
+
if (contentType == 'audio') {
|
|
712
|
+
let audioStartTime = null;
|
|
713
|
+
const audioData = this.getAudioData();
|
|
714
|
+
if (audioData.length) {
|
|
715
|
+
const pes = audioData[0];
|
|
716
|
+
audioStartTime = Math.min(pes.dts, pes.pts) / timescale;
|
|
657
717
|
}
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
}
|
|
718
|
+
return audioStartTime;
|
|
719
|
+
} else if (contentType == 'video') {
|
|
720
|
+
let videoStartTime = null;
|
|
721
|
+
const videoData = this.getVideoData(/* naluProcessing= */ false);
|
|
722
|
+
if (videoData.length) {
|
|
723
|
+
const pes = videoData[0];
|
|
724
|
+
videoStartTime = Math.min(pes.dts, pes.pts) / timescale;
|
|
666
725
|
}
|
|
726
|
+
return videoStartTime;
|
|
667
727
|
}
|
|
668
|
-
return
|
|
669
|
-
audio: audioStartTime,
|
|
670
|
-
video: videoStartTime,
|
|
671
|
-
};
|
|
728
|
+
return null;
|
|
672
729
|
}
|
|
673
730
|
|
|
674
731
|
/**
|
|
@@ -692,14 +749,8 @@ shaka.util.TsParser = class {
|
|
|
692
749
|
*/
|
|
693
750
|
getVideoNalus() {
|
|
694
751
|
const nalus = [];
|
|
695
|
-
const
|
|
696
|
-
|
|
697
|
-
const pes = videoData[i];
|
|
698
|
-
let nextPes;
|
|
699
|
-
if (i + 1 < videoData.length) {
|
|
700
|
-
nextPes = videoData[i + 1];
|
|
701
|
-
}
|
|
702
|
-
nalus.push(...this.parseNalus(pes, nextPes));
|
|
752
|
+
for (const pes of this.getVideoData()) {
|
|
753
|
+
nalus.push(...pes.nalus);
|
|
703
754
|
}
|
|
704
755
|
return nalus;
|
|
705
756
|
}
|
|
@@ -115,7 +115,11 @@ shaka.util.Uint8ArrayUtils = class {
|
|
|
115
115
|
const result = new Uint8Array(totalLength);
|
|
116
116
|
let offset = 0;
|
|
117
117
|
for (const arr of varArgs) {
|
|
118
|
-
|
|
118
|
+
if (arr instanceof Uint8Array) {
|
|
119
|
+
result.set(arr, offset);
|
|
120
|
+
} else {
|
|
121
|
+
result.set(shaka.util.BufferUtils.toUint8(arr), offset);
|
|
122
|
+
}
|
|
119
123
|
offset += arr.byteLength;
|
|
120
124
|
}
|
|
121
125
|
return result;
|