shaka-player 4.1.1 → 4.1.4
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/workflows/build-and-test.yaml +67 -15
- package/.github/workflows/compute-incremental-coverage.py +251 -0
- package/.github/workflows/report-incremental-coverage.yaml +39 -0
- package/.github/workflows/selenium-lab-tests.yaml +179 -31
- package/AUTHORS +1 -0
- package/CHANGELOG.md +40 -0
- package/CONTRIBUTORS +3 -0
- package/README.md +20 -6
- package/demo/index.html +1 -3
- package/dist/controls.css +2 -2
- package/dist/controls.css.map +1 -1
- package/dist/deps.js +3 -3
- package/dist/locales.js +33 -33
- package/dist/shaka-player.compiled.d.ts +12 -1
- package/dist/shaka-player.compiled.debug.d.ts +12 -1
- package/dist/shaka-player.compiled.debug.externs.js +49 -38
- package/dist/shaka-player.compiled.debug.js +173 -165
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +49 -38
- package/dist/shaka-player.compiled.js +789 -785
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +12 -1
- package/dist/shaka-player.ui.debug.d.ts +12 -1
- package/dist/shaka-player.ui.debug.externs.js +49 -38
- package/dist/shaka-player.ui.debug.js +187 -179
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +49 -38
- package/dist/shaka-player.ui.js +916 -912
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/ui.md +6 -6
- package/docs/tutorials/upgrade.md +1 -0
- package/docs/tutorials/welcome.md +6 -3
- package/karma.conf.js +3 -11
- package/lib/ads/client_side_ad_manager.js +1 -1
- package/lib/dash/dash_parser.js +5 -0
- package/lib/hls/hls_parser.js +6 -2
- package/lib/media/drm_engine.js +1 -1
- package/lib/media/media_source_engine.js +57 -24
- package/lib/media/presentation_timeline.js +24 -1
- package/lib/media/streaming_engine.js +4 -4
- package/lib/media/time_ranges_utils.js +46 -0
- package/lib/player.js +13 -6
- package/lib/polyfill/media_capabilities.js +9 -0
- package/lib/polyfill/videoplaybackquality.js +3 -1
- package/lib/text/cue.js +0 -5
- package/lib/text/simple_text_displayer.js +21 -9
- package/lib/text/ui_text_displayer.js +91 -19
- package/lib/util/buffer_utils.js +3 -0
- package/lib/util/object_utils.js +1 -0
- package/lib/util/platform.js +19 -1
- package/lib/util/player_configuration.js +1 -0
- package/lib/util/stream_utils.js +23 -3
- package/lib/util/string_utils.js +102 -13
- package/maintained-branches.md +15 -0
- package/package.json +3 -5
- package/test/media/drm_engine_integration.js +24 -8
- package/test/media/drm_engine_unit.js +29 -0
- package/test/media/media_source_engine_integration.js +24 -10
- package/test/media/media_source_engine_unit.js +53 -38
- package/test/media/streaming_engine_unit.js +28 -27
- package/test/player_src_equals_integration.js +2 -0
- package/test/player_unit.js +39 -1
- package/test/test/assets/small.mp4 +0 -0
- package/test/test/util/fake_media_source_engine.js +10 -9
- package/test/text/simple_text_displayer_unit.js +27 -0
- package/test/text/ui_text_displayer_unit.js +65 -0
- package/test/util/string_utils_unit.js +46 -8
- package/ui/less/ad_controls.less +4 -0
- package/ui/text_selection.js +2 -2
- package/app-engine/README.md +0 -9
- package/app-engine/demo-version-index/README.md +0 -14
- package/app-engine/demo-version-index/app.yaml +0 -28
- package/app-engine/demo-version-index/generate.py +0 -164
- package/app-engine/demo-version-index/main.py +0 -11
- package/app-engine/demo-version-index/requirements.txt +0 -5
- package/app-engine/demo-version-index/templates/index.html +0 -114
- package/app-engine/shaka-player-demo/README.md +0 -18
- package/app-engine/shaka-player-demo/app.yaml +0 -61
- package/app-engine/shaka-player-demo/main.py +0 -95
- package/app-engine/shaka-player-demo/posters/10yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/10yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/1yo.jpg +0 -0
- package/app-engine/shaka-player-demo/posters/2yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/2yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/3yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/3yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/4yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/4yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/5yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/5yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/6yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/6yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/7yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/7yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/8yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/8yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/9yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/9yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/audioOnly.gif +0 -0
- package/app-engine/shaka-player-demo/posters/audioRickRoll.gif +0 -0
- package/app-engine/shaka-player-demo/posters/colorbars.gif +0 -0
- package/app-engine/shaka-player-demo/posters/fireworks.jpg +0 -0
- package/app-engine/shaka-player-demo/posters/party-hat.png +0 -0
- package/app-engine/shaka-player-demo/posters/sources.txt +0 -46
- package/app-engine/shaka-player-demo/posters/standard.png +0 -0
- package/app-engine/shaka-player-demo/posters/trek.jpg +0 -0
- package/app-engine/shaka-player-demo/posters/valentines.png +0 -0
- package/app-engine/shaka-player-demo/posters/zombie.jpg +0 -0
- package/app-engine/shaka-player-demo/posters.py +0 -110
- package/app-engine/shaka-player-demo/requirements.txt +0 -5
- package/app-engine/shaka-player-demo/time.txt +0 -1
- package/build/README.md +0 -127
- package/build/__init__.py +0 -0
- package/build/all.py +0 -150
- package/build/apps.py +0 -186
- package/build/build.py +0 -392
- package/build/check.py +0 -354
- package/build/checkversion.py +0 -84
- package/build/compiler.py +0 -513
- package/build/conformance.textproto +0 -335
- package/build/docker/Dockerfile +0 -20
- package/build/docker/docker-compose.yml +0 -10
- package/build/docs.py +0 -54
- package/build/eslint-plugin-shaka-rules/arg-comment-spacing.js +0 -72
- package/build/eslint-plugin-shaka-rules/index.js +0 -24
- package/build/eslint-plugin-shaka-rules/package.json +0 -7
- package/build/eslint-plugin-shaka-rules/private.js +0 -109
- package/build/gendeps.py +0 -71
- package/build/generateExterns.js +0 -867
- package/build/generateLocalizations.py +0 -262
- package/build/generateTsDefs.py +0 -137
- package/build/install-linux-prereqs.sh +0 -136
- package/build/license-header +0 -5
- package/build/misspellings.txt +0 -39
- package/build/pixelsChanged.js +0 -35
- package/build/shaka-lab.yaml +0 -161
- package/build/shakaBuildHelpers.py +0 -356
- package/build/stats.py +0 -816
- package/build/subprocessWindowsPatch.py +0 -103
- package/build/test.py +0 -541
- package/build/types/ads +0 -8
- package/build/types/cast +0 -6
- package/build/types/cea +0 -13
- package/build/types/complete +0 -9
- package/build/types/core +0 -108
- package/build/types/dash +0 -8
- package/build/types/hls +0 -9
- package/build/types/manifests +0 -5
- package/build/types/networking +0 -6
- package/build/types/offline +0 -22
- package/build/types/polyfill +0 -18
- package/build/types/text +0 -11
- package/build/types/ui +0 -39
- package/build/updateScreenshots.py +0 -85
- package/build/wrapper.template.js +0 -52
package/docs/tutorials/ui.md
CHANGED
|
@@ -30,7 +30,7 @@ Set up controls with HTML data attributes:
|
|
|
30
30
|
The data-shaka-player-cast-receiver-id tag allows you to provide a Cast Application ID that
|
|
31
31
|
the cast button will cast to; the value provided here is the sample cast receiver. -->
|
|
32
32
|
<div data-shaka-player-container style="max-width:40em"
|
|
33
|
-
data-shaka-player-cast-receiver-id="
|
|
33
|
+
data-shaka-player-cast-receiver-id="06EDA6EE">
|
|
34
34
|
<!-- The data-shaka-player tag will make the UI library use this video element.
|
|
35
35
|
If no video is provided, the UI will automatically make one inside the container div. -->
|
|
36
36
|
<video autoplay data-shaka-player id="video" style="width:100%;height:100%"></video>
|
|
@@ -111,7 +111,7 @@ set up a listener for the 'caststatuschanged' events.
|
|
|
111
111
|
<!-- Add a data-shaka-player-cast-receiver-id tag to provide a Cast Application ID that
|
|
112
112
|
the cast button will cast to; the value provided here is the sample cast receiver. -->
|
|
113
113
|
<div data-shaka-player-container style="max-width:40em"
|
|
114
|
-
data-shaka-player-cast-receiver-id="
|
|
114
|
+
data-shaka-player-cast-receiver-id="06EDA6EE">
|
|
115
115
|
</div>
|
|
116
116
|
```
|
|
117
117
|
|
|
@@ -154,7 +154,7 @@ or a `<source>` tag inside it to enable auto loading of the specified content.
|
|
|
154
154
|
|
|
155
155
|
```html
|
|
156
156
|
<div data-shaka-player-container style="max-width:40em"
|
|
157
|
-
data-shaka-player-cast-receiver-id="
|
|
157
|
+
data-shaka-player-cast-receiver-id="06EDA6EE">
|
|
158
158
|
<!-- The manifest url in the src attribute will be automatically loaded -->
|
|
159
159
|
<video autoplay data-shaka-player id="video" style="width:100%;height:100%"
|
|
160
160
|
src="https://storage.googleapis.com/shaka-demo-assets/angel-one/dash.mpd"></video>
|
|
@@ -165,7 +165,7 @@ or
|
|
|
165
165
|
|
|
166
166
|
```html
|
|
167
167
|
<div data-shaka-player-container style="max-width:40em"
|
|
168
|
-
data-shaka-player-cast-receiver-id="
|
|
168
|
+
data-shaka-player-cast-receiver-id="06EDA6EE">
|
|
169
169
|
<video autoplay data-shaka-player id="video" style="width:100%;height:100%">
|
|
170
170
|
<!-- The manifest url in the src attribute will be auto loaded -->
|
|
171
171
|
<source src="https://storage.googleapis.com/shaka-demo-assets/angel-one/dash.mpd"/>
|
|
@@ -178,7 +178,7 @@ call to the first one fails.
|
|
|
178
178
|
|
|
179
179
|
```html
|
|
180
180
|
<div data-shaka-player-container style="max-width:40em"
|
|
181
|
-
data-shaka-player-cast-receiver-id="
|
|
181
|
+
data-shaka-player-cast-receiver-id="06EDA6EE">
|
|
182
182
|
<video autoplay data-shaka-player id="video" style="width:100%;height:100%">
|
|
183
183
|
<!-- Try this first -->
|
|
184
184
|
<source src="https://storage.googleapis.com/shaka-demo-assets/angel-one/dash.mpd"/>
|
|
@@ -222,7 +222,7 @@ const video = controls.getVideo();
|
|
|
222
222
|
// Receiver Compatability.
|
|
223
223
|
ui.configure({
|
|
224
224
|
// Set the castReceiverAppId
|
|
225
|
-
'castReceiverAppId': '
|
|
225
|
+
'castReceiverAppId': '06EDA6EE',
|
|
226
226
|
// Enable casting to native Android Apps (e.g. Android TV Apps)
|
|
227
227
|
'castAndroidReceiverCompatible': true,
|
|
228
228
|
});
|
|
@@ -25,6 +25,7 @@ application:
|
|
|
25
25
|
- TextDecoder/TextEncoder platform support or polyfill required (affects
|
|
26
26
|
Xbox One, but not evergreen browsers); we suggest the polyfill
|
|
27
27
|
[https://github.com/anonyco/FastestSmallestTextEncoderDecoder](fastestsmallesttextencoderdecoder/EncoderDecoderTogether.min.js)
|
|
28
|
+
Fallback included by default in v4.2
|
|
28
29
|
|
|
29
30
|
- Support removed:
|
|
30
31
|
- IE11 support removed
|
|
@@ -98,11 +98,14 @@ You can find a full list of available browsers with `--browsers help`, and you
|
|
|
98
98
|
can find a complete list of testing options with `--help`.
|
|
99
99
|
|
|
100
100
|
|
|
101
|
-
####
|
|
101
|
+
#### Announcements
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
To subscribe to new releases on GitHub, you can follow
|
|
104
|
+
[instructions from this blog](https://www.jessesquires.com/blog/2020/07/30/github-tip-watching-releases/).
|
|
105
|
+
|
|
106
|
+
To receive infrequent announcements and surveys from us, you can join our
|
|
104
107
|
[mailing list](https://groups.google.com/forum/#!forum/shaka-player-users).
|
|
105
|
-
The list is very low volume.
|
|
108
|
+
The list is very low volume, and can only be written to by us.
|
|
106
109
|
|
|
107
110
|
|
|
108
111
|
#### Continue the Tutorials
|
package/karma.conf.js
CHANGED
|
@@ -160,10 +160,6 @@ module.exports = (config) => {
|
|
|
160
160
|
'node_modules/es6-promise-polyfill/promise.js',
|
|
161
161
|
// Babel polyfill, required for async/await
|
|
162
162
|
'node_modules/@babel/polyfill/dist/polyfill.js',
|
|
163
|
-
// TextDecoder polyfill, required for TextDecoder/TextEncoder on IE and
|
|
164
|
-
// legacy Edge
|
|
165
|
-
// eslint-disable-next-line max-len
|
|
166
|
-
'node_modules/fastestsmallesttextencoderdecoder/EncoderDecoderTogether.min.js',
|
|
167
163
|
|
|
168
164
|
// muxjs module next
|
|
169
165
|
'node_modules/mux.js/dist/mux.min.js',
|
|
@@ -306,13 +302,6 @@ module.exports = (config) => {
|
|
|
306
302
|
// Force failure when running empty test-suites.
|
|
307
303
|
failOnEmptyTestSuite: true,
|
|
308
304
|
|
|
309
|
-
coverageReporter: {
|
|
310
|
-
includeAllSources: true,
|
|
311
|
-
reporters: [
|
|
312
|
-
{type: 'text'},
|
|
313
|
-
],
|
|
314
|
-
},
|
|
315
|
-
|
|
316
305
|
specReporter: {
|
|
317
306
|
suppressSkipped: true,
|
|
318
307
|
showBrowser: true,
|
|
@@ -405,9 +394,12 @@ module.exports = (config) => {
|
|
|
405
394
|
|
|
406
395
|
config.set({
|
|
407
396
|
coverageReporter: {
|
|
397
|
+
includeAllSources: true,
|
|
408
398
|
reporters: [
|
|
409
399
|
{type: 'html', dir: 'coverage'},
|
|
410
400
|
{type: 'cobertura', dir: 'coverage', file: 'coverage.xml'},
|
|
401
|
+
{type: 'json-summary', dir: 'coverage', file: 'coverage.json'},
|
|
402
|
+
{type: 'json', dir: 'coverage', file: 'coverage-details.json'},
|
|
411
403
|
],
|
|
412
404
|
},
|
|
413
405
|
});
|
|
@@ -427,7 +427,7 @@ shaka.ads.ClientSideAdManager = class {
|
|
|
427
427
|
onAdComplete_(e) {
|
|
428
428
|
this.onEvent_(new shaka.util.FakeEvent(shaka.ads.AdManager.AD_STOPPED,
|
|
429
429
|
(new Map()).set('originalEvent', e)));
|
|
430
|
-
if (this.ad_.isLinear()) {
|
|
430
|
+
if (this.ad_ && this.ad_.isLinear()) {
|
|
431
431
|
this.adContainer_.removeAttribute('ad-active');
|
|
432
432
|
this.video_.play();
|
|
433
433
|
}
|
package/lib/dash/dash_parser.js
CHANGED
|
@@ -513,6 +513,11 @@ shaka.dash.DashParser = class {
|
|
|
513
513
|
}
|
|
514
514
|
presentationTimeline.setClockOffset(offset);
|
|
515
515
|
}
|
|
516
|
+
|
|
517
|
+
// This is the first point where we have a meaningful presentation start
|
|
518
|
+
// time, and we need to tell PresentationTimeline that so that it can
|
|
519
|
+
// maintain consistency from here on.
|
|
520
|
+
presentationTimeline.lockStartTime();
|
|
516
521
|
} else {
|
|
517
522
|
// Just update the variants and text streams, which may change as periods
|
|
518
523
|
// are added or removed.
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -740,8 +740,14 @@ shaka.hls.HlsParser = class {
|
|
|
740
740
|
for (const stream of streamsToNotify) {
|
|
741
741
|
this.segmentsToNotifyByStream_.push(stream.segmentIndex.references);
|
|
742
742
|
}
|
|
743
|
+
|
|
743
744
|
this.notifySegments_();
|
|
744
745
|
|
|
746
|
+
// This is the first point where we have a meaningful presentation start
|
|
747
|
+
// time, and we need to tell PresentationTimeline that so that it can
|
|
748
|
+
// maintain consistency from here on.
|
|
749
|
+
this.presentationTimeline_.lockStartTime();
|
|
750
|
+
|
|
745
751
|
// This asserts that the live edge is being calculated from segment times.
|
|
746
752
|
// For VOD and event streams, this check should still pass.
|
|
747
753
|
goog.asserts.assert(
|
|
@@ -1859,8 +1865,6 @@ shaka.hls.HlsParser = class {
|
|
|
1859
1865
|
/* presentationStartTime= */ null, /* delay= */ 0);
|
|
1860
1866
|
this.presentationTimeline_.setStatic(true);
|
|
1861
1867
|
}
|
|
1862
|
-
|
|
1863
|
-
this.notifySegments_();
|
|
1864
1868
|
}
|
|
1865
1869
|
|
|
1866
1870
|
/**
|
package/lib/media/drm_engine.js
CHANGED
|
@@ -1548,7 +1548,7 @@ shaka.media.DrmEngine = class {
|
|
|
1548
1548
|
if (shaka.media.DrmEngine.isPlayReadyKeySystem(
|
|
1549
1549
|
this.currentDrmInfo_.keySystem) &&
|
|
1550
1550
|
keyId.byteLength == 16 &&
|
|
1551
|
-
shaka.util.Platform.isEdge()) {
|
|
1551
|
+
(shaka.util.Platform.isEdge() || shaka.util.Platform.isPS4())) {
|
|
1552
1552
|
// Read out some fields in little-endian:
|
|
1553
1553
|
const dataView = shaka.util.BufferUtils.toDataView(keyId);
|
|
1554
1554
|
const part0 = dataView.getUint32(0, /* LE= */ true);
|
|
@@ -10,6 +10,7 @@ goog.require('goog.asserts');
|
|
|
10
10
|
goog.require('shaka.log');
|
|
11
11
|
goog.require('shaka.media.ContentWorkarounds');
|
|
12
12
|
goog.require('shaka.media.IClosedCaptionParser');
|
|
13
|
+
goog.require('shaka.media.SegmentReference');
|
|
13
14
|
goog.require('shaka.media.TimeRangesUtils');
|
|
14
15
|
goog.require('shaka.media.Transmuxer');
|
|
15
16
|
goog.require('shaka.text.TextEngine');
|
|
@@ -466,13 +467,13 @@ shaka.media.MediaSourceEngine = class {
|
|
|
466
467
|
*/
|
|
467
468
|
getBufferedInfo() {
|
|
468
469
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
469
|
-
const
|
|
470
|
+
const TimeRangesUtils = shaka.media.TimeRangesUtils;
|
|
470
471
|
|
|
471
472
|
const info = {
|
|
472
|
-
total:
|
|
473
|
-
audio:
|
|
473
|
+
total: TimeRangesUtils.getBufferedInfo(this.video_.buffered),
|
|
474
|
+
audio: TimeRangesUtils.getBufferedInfo(
|
|
474
475
|
this.getBuffered_(ContentType.AUDIO)),
|
|
475
|
-
video:
|
|
476
|
+
video: TimeRangesUtils.getBufferedInfo(
|
|
476
477
|
this.getBuffered_(ContentType.VIDEO)),
|
|
477
478
|
text: [],
|
|
478
479
|
};
|
|
@@ -516,15 +517,14 @@ shaka.media.MediaSourceEngine = class {
|
|
|
516
517
|
*
|
|
517
518
|
* @param {shaka.util.ManifestParserUtils.ContentType} contentType
|
|
518
519
|
* @param {!BufferSource} data
|
|
519
|
-
* @param {?
|
|
520
|
-
*
|
|
520
|
+
* @param {?shaka.media.SegmentReference} reference The segment reference
|
|
521
|
+
* we are appending, or null for init segments
|
|
521
522
|
* @param {?boolean} hasClosedCaptions True if the buffer contains CEA closed
|
|
522
|
-
*
|
|
523
|
+
* captions
|
|
523
524
|
* @param {boolean=} seeked True if we just seeked
|
|
524
525
|
* @return {!Promise}
|
|
525
526
|
*/
|
|
526
|
-
async appendBuffer(
|
|
527
|
-
contentType, data, startTime, endTime, hasClosedCaptions, seeked) {
|
|
527
|
+
async appendBuffer(contentType, data, reference, hasClosedCaptions, seeked) {
|
|
528
528
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
529
529
|
|
|
530
530
|
if (contentType == ContentType.TEXT) {
|
|
@@ -533,7 +533,10 @@ shaka.media.MediaSourceEngine = class {
|
|
|
533
533
|
const offset = await this.textSequenceModeOffset_;
|
|
534
534
|
this.textEngine_.setTimestampOffset(offset);
|
|
535
535
|
}
|
|
536
|
-
await this.textEngine_.appendBuffer(
|
|
536
|
+
await this.textEngine_.appendBuffer(
|
|
537
|
+
data,
|
|
538
|
+
reference ? reference.startTime : null,
|
|
539
|
+
reference ? reference.endTime : null);
|
|
537
540
|
return;
|
|
538
541
|
}
|
|
539
542
|
|
|
@@ -549,7 +552,10 @@ shaka.media.MediaSourceEngine = class {
|
|
|
549
552
|
if (transmuxedData.metadata) {
|
|
550
553
|
const timestampOffset =
|
|
551
554
|
this.sourceBuffers_[contentType].timestampOffset;
|
|
552
|
-
this.onMetadata_(
|
|
555
|
+
this.onMetadata_(
|
|
556
|
+
transmuxedData.metadata,
|
|
557
|
+
timestampOffset,
|
|
558
|
+
reference ? reference.endTime : null);
|
|
553
559
|
}
|
|
554
560
|
// This doesn't work for native TS support (ex. Edge/Chromecast),
|
|
555
561
|
// since no transmuxing is needed for native TS.
|
|
@@ -559,7 +565,10 @@ shaka.media.MediaSourceEngine = class {
|
|
|
559
565
|
const closedCaptions = this.textEngine_
|
|
560
566
|
.convertMuxjsCaptionsToShakaCaptions(transmuxedData.captions);
|
|
561
567
|
this.textEngine_.storeAndAppendClosedCaptions(
|
|
562
|
-
closedCaptions,
|
|
568
|
+
closedCaptions,
|
|
569
|
+
reference ? reference.startTime : null,
|
|
570
|
+
reference ? reference.endTime : null,
|
|
571
|
+
videoOffset);
|
|
563
572
|
}
|
|
564
573
|
|
|
565
574
|
data = transmuxedData.data;
|
|
@@ -569,7 +578,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
569
578
|
}
|
|
570
579
|
// If it is the init segment for closed captions, initialize the closed
|
|
571
580
|
// caption parser.
|
|
572
|
-
if (
|
|
581
|
+
if (!reference) {
|
|
573
582
|
this.captionParser_.init(data);
|
|
574
583
|
} else {
|
|
575
584
|
const closedCaptions = this.captionParser_.parseFrom(data);
|
|
@@ -577,18 +586,21 @@ shaka.media.MediaSourceEngine = class {
|
|
|
577
586
|
const videoOffset =
|
|
578
587
|
this.sourceBuffers_[ContentType.VIDEO].timestampOffset;
|
|
579
588
|
this.textEngine_.storeAndAppendClosedCaptions(
|
|
580
|
-
closedCaptions,
|
|
589
|
+
closedCaptions,
|
|
590
|
+
reference.startTime,
|
|
591
|
+
reference.endTime,
|
|
592
|
+
videoOffset);
|
|
581
593
|
}
|
|
582
594
|
}
|
|
583
595
|
}
|
|
584
596
|
|
|
585
|
-
data = this.workAroundBrokenPlatforms_(
|
|
597
|
+
data = this.workAroundBrokenPlatforms_(
|
|
598
|
+
data, reference ? reference.startTime : null, contentType);
|
|
586
599
|
|
|
587
600
|
const sourceBuffer = this.sourceBuffers_[contentType];
|
|
588
601
|
const SEQUENCE = shaka.media.MediaSourceEngine.SourceBufferMode_.SEQUENCE;
|
|
589
602
|
|
|
590
|
-
if (this.sequenceMode_ && sourceBuffer.mode != SEQUENCE &&
|
|
591
|
-
startTime != null) {
|
|
603
|
+
if (this.sequenceMode_ && sourceBuffer.mode != SEQUENCE && reference) {
|
|
592
604
|
// This is the first media segment to be appended to a SourceBuffer in
|
|
593
605
|
// sequence mode. We set the mode late so that we can trick MediaSource
|
|
594
606
|
// into extracting a timestamp for us to align text segments in sequence
|
|
@@ -623,7 +635,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
623
635
|
// segments.
|
|
624
636
|
const mediaStartTime = shaka.media.TimeRangesUtils.bufferStart(
|
|
625
637
|
this.getBuffered_(contentType));
|
|
626
|
-
const textOffset = (startTime || 0) - (mediaStartTime || 0);
|
|
638
|
+
const textOffset = (reference.startTime || 0) - (mediaStartTime || 0);
|
|
627
639
|
this.textSequenceModeOffset_.resolve(textOffset);
|
|
628
640
|
|
|
629
641
|
// Finally, clear the buffer.
|
|
@@ -636,22 +648,43 @@ shaka.media.MediaSourceEngine = class {
|
|
|
636
648
|
sourceBuffer.mode = SEQUENCE;
|
|
637
649
|
}
|
|
638
650
|
|
|
639
|
-
if (
|
|
640
|
-
contentType != ContentType.TEXT) {
|
|
651
|
+
if (reference && this.sequenceMode_ && contentType != ContentType.TEXT) {
|
|
641
652
|
// In sequence mode, for non-text streams, if we just cleared the buffer
|
|
642
653
|
// and are performing an unbuffered seek, we need to set a new
|
|
643
654
|
// timestampOffset on the sourceBuffer.
|
|
644
655
|
if (seeked) {
|
|
645
|
-
const timestampOffset =
|
|
656
|
+
const timestampOffset = reference.startTime;
|
|
646
657
|
this.enqueueOperation_(
|
|
647
658
|
contentType,
|
|
648
659
|
() => this.setTimestampOffset_(contentType, timestampOffset));
|
|
649
660
|
}
|
|
650
661
|
}
|
|
651
662
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
663
|
+
let bufferedBefore = null;
|
|
664
|
+
|
|
665
|
+
await this.enqueueOperation_(contentType, () => {
|
|
666
|
+
if (goog.DEBUG && reference) {
|
|
667
|
+
bufferedBefore = this.getBuffered_(contentType);
|
|
668
|
+
}
|
|
669
|
+
this.append_(contentType, data);
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
if (goog.DEBUG && reference) {
|
|
673
|
+
const bufferedAfter = this.getBuffered_(contentType);
|
|
674
|
+
const newBuffered = shaka.media.TimeRangesUtils.computeAddedRange(
|
|
675
|
+
bufferedBefore, bufferedAfter);
|
|
676
|
+
if (newBuffered) {
|
|
677
|
+
const segmentDuration = reference.endTime - reference.startTime;
|
|
678
|
+
if (Math.abs(newBuffered.start - reference.startTime) >
|
|
679
|
+
segmentDuration / 2) {
|
|
680
|
+
shaka.log.error('Possible encoding problem detected!',
|
|
681
|
+
'Unexpected buffered range for reference', reference,
|
|
682
|
+
'from URIs', reference.getUris(),
|
|
683
|
+
'should be', {start: reference.startTime, end: reference.endTime},
|
|
684
|
+
'but got', newBuffered);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
655
688
|
}
|
|
656
689
|
|
|
657
690
|
/**
|
|
@@ -93,6 +93,9 @@ shaka.media.PresentationTimeline = class {
|
|
|
93
93
|
* @private {number}
|
|
94
94
|
*/
|
|
95
95
|
this.availabilityTimeOffset_ = 0;
|
|
96
|
+
|
|
97
|
+
/** @private {boolean} */
|
|
98
|
+
this.startTimeLocked_ = false;
|
|
96
99
|
}
|
|
97
100
|
|
|
98
101
|
|
|
@@ -229,7 +232,8 @@ shaka.media.PresentationTimeline = class {
|
|
|
229
232
|
this.maxSegmentEndTime_ =
|
|
230
233
|
Math.max(this.maxSegmentEndTime_, lastReferenceEndTime);
|
|
231
234
|
|
|
232
|
-
if (this.presentationStartTime_ != null && this.autoCorrectDrift_
|
|
235
|
+
if (this.presentationStartTime_ != null && this.autoCorrectDrift_ &&
|
|
236
|
+
!this.startTimeLocked_) {
|
|
233
237
|
// Since we have explicit segment end times, calculate a presentation
|
|
234
238
|
// start based on them. This start time accounts for drift.
|
|
235
239
|
// Date.now() is in milliseconds, from which we compute "now" in seconds.
|
|
@@ -243,6 +247,25 @@ shaka.media.PresentationTimeline = class {
|
|
|
243
247
|
}
|
|
244
248
|
|
|
245
249
|
|
|
250
|
+
/**
|
|
251
|
+
* Lock the presentation timeline's start time. After this is called, no
|
|
252
|
+
* further adjustments to presentationStartTime_ will be permitted.
|
|
253
|
+
*
|
|
254
|
+
* This should be called after all Periods have been parsed, and all calls to
|
|
255
|
+
* notifySegments() from the initial manifest parse have been made.
|
|
256
|
+
*
|
|
257
|
+
* Without this, we can get assertion failures in SegmentIndex for certain
|
|
258
|
+
* DAI content. If DAI adds ad segments to the manifest faster than
|
|
259
|
+
* real-time, adjustments to presentationStartTime_ can cause availability
|
|
260
|
+
* windows to jump around on updates.
|
|
261
|
+
*
|
|
262
|
+
* @export
|
|
263
|
+
*/
|
|
264
|
+
lockStartTime() {
|
|
265
|
+
this.startTimeLocked_ = true;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
|
|
246
269
|
/**
|
|
247
270
|
* Gives PresentationTimeline a Stream's minimum segment start time.
|
|
248
271
|
*
|
|
@@ -1555,8 +1555,8 @@ shaka.media.StreamingEngine = class {
|
|
|
1555
1555
|
const hasClosedCaptions = mediaState.stream.closedCaptions &&
|
|
1556
1556
|
mediaState.stream.closedCaptions.size > 0;
|
|
1557
1557
|
await this.playerInterface_.mediaSourceEngine.appendBuffer(
|
|
1558
|
-
mediaState.type, initSegment, /*
|
|
1559
|
-
|
|
1558
|
+
mediaState.type, initSegment, /* reference= */ null,
|
|
1559
|
+
hasClosedCaptions);
|
|
1560
1560
|
} catch (error) {
|
|
1561
1561
|
mediaState.lastInitSegmentReference = null;
|
|
1562
1562
|
throw error;
|
|
@@ -1609,8 +1609,7 @@ shaka.media.StreamingEngine = class {
|
|
|
1609
1609
|
await this.playerInterface_.mediaSourceEngine.appendBuffer(
|
|
1610
1610
|
mediaState.type,
|
|
1611
1611
|
segment,
|
|
1612
|
-
reference
|
|
1613
|
-
reference.endTime,
|
|
1612
|
+
reference,
|
|
1614
1613
|
hasClosedCaptions,
|
|
1615
1614
|
seeked);
|
|
1616
1615
|
this.destroyer_.ensureNotDestroyed();
|
|
@@ -1791,6 +1790,7 @@ shaka.media.StreamingEngine = class {
|
|
|
1791
1790
|
*
|
|
1792
1791
|
* @return {!Promise.<BufferSource>}
|
|
1793
1792
|
* @private
|
|
1793
|
+
* @suppress {strictMissingProperties}
|
|
1794
1794
|
*/
|
|
1795
1795
|
async fetch_(mediaState, reference, streamDataCallback) {
|
|
1796
1796
|
const requestType = shaka.net.NetworkingEngine.RequestType.SEGMENT;
|
|
@@ -155,4 +155,50 @@ shaka.media.TimeRangesUtils = class {
|
|
|
155
155
|
}
|
|
156
156
|
return ret;
|
|
157
157
|
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* This operation can be potentially EXPENSIVE and should only be done in
|
|
161
|
+
* debug builds for debugging purposes.
|
|
162
|
+
*
|
|
163
|
+
* @param {TimeRanges} oldRanges
|
|
164
|
+
* @param {TimeRanges} newRanges
|
|
165
|
+
* @return {?shaka.extern.BufferedRange} The last added range,
|
|
166
|
+
* chronologically by presentation time.
|
|
167
|
+
*/
|
|
168
|
+
static computeAddedRange(oldRanges, newRanges) {
|
|
169
|
+
const TimeRangesUtils = shaka.media.TimeRangesUtils;
|
|
170
|
+
|
|
171
|
+
if (!oldRanges || !oldRanges.length) {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
if (!newRanges || !newRanges.length) {
|
|
175
|
+
return TimeRangesUtils.getBufferedInfo(newRanges).pop();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const newRangesReversed =
|
|
179
|
+
TimeRangesUtils.getBufferedInfo(newRanges).reverse();
|
|
180
|
+
const oldRangesReversed =
|
|
181
|
+
TimeRangesUtils.getBufferedInfo(oldRanges).reverse();
|
|
182
|
+
for (const newRange of newRangesReversed) {
|
|
183
|
+
let foundOverlap = false;
|
|
184
|
+
|
|
185
|
+
for (const oldRange of oldRangesReversed) {
|
|
186
|
+
if (oldRange.end >= newRange.start && oldRange.end <= newRange.end) {
|
|
187
|
+
foundOverlap = true;
|
|
188
|
+
|
|
189
|
+
// If the new range goes beyond the corresponding old one, the
|
|
190
|
+
// difference is newly-added.
|
|
191
|
+
if (newRange.end > oldRange.end) {
|
|
192
|
+
return {start: oldRange.end, end: newRange.end};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (!foundOverlap) {
|
|
198
|
+
return newRange;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
158
204
|
};
|
package/lib/player.js
CHANGED
|
@@ -857,14 +857,9 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
857
857
|
if (!window.Promise) {
|
|
858
858
|
shaka.log.alwaysWarn('A Promise implementation or polyfill is required');
|
|
859
859
|
}
|
|
860
|
-
if (!window.TextDecoder || !window.TextEncoder) {
|
|
861
|
-
shaka.log.alwaysWarn(
|
|
862
|
-
'A TextDecoder/TextEncoder implementation or polyfill is required');
|
|
863
|
-
}
|
|
864
860
|
|
|
865
861
|
// Basic features needed for the library to be usable.
|
|
866
862
|
const basicSupport = !!window.Promise && !!window.Uint8Array &&
|
|
867
|
-
!!window.TextDecoder && !!window.TextEncoder &&
|
|
868
863
|
// eslint-disable-next-line no-restricted-syntax
|
|
869
864
|
!!Array.prototype.forEach;
|
|
870
865
|
if (!basicSupport) {
|
|
@@ -4457,6 +4452,12 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4457
4452
|
this.stats_.setBandwidthEstimate(estimate);
|
|
4458
4453
|
}
|
|
4459
4454
|
|
|
4455
|
+
if (this.loadMode_ == shaka.Player.LoadMode.SRC_EQUALS) {
|
|
4456
|
+
this.stats_.setResolution(
|
|
4457
|
+
/* width= */ element.videoWidth || NaN,
|
|
4458
|
+
/* height= */ element.videoHeight || NaN);
|
|
4459
|
+
}
|
|
4460
|
+
|
|
4460
4461
|
return this.stats_.getBlob();
|
|
4461
4462
|
}
|
|
4462
4463
|
|
|
@@ -5623,6 +5624,12 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5623
5624
|
return false;
|
|
5624
5625
|
}
|
|
5625
5626
|
|
|
5627
|
+
if (!navigator.onLine) {
|
|
5628
|
+
// Don't restrict variants if we're completely offline, or else we end up
|
|
5629
|
+
// rapidly restricting all of them.
|
|
5630
|
+
return false;
|
|
5631
|
+
}
|
|
5632
|
+
|
|
5626
5633
|
let maxDisabledTime = this.config_.streaming.maxDisabledTime;
|
|
5627
5634
|
if (maxDisabledTime == 0) {
|
|
5628
5635
|
if (error.code == shaka.util.Error.Code.SEGMENT_MISSING) {
|
|
@@ -6556,7 +6563,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
6556
6563
|
* @define {string} A version number taken from git at compile time.
|
|
6557
6564
|
* @export
|
|
6558
6565
|
*/
|
|
6559
|
-
shaka.Player.version = 'v4.1.
|
|
6566
|
+
shaka.Player.version = 'v4.1.4-uncompiled';
|
|
6560
6567
|
|
|
6561
6568
|
// Initialize the deprecation system using the version string we just set
|
|
6562
6569
|
// on the player.
|
|
@@ -37,9 +37,18 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
37
37
|
// See: https://github.com/shaka-project/shaka-player/issues/3582
|
|
38
38
|
// TODO: re-evaluate MediaCapabilities in the future versions of PS5
|
|
39
39
|
// Browsers.
|
|
40
|
+
// Since MediaCapabilities implementation does not exist in PS4 browsers, we
|
|
41
|
+
// should always install polyfill.
|
|
42
|
+
// Since MediaCapabilities implementation is buggy in Tizen browsers, we
|
|
43
|
+
// should always install polyfill for Tizen browsers.
|
|
44
|
+
// Since MediaCapabilities implementation is buggy in WebOS browsers, we
|
|
45
|
+
// should always install polyfill for WebOS browsers.
|
|
40
46
|
let canUseNativeMCap = true;
|
|
41
47
|
if (shaka.util.Platform.isApple() ||
|
|
42
48
|
shaka.util.Platform.isPS5() ||
|
|
49
|
+
shaka.util.Platform.isPS4() ||
|
|
50
|
+
shaka.util.Platform.isWebOS() ||
|
|
51
|
+
shaka.util.Platform.isTizen() ||
|
|
43
52
|
shaka.util.Platform.isChromecast()) {
|
|
44
53
|
canUseNativeMCap = false;
|
|
45
54
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
goog.provide('shaka.polyfill.VideoPlaybackQuality');
|
|
8
8
|
|
|
9
9
|
goog.require('shaka.polyfill');
|
|
10
|
+
goog.require('shaka.util.Platform');
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -33,7 +34,8 @@ shaka.polyfill.VideoPlaybackQuality = class {
|
|
|
33
34
|
return;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
if ('webkitDroppedFrameCount' in proto
|
|
37
|
+
if ('webkitDroppedFrameCount' in proto ||
|
|
38
|
+
shaka.util.Platform.isWebOS3()) {
|
|
37
39
|
proto.getVideoPlaybackQuality =
|
|
38
40
|
shaka.polyfill.VideoPlaybackQuality.webkit_;
|
|
39
41
|
}
|
package/lib/text/cue.js
CHANGED
|
@@ -41,14 +41,9 @@ shaka.text.Cue = class {
|
|
|
41
41
|
*/
|
|
42
42
|
this.endTime = endTime;
|
|
43
43
|
|
|
44
|
-
// The explicit type here is to work around an apparent compiler bug where
|
|
45
|
-
// the compiler seems to get confused about the type. Since we are
|
|
46
|
-
// overriding the interface type, it shouldn't be necessary to do this.
|
|
47
|
-
// Compiler version 20200517.
|
|
48
44
|
/**
|
|
49
45
|
* @override
|
|
50
46
|
* @exportInterface
|
|
51
|
-
* @type {string}
|
|
52
47
|
*/
|
|
53
48
|
this.payload = payload;
|
|
54
49
|
|
|
@@ -121,16 +121,28 @@ shaka.text.SimpleTextDisplayer = class {
|
|
|
121
121
|
// We don't want to modify the array or objects passed in, since we don't
|
|
122
122
|
// technically own them. So we build a new array and replace certain items
|
|
123
123
|
// in it if they need to be flattened.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
124
|
+
// We also don't want to flatten the text payloads starting at a container
|
|
125
|
+
// element; otherwise, for containers encapsulating multiple caption lines,
|
|
126
|
+
// the lines would merge into a single cue. This is undesirable when a
|
|
127
|
+
// subset of the captions are outside of the append time window. To fix
|
|
128
|
+
// this, we only call flattenPayload() starting at elements marked as
|
|
129
|
+
// isContainer = false.
|
|
130
|
+
const getCuesToFlatten = (cues, result) => {
|
|
131
|
+
for (const cue of cues) {
|
|
132
|
+
if (cue.isContainer) {
|
|
133
|
+
// Recurse to find the actual text payload cues.
|
|
134
|
+
getCuesToFlatten(cue.nestedCues, result);
|
|
135
|
+
} else {
|
|
136
|
+
// Flatten the payload.
|
|
137
|
+
const flatCue = cue.clone();
|
|
138
|
+
flatCue.nestedCues = [];
|
|
139
|
+
flatCue.payload = flattenPayload(cue);
|
|
140
|
+
result.push(flatCue);
|
|
141
|
+
}
|
|
132
142
|
}
|
|
133
|
-
|
|
143
|
+
return result;
|
|
144
|
+
};
|
|
145
|
+
const flattenedCues = getCuesToFlatten(cues, []);
|
|
134
146
|
|
|
135
147
|
// Convert cues.
|
|
136
148
|
const textTrackCues = [];
|