shaka-player 4.5.0 → 4.6.1
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 +109 -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 +34 -30
- 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 +789 -738
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +162 -77
- package/dist/shaka-player.compiled.js +1147 -1113
- 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 +857 -791
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +167 -77
- package/dist/shaka-player.ui.js +1359 -1314
- 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 +251 -84
- 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 +92 -29
- package/lib/hls/hls_classes.js +28 -43
- package/lib/hls/hls_parser.js +770 -652
- 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 +72 -44
- 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 +998 -1503
- 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 +417 -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
|
@@ -6,9 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
goog.provide('shaka.media.ManifestParser');
|
|
8
8
|
|
|
9
|
-
goog.require('
|
|
9
|
+
goog.require('shaka.Deprecate');
|
|
10
10
|
goog.require('shaka.log');
|
|
11
|
-
goog.require('shaka.net.NetworkingEngine');
|
|
12
11
|
goog.require('shaka.util.Error');
|
|
13
12
|
goog.require('shaka.util.Platform');
|
|
14
13
|
|
|
@@ -28,7 +27,9 @@ shaka.media.ManifestParser = class {
|
|
|
28
27
|
* @export
|
|
29
28
|
*/
|
|
30
29
|
static registerParserByExtension(extension, parserFactory) {
|
|
31
|
-
shaka.
|
|
30
|
+
shaka.Deprecate.deprecateFeature(5,
|
|
31
|
+
'ManifestParser',
|
|
32
|
+
'Please use an ManifestParser with registerParserByMime function.');
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
|
|
@@ -70,9 +71,6 @@ shaka.media.ManifestParser = class {
|
|
|
70
71
|
for (const type in ManifestParser.parsersByMime) {
|
|
71
72
|
support[type] = true;
|
|
72
73
|
}
|
|
73
|
-
for (const type in ManifestParser.parsersByExtension) {
|
|
74
|
-
support[type] = true;
|
|
75
|
-
}
|
|
76
74
|
}
|
|
77
75
|
|
|
78
76
|
// Make sure all well-known types are tested as well, just to show an
|
|
@@ -86,14 +84,6 @@ shaka.media.ManifestParser = class {
|
|
|
86
84
|
// SmoothStreaming
|
|
87
85
|
'application/vnd.ms-sstr+xml',
|
|
88
86
|
];
|
|
89
|
-
const testExtensions = {
|
|
90
|
-
// DASH
|
|
91
|
-
'mpd': 'application/dash+xml',
|
|
92
|
-
// HLS
|
|
93
|
-
'm3u8': 'application/x-mpegurl',
|
|
94
|
-
// SmoothStreaming
|
|
95
|
-
'ism': 'application/vnd.ms-sstr+xml',
|
|
96
|
-
};
|
|
97
87
|
|
|
98
88
|
for (const type of testMimeTypes) {
|
|
99
89
|
// Only query our parsers for MSE-enabled platforms. Otherwise, query a
|
|
@@ -105,18 +95,6 @@ shaka.media.ManifestParser = class {
|
|
|
105
95
|
}
|
|
106
96
|
}
|
|
107
97
|
|
|
108
|
-
for (const extension in testExtensions) {
|
|
109
|
-
// Only query our parsers for MSE-enabled platforms. Otherwise, query a
|
|
110
|
-
// temporary media element for native support for these MIME type for the
|
|
111
|
-
// extension.
|
|
112
|
-
if (shaka.util.Platform.supportsMediaSource()) {
|
|
113
|
-
support[extension] = !!ManifestParser.parsersByExtension[extension];
|
|
114
|
-
} else {
|
|
115
|
-
const type = testExtensions[extension];
|
|
116
|
-
support[extension] = shaka.util.Platform.supportsMediaType(type);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
98
|
return support;
|
|
121
99
|
}
|
|
122
100
|
|
|
@@ -126,12 +104,10 @@ shaka.media.ManifestParser = class {
|
|
|
126
104
|
* parse the manifest at |uri|.
|
|
127
105
|
*
|
|
128
106
|
* @param {string} uri
|
|
129
|
-
* @param {!shaka.net.NetworkingEngine} netEngine
|
|
130
|
-
* @param {shaka.extern.RetryParameters} retryParams
|
|
131
107
|
* @param {?string} mimeType
|
|
132
|
-
* @return {
|
|
108
|
+
* @return {shaka.extern.ManifestParser.Factory}
|
|
133
109
|
*/
|
|
134
|
-
static
|
|
110
|
+
static getFactory(uri, mimeType) {
|
|
135
111
|
const ManifestParser = shaka.media.ManifestParser;
|
|
136
112
|
|
|
137
113
|
// Try using the MIME type we were given.
|
|
@@ -145,33 +121,6 @@ shaka.media.ManifestParser = class {
|
|
|
145
121
|
'Could not determine manifest type using MIME type ', mimeType);
|
|
146
122
|
}
|
|
147
123
|
|
|
148
|
-
const extension = ManifestParser.getExtension(uri);
|
|
149
|
-
if (extension) {
|
|
150
|
-
const factory = ManifestParser.parsersByExtension[extension];
|
|
151
|
-
if (factory) {
|
|
152
|
-
return factory;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
shaka.log.warning(
|
|
156
|
-
'Could not determine manifest type for extension ', extension);
|
|
157
|
-
} else {
|
|
158
|
-
shaka.log.warning('Could not find extension for ', uri);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (!mimeType) {
|
|
162
|
-
mimeType = await ManifestParser.getMimeType(uri, netEngine, retryParams);
|
|
163
|
-
|
|
164
|
-
if (mimeType) {
|
|
165
|
-
const factory = shaka.media.ManifestParser.parsersByMime[mimeType];
|
|
166
|
-
if (factory) {
|
|
167
|
-
return factory;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
shaka.log.warning('Could not determine manifest type using MIME type',
|
|
171
|
-
mimeType);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
124
|
throw new shaka.util.Error(
|
|
176
125
|
shaka.util.Error.Severity.CRITICAL,
|
|
177
126
|
shaka.util.Error.Category.MANIFEST,
|
|
@@ -181,56 +130,15 @@ shaka.media.ManifestParser = class {
|
|
|
181
130
|
|
|
182
131
|
|
|
183
132
|
/**
|
|
184
|
-
*
|
|
185
|
-
* @param {!shaka.net.NetworkingEngine} netEngine
|
|
186
|
-
* @param {shaka.extern.RetryParameters} retryParams
|
|
187
|
-
* @return {!Promise.<string>}
|
|
188
|
-
*/
|
|
189
|
-
static async getMimeType(uri, netEngine, retryParams) {
|
|
190
|
-
const type = shaka.net.NetworkingEngine.RequestType.MANIFEST;
|
|
191
|
-
|
|
192
|
-
const request = shaka.net.NetworkingEngine.makeRequest([uri], retryParams);
|
|
193
|
-
request.method = 'HEAD';
|
|
194
|
-
|
|
195
|
-
const response = await netEngine.request(type, request).promise;
|
|
196
|
-
|
|
197
|
-
// https://bit.ly/2K9s9kf says this header should always be available,
|
|
198
|
-
// but just to be safe:
|
|
199
|
-
const mimeType = response.headers['content-type'];
|
|
200
|
-
return mimeType ? mimeType.toLowerCase().split(';').shift() : '';
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* @param {string} uri
|
|
206
|
-
* @return {string}
|
|
207
|
-
*/
|
|
208
|
-
static getExtension(uri) {
|
|
209
|
-
const uriObj = new goog.Uri(uri);
|
|
210
|
-
const uriPieces = uriObj.getPath().split('/');
|
|
211
|
-
const uriFilename = uriPieces.pop();
|
|
212
|
-
const filenamePieces = uriFilename.split('.');
|
|
213
|
-
|
|
214
|
-
// Only one piece means there is no extension.
|
|
215
|
-
if (filenamePieces.length == 1) {
|
|
216
|
-
return '';
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return filenamePieces.pop().toLowerCase();
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Determines whether or not this URI and MIME type are supported by our own
|
|
133
|
+
* Determines whether or not the MIME type is supported by our own
|
|
225
134
|
* manifest parsers on this platform. This takes into account whether or not
|
|
226
135
|
* MediaSource is available, as well as which parsers are registered to the
|
|
227
136
|
* system.
|
|
228
137
|
*
|
|
229
|
-
* @param {string} uri
|
|
230
138
|
* @param {string} mimeType
|
|
231
139
|
* @return {boolean}
|
|
232
140
|
*/
|
|
233
|
-
static isSupported(
|
|
141
|
+
static isSupported(mimeType) {
|
|
234
142
|
// Without MediaSource, our own parsers are useless.
|
|
235
143
|
if (!shaka.util.Platform.supportsMediaSource()) {
|
|
236
144
|
return false;
|
|
@@ -240,11 +148,6 @@ shaka.media.ManifestParser = class {
|
|
|
240
148
|
return true;
|
|
241
149
|
}
|
|
242
150
|
|
|
243
|
-
const extension = shaka.media.ManifestParser.getExtension(uri);
|
|
244
|
-
if (extension in shaka.media.ManifestParser.parsersByExtension) {
|
|
245
|
-
return true;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
151
|
return false;
|
|
249
152
|
}
|
|
250
153
|
};
|
|
@@ -292,11 +195,3 @@ shaka.media.ManifestParser.AccessibilityPurpose = {
|
|
|
292
195
|
shaka.media.ManifestParser.parsersByMime = {};
|
|
293
196
|
|
|
294
197
|
|
|
295
|
-
/**
|
|
296
|
-
* Contains the parser factory functions indexed by file extension.
|
|
297
|
-
*
|
|
298
|
-
* @type {!Object.<string, shaka.extern.ManifestParser.Factory>}
|
|
299
|
-
*/
|
|
300
|
-
shaka.media.ManifestParser.parsersByExtension = {};
|
|
301
|
-
|
|
302
|
-
|
|
@@ -23,9 +23,16 @@ shaka.media.Capabilities = class {
|
|
|
23
23
|
if (supportMap.has(type)) {
|
|
24
24
|
return supportMap.get(type);
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
if (window.ManagedMediaSource) {
|
|
27
|
+
const currentSupport = ManagedMediaSource.isTypeSupported(type);
|
|
28
|
+
supportMap.set(type, currentSupport);
|
|
29
|
+
return currentSupport;
|
|
30
|
+
} else if (window.MediaSource) {
|
|
31
|
+
const currentSupport = MediaSource.isTypeSupported(type);
|
|
32
|
+
supportMap.set(type, currentSupport);
|
|
33
|
+
return currentSupport;
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
29
36
|
}
|
|
30
37
|
|
|
31
38
|
/**
|
|
@@ -119,7 +119,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
119
119
|
/** @private {boolean} */
|
|
120
120
|
this.playbackHasBegun_ = false;
|
|
121
121
|
|
|
122
|
-
/** @private {MediaSource} */
|
|
122
|
+
/** @private {(MediaSource|ManagedMediaSource)} */
|
|
123
123
|
this.mediaSource_ = this.createMediaSource(this.mediaSourceOpen_);
|
|
124
124
|
|
|
125
125
|
/** @private {boolean} */
|
|
@@ -145,6 +145,9 @@ shaka.media.MediaSourceEngine = class {
|
|
|
145
145
|
|
|
146
146
|
/** @private {boolean} */
|
|
147
147
|
this.needSplitMuxedContent_ = false;
|
|
148
|
+
|
|
149
|
+
/** @private {boolean} */
|
|
150
|
+
this.streamingAllowed_ = true;
|
|
148
151
|
}
|
|
149
152
|
|
|
150
153
|
/**
|
|
@@ -154,30 +157,60 @@ shaka.media.MediaSourceEngine = class {
|
|
|
154
157
|
* Replaced by unit tests.
|
|
155
158
|
*
|
|
156
159
|
* @param {!shaka.util.PublicPromise} p
|
|
157
|
-
* @return {!MediaSource}
|
|
160
|
+
* @return {!(MediaSource|ManagedMediaSource)}
|
|
158
161
|
*/
|
|
159
162
|
createMediaSource(p) {
|
|
160
|
-
|
|
163
|
+
if (window.ManagedMediaSource) {
|
|
164
|
+
this.video_.disableRemotePlayback = true;
|
|
161
165
|
|
|
162
|
-
|
|
163
|
-
this.eventManager_.listenOnce(
|
|
164
|
-
mediaSource, 'sourceopen', () => this.onSourceOpen_(p));
|
|
166
|
+
const mediaSource = new ManagedMediaSource();
|
|
165
167
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
168
|
+
this.eventManager_.listenOnce(
|
|
169
|
+
mediaSource, 'sourceopen', () => this.onSourceOpen_(p));
|
|
170
|
+
|
|
171
|
+
this.eventManager_.listen(
|
|
172
|
+
mediaSource, 'startstreaming', () => {
|
|
173
|
+
this.streamingAllowed_ = true;
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
this.eventManager_.listen(
|
|
177
|
+
mediaSource, 'endstreaming', () => {
|
|
178
|
+
this.streamingAllowed_ = false;
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Correctly set when playback has begun.
|
|
182
|
+
this.eventManager_.listenOnce(this.video_, 'playing', () => {
|
|
183
|
+
this.playbackHasBegun_ = true;
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
this.url_ = shaka.media.MediaSourceEngine.createObjectURL(mediaSource);
|
|
187
|
+
|
|
188
|
+
this.video_.src = this.url_;
|
|
189
|
+
|
|
190
|
+
return mediaSource;
|
|
191
|
+
} else {
|
|
192
|
+
const mediaSource = new MediaSource();
|
|
193
|
+
|
|
194
|
+
// Set up MediaSource on the video element.
|
|
195
|
+
this.eventManager_.listenOnce(
|
|
196
|
+
mediaSource, 'sourceopen', () => this.onSourceOpen_(p));
|
|
170
197
|
|
|
171
|
-
|
|
172
|
-
|
|
198
|
+
// Correctly set when playback has begun.
|
|
199
|
+
this.eventManager_.listenOnce(this.video_, 'playing', () => {
|
|
200
|
+
this.playbackHasBegun_ = true;
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Store the object URL for releasing it later.
|
|
204
|
+
this.url_ = shaka.media.MediaSourceEngine.createObjectURL(mediaSource);
|
|
173
205
|
|
|
174
|
-
|
|
206
|
+
this.video_.src = this.url_;
|
|
175
207
|
|
|
176
|
-
|
|
208
|
+
return mediaSource;
|
|
209
|
+
}
|
|
177
210
|
}
|
|
178
211
|
|
|
179
212
|
/**
|
|
180
|
-
* @param {
|
|
213
|
+
* @param {shaka.util.PublicPromise} p
|
|
181
214
|
* @private
|
|
182
215
|
*/
|
|
183
216
|
onSourceOpen_(p) {
|
|
@@ -229,9 +262,11 @@ shaka.media.MediaSourceEngine = class {
|
|
|
229
262
|
'video/mp4; codecs="vp9"',
|
|
230
263
|
'video/mp4; codecs="vp09.00.10.08"',
|
|
231
264
|
'video/mp4; codecs="av01.0.01M.08"',
|
|
265
|
+
'video/mp4; codecs="dvh1.20.01"',
|
|
232
266
|
'audio/mp4; codecs="mp4a.40.2"',
|
|
233
267
|
'audio/mp4; codecs="ac-3"',
|
|
234
268
|
'audio/mp4; codecs="ec-3"',
|
|
269
|
+
'audio/mp4; codecs="ac-4"',
|
|
235
270
|
'audio/mp4; codecs="opus"',
|
|
236
271
|
'audio/mp4; codecs="flac"',
|
|
237
272
|
'audio/mp4; codecs="dtsc"', // DTS Digital Surround
|
|
@@ -480,8 +515,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
480
515
|
shaka.util.Error.Category.MEDIA,
|
|
481
516
|
shaka.util.Error.Code.MEDIA_SOURCE_OPERATION_THREW,
|
|
482
517
|
exception,
|
|
483
|
-
'The mediaSource_ status was' + this.mediaSource_.readyState +
|
|
484
|
-
'expected \'open\'');
|
|
518
|
+
'The mediaSource_ status was ' + this.mediaSource_.readyState +
|
|
519
|
+
' expected \'open\'');
|
|
485
520
|
}
|
|
486
521
|
|
|
487
522
|
if (this.sequenceMode_) {
|
|
@@ -511,6 +546,16 @@ shaka.media.MediaSourceEngine = class {
|
|
|
511
546
|
this.config_ = config;
|
|
512
547
|
}
|
|
513
548
|
|
|
549
|
+
/**
|
|
550
|
+
* Indicate if the streaming is allowed by MediaSourceEngine.
|
|
551
|
+
* If we using MediaSource we allways returns true.
|
|
552
|
+
*
|
|
553
|
+
* @return {boolean}
|
|
554
|
+
*/
|
|
555
|
+
isStreamingAllowed() {
|
|
556
|
+
return this.streamingAllowed_;
|
|
557
|
+
}
|
|
558
|
+
|
|
514
559
|
/**
|
|
515
560
|
* Reinitialize the TextEngine for a new text type.
|
|
516
561
|
* @param {string} mimeType
|
|
@@ -739,7 +784,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
739
784
|
} else if (!mimeType.includes('/mp4') && !mimeType.includes('/webm') &&
|
|
740
785
|
shaka.util.TsParser.probe(uint8ArrayData)) {
|
|
741
786
|
const tsParser = new shaka.util.TsParser().parse(uint8ArrayData);
|
|
742
|
-
const startTime = tsParser.getStartTime()
|
|
787
|
+
const startTime = tsParser.getStartTime(contentType);
|
|
743
788
|
if (startTime != null) {
|
|
744
789
|
timestamp = startTime;
|
|
745
790
|
}
|
|
@@ -786,7 +831,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
786
831
|
await this.textEngine_.appendBuffer(
|
|
787
832
|
data,
|
|
788
833
|
reference ? reference.startTime : null,
|
|
789
|
-
reference ? reference.endTime : null
|
|
834
|
+
reference ? reference.endTime : null,
|
|
835
|
+
reference ? reference.getUris()[0] : null);
|
|
790
836
|
return;
|
|
791
837
|
}
|
|
792
838
|
|
|
@@ -809,7 +855,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
809
855
|
|
|
810
856
|
let mimeType = this.sourceBufferTypes_[contentType];
|
|
811
857
|
if (this.transmuxers_[contentType]) {
|
|
812
|
-
mimeType = this.transmuxers_[contentType].
|
|
858
|
+
mimeType = this.transmuxers_[contentType].getOriginalMimeType();
|
|
813
859
|
}
|
|
814
860
|
if (reference) {
|
|
815
861
|
const timestamp = this.getTimestampAndDispatchMetadata_(
|
|
@@ -818,7 +864,9 @@ shaka.media.MediaSourceEngine = class {
|
|
|
818
864
|
const calculatedTimestampOffset = reference.startTime - timestamp;
|
|
819
865
|
const timestampOffsetDifference =
|
|
820
866
|
Math.abs(timestampOffset - calculatedTimestampOffset);
|
|
821
|
-
if (timestampOffsetDifference >= 0.1 || seeked || adaptation)
|
|
867
|
+
if ((timestampOffsetDifference >= 0.1 || seeked || adaptation) &&
|
|
868
|
+
(!isChunkedData || calculatedTimestampOffset > 0 ||
|
|
869
|
+
!timestampOffset)) {
|
|
822
870
|
timestampOffset = calculatedTimestampOffset;
|
|
823
871
|
if (this.attemptTimestampOffsetCalculation_) {
|
|
824
872
|
this.enqueueOperation_(
|
|
@@ -1778,6 +1826,9 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1778
1826
|
* @private
|
|
1779
1827
|
*/
|
|
1780
1828
|
async codecSwitchIfNecessary_(contentType, stream, streamsByType) {
|
|
1829
|
+
if (contentType == shaka.util.ManifestParserUtils.ContentType.TEXT) {
|
|
1830
|
+
return false;
|
|
1831
|
+
}
|
|
1781
1832
|
const MimeUtils = shaka.util.MimeUtils;
|
|
1782
1833
|
const currentCodec = MimeUtils.getCodecBase(
|
|
1783
1834
|
MimeUtils.getCodecs(this.sourceBufferTypes_[contentType]));
|
|
@@ -1840,6 +1891,9 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1840
1891
|
* @private
|
|
1841
1892
|
*/
|
|
1842
1893
|
isCodecSwitchNecessary_(contentType, stream) {
|
|
1894
|
+
if (contentType == shaka.util.ManifestParserUtils.ContentType.TEXT) {
|
|
1895
|
+
return false;
|
|
1896
|
+
}
|
|
1843
1897
|
const MimeUtils = shaka.util.MimeUtils;
|
|
1844
1898
|
const currentCodec = MimeUtils.getCodecBase(
|
|
1845
1899
|
MimeUtils.getCodecs(this.sourceBufferTypes_[contentType]));
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
goog.provide('shaka.media.PlayRateController');
|
|
8
8
|
|
|
9
|
-
goog.require('goog.asserts');
|
|
10
9
|
goog.require('shaka.log');
|
|
11
10
|
goog.require('shaka.util.IReleasable');
|
|
12
11
|
goog.require('shaka.util.Timer');
|
|
@@ -17,8 +16,6 @@ goog.require('shaka.util.Timer');
|
|
|
17
16
|
* the playback rate on the media element can change outside of the controller,
|
|
18
17
|
* the playback controller will need to be updated to stay in-sync.
|
|
19
18
|
*
|
|
20
|
-
* TODO: Try not to manage buffering above the browser with playbackRate=0.
|
|
21
|
-
*
|
|
22
19
|
* @implements {shaka.util.IReleasable}
|
|
23
20
|
* @final
|
|
24
21
|
*/
|
|
@@ -30,9 +27,6 @@ shaka.media.PlayRateController = class {
|
|
|
30
27
|
/** @private {?shaka.media.PlayRateController.Harness} */
|
|
31
28
|
this.harness_ = harness;
|
|
32
29
|
|
|
33
|
-
/** @private {boolean} */
|
|
34
|
-
this.isBuffering_ = false;
|
|
35
|
-
|
|
36
30
|
/** @private {number} */
|
|
37
31
|
this.rate_ = this.harness_.getRate();
|
|
38
32
|
|
|
@@ -56,25 +50,15 @@ shaka.media.PlayRateController = class {
|
|
|
56
50
|
}
|
|
57
51
|
|
|
58
52
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* @param {boolean} isBuffering If true, forces playback rate to 0 internally.
|
|
62
|
-
*/
|
|
63
|
-
setBuffering(isBuffering) {
|
|
64
|
-
this.isBuffering_ = isBuffering;
|
|
65
|
-
this.apply_();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Set the playback rate. This rate will only be used as provided when the
|
|
70
|
-
* player is not buffering. You should never set the rate to 0.
|
|
53
|
+
* Set the playback rate.
|
|
71
54
|
*
|
|
72
55
|
* @param {number} rate
|
|
73
56
|
*/
|
|
74
57
|
set(rate) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
58
|
+
if (this.rate_ != rate) {
|
|
59
|
+
this.rate_ = rate;
|
|
60
|
+
this.apply_();
|
|
61
|
+
}
|
|
78
62
|
}
|
|
79
63
|
|
|
80
64
|
/**
|
|
@@ -108,14 +92,11 @@ shaka.media.PlayRateController = class {
|
|
|
108
92
|
// Always stop the timer. We may not start it again.
|
|
109
93
|
this.timer_.stop();
|
|
110
94
|
|
|
111
|
-
|
|
112
|
-
const rate = this.calculateCurrentRate_();
|
|
95
|
+
shaka.log.v1('Changing effective playback rate to', this.rate_);
|
|
113
96
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (rate >= 0) {
|
|
97
|
+
if (this.rate_ >= 0) {
|
|
117
98
|
try {
|
|
118
|
-
this.applyRate_(
|
|
99
|
+
this.applyRate_(this.rate_);
|
|
119
100
|
return;
|
|
120
101
|
} catch (e) {
|
|
121
102
|
// Fall through to the next clause.
|
|
@@ -135,17 +116,6 @@ shaka.media.PlayRateController = class {
|
|
|
135
116
|
this.applyRate_(0);
|
|
136
117
|
}
|
|
137
118
|
|
|
138
|
-
/**
|
|
139
|
-
* Calculate the rate that the controller wants the media element to have
|
|
140
|
-
* based on the current state of the controller.
|
|
141
|
-
*
|
|
142
|
-
* @return {number}
|
|
143
|
-
* @private
|
|
144
|
-
*/
|
|
145
|
-
calculateCurrentRate_() {
|
|
146
|
-
return this.isBuffering_ ? 0 : this.rate_;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
119
|
/**
|
|
150
120
|
* If the new rate is different than the media element's playback rate, this
|
|
151
121
|
* will change the playback rate. If the rate does not need to change, it will
|
|
@@ -619,7 +619,9 @@ shaka.media.PresentationTimeline = class {
|
|
|
619
619
|
* @typedef {{
|
|
620
620
|
* start: number,
|
|
621
621
|
* unscaledStart: number,
|
|
622
|
-
* end: number
|
|
622
|
+
* end: number,
|
|
623
|
+
* partialSegments: number,
|
|
624
|
+
* segmentPosition: number
|
|
623
625
|
* }}
|
|
624
626
|
*
|
|
625
627
|
* @description
|
|
@@ -631,6 +633,10 @@ shaka.media.PresentationTimeline = class {
|
|
|
631
633
|
* The start time of the range in representation timescale units.
|
|
632
634
|
* @property {number} end
|
|
633
635
|
* The end time (exclusive) of the range.
|
|
636
|
+
* @property {number} partialSegments
|
|
637
|
+
* The number of partial segments
|
|
638
|
+
* @property {number} segmentPosition
|
|
639
|
+
* The segment position of the timeline entry as it appears in the manifest
|
|
634
640
|
*
|
|
635
641
|
* @export
|
|
636
642
|
*/
|
|
@@ -261,7 +261,7 @@ shaka.media.QualityObserver.QualityChangePosition;
|
|
|
261
261
|
*
|
|
262
262
|
* @description
|
|
263
263
|
* Contains media quality information for a specific content type
|
|
264
|
-
* e.g video or audio.
|
|
264
|
+
* e.g. video or audio.
|
|
265
265
|
*
|
|
266
266
|
* @property {!Array.<shaka.media.QualityObserver.QualityChangePosition>}
|
|
267
267
|
* qualityChangePositions
|
|
@@ -582,7 +582,7 @@ shaka.media.SegmentIterator = class {
|
|
|
582
582
|
// new references in merge(), the pointers may not make sense any more.
|
|
583
583
|
// This adjusts the invalid pointer values to point to the next newly added
|
|
584
584
|
// segment or partial segment.
|
|
585
|
-
if (ref && ref.hasPartialSegments() && ref.
|
|
585
|
+
if (ref && ref.hasPartialSegments() && ref.hasAllPartialSegments() &&
|
|
586
586
|
this.currentPartialPosition_ >= ref.partialReferences.length) {
|
|
587
587
|
this.currentPosition_++;
|
|
588
588
|
this.currentPartialPosition_ = 0;
|
|
@@ -609,12 +609,12 @@ shaka.media.SegmentIterator = class {
|
|
|
609
609
|
// If the regular segment contains partial segments, move to the next
|
|
610
610
|
// partial SegmentReference.
|
|
611
611
|
this.currentPartialPosition_++;
|
|
612
|
-
// If the current regular segment has been published completely
|
|
613
|
-
//
|
|
614
|
-
//
|
|
612
|
+
// If the current regular segment has been published completely, and
|
|
613
|
+
// we've reached the end of its partial segments list, move to the next
|
|
614
|
+
// regular segment.
|
|
615
615
|
// If the Partial Segments list is still on the fly, do not move to
|
|
616
616
|
// the next regular segment.
|
|
617
|
-
if (ref.
|
|
617
|
+
if (ref.hasAllPartialSegments() &&
|
|
618
618
|
this.currentPartialPosition_ == ref.partialReferences.length) {
|
|
619
619
|
this.currentPosition_++;
|
|
620
620
|
this.currentPartialPosition_ = 0;
|