shaka-player 3.3.14 → 3.3.15
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 +13 -0
- package/AUTHORS +1 -0
- package/CHANGELOG.md +9 -0
- package/CONTRIBUTORS +1 -0
- package/dist/locales.js +29 -29
- package/dist/shaka-player.compiled.debug.js +14 -14
- package/dist/shaka-player.compiled.debug.map +2 -2
- package/dist/shaka-player.compiled.js +138 -138
- package/dist/shaka-player.compiled.map +2 -2
- package/dist/shaka-player.ui.debug.js +16 -16
- package/dist/shaka-player.ui.debug.map +2 -2
- package/dist/shaka-player.ui.js +154 -154
- package/dist/shaka-player.ui.map +2 -2
- package/lib/ads/ad_manager.js +2 -2
- package/lib/media/streaming_engine.js +20 -8
- package/lib/player.js +11 -2
- package/package.json +1 -1
- package/test/player_integration.js +10 -3
- package/test/test/boot.js +29 -11
- package/test/test/util/test_scheme.js +2 -2
package/lib/ads/ad_manager.js
CHANGED
|
@@ -19,8 +19,8 @@ goog.require('shaka.util.IReleasable');
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* @event shaka.ads.AdManager.
|
|
23
|
-
* @description Fired when
|
|
22
|
+
* @event shaka.ads.AdManager.AdsLoadedEvent
|
|
23
|
+
* @description Fired when a sequence of ads has been loaded.
|
|
24
24
|
* @property {string} type
|
|
25
25
|
* 'ads-loaded'
|
|
26
26
|
* @property {number} loadTime
|
|
@@ -603,6 +603,11 @@ shaka.media.StreamingEngine = class {
|
|
|
603
603
|
* within the presentation timeline.
|
|
604
604
|
*/
|
|
605
605
|
seeked() {
|
|
606
|
+
if (!this.playerInterface_) {
|
|
607
|
+
// Already destroyed.
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
|
|
606
611
|
const presentationTime = this.playerInterface_.getPresentationTime();
|
|
607
612
|
const smallGapLimit = this.config_.smallGapLimit;
|
|
608
613
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
@@ -657,7 +662,7 @@ shaka.media.StreamingEngine = class {
|
|
|
657
662
|
|
|
658
663
|
/**
|
|
659
664
|
* Clear the buffer for a given stream. Unlike clearBuffer_, this will handle
|
|
660
|
-
* cases where a MediaState is performing an update. After this runs,
|
|
665
|
+
* cases where a MediaState is performing an update. After this runs, the
|
|
661
666
|
* MediaState will have a pending update.
|
|
662
667
|
* @param {!shaka.media.StreamingEngine.MediaState_} mediaState
|
|
663
668
|
* @private
|
|
@@ -772,9 +777,9 @@ shaka.media.StreamingEngine = class {
|
|
|
772
777
|
for (const type of streamsByType.keys()) {
|
|
773
778
|
const stream = streamsByType.get(type);
|
|
774
779
|
if (!this.mediaStates_.has(type)) {
|
|
775
|
-
const
|
|
776
|
-
this.mediaStates_.set(type,
|
|
777
|
-
this.scheduleUpdate_(
|
|
780
|
+
const mediaState = this.createMediaState_(stream);
|
|
781
|
+
this.mediaStates_.set(type, mediaState);
|
|
782
|
+
this.scheduleUpdate_(mediaState, 0);
|
|
778
783
|
}
|
|
779
784
|
}
|
|
780
785
|
}
|
|
@@ -884,7 +889,7 @@ shaka.media.StreamingEngine = class {
|
|
|
884
889
|
'mediastate.stream should not have segmentIndex yet.');
|
|
885
890
|
thisStream.closeSegmentIndex();
|
|
886
891
|
}
|
|
887
|
-
if (mediaState.
|
|
892
|
+
if (!mediaState.performingUpdate && !mediaState.updateTimer) {
|
|
888
893
|
this.scheduleUpdate_(mediaState, 0);
|
|
889
894
|
}
|
|
890
895
|
return;
|
|
@@ -1352,7 +1357,7 @@ shaka.media.StreamingEngine = class {
|
|
|
1352
1357
|
// If the network slows down, abort the current fetch request and start
|
|
1353
1358
|
// a new one, and ignore the error message.
|
|
1354
1359
|
mediaState.performingUpdate = false;
|
|
1355
|
-
mediaState
|
|
1360
|
+
this.cancelUpdate_(mediaState);
|
|
1356
1361
|
this.scheduleUpdate_(mediaState, 0);
|
|
1357
1362
|
} else if (mediaState.type == ContentType.TEXT &&
|
|
1358
1363
|
this.config_.ignoreTextStreamFailures) {
|
|
@@ -1397,7 +1402,10 @@ shaka.media.StreamingEngine = class {
|
|
|
1397
1402
|
|
|
1398
1403
|
for (const mediaState of this.mediaStates_.values()) {
|
|
1399
1404
|
const logPrefix = shaka.media.StreamingEngine.logPrefix_(mediaState);
|
|
1400
|
-
if
|
|
1405
|
+
// Only schedule an update if it has an error, but it's not mid-update
|
|
1406
|
+
// and there is not already an update scheduled.
|
|
1407
|
+
if (mediaState.hasError && !mediaState.performingUpdate &&
|
|
1408
|
+
!mediaState.updateTimer) {
|
|
1401
1409
|
shaka.log.info(logPrefix, 'Retrying after failure...');
|
|
1402
1410
|
mediaState.hasError = false;
|
|
1403
1411
|
this.scheduleUpdate_(mediaState, delaySeconds);
|
|
@@ -1880,7 +1888,11 @@ shaka.media.StreamingEngine = class {
|
|
|
1880
1888
|
shaka.log.debug(logPrefix, 'cleared buffer');
|
|
1881
1889
|
mediaState.clearingBuffer = false;
|
|
1882
1890
|
mediaState.endOfStream = false;
|
|
1883
|
-
|
|
1891
|
+
// Since the clear operation was async, check to make sure we're not doing
|
|
1892
|
+
// another update and we don't have one scheduled yet.
|
|
1893
|
+
if (!mediaState.performingUpdate && !mediaState.updateTimer) {
|
|
1894
|
+
this.scheduleUpdate_(mediaState, 0);
|
|
1895
|
+
}
|
|
1884
1896
|
}
|
|
1885
1897
|
|
|
1886
1898
|
|
package/lib/player.js
CHANGED
|
@@ -4116,16 +4116,25 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4116
4116
|
return [];
|
|
4117
4117
|
}
|
|
4118
4118
|
const chapters = [];
|
|
4119
|
+
const uniqueChapters = new Set();
|
|
4119
4120
|
for (const chaptersTrack of chaptersTracksWithLanguage) {
|
|
4120
4121
|
if (chaptersTrack && chaptersTrack.cues) {
|
|
4121
4122
|
for (const cue of chaptersTrack.cues) {
|
|
4123
|
+
let id = cue.id;
|
|
4124
|
+
if (!id || id == '') {
|
|
4125
|
+
id = cue.startTime + '-' + cue.endTime + '-' + cue.text;
|
|
4126
|
+
}
|
|
4122
4127
|
/** @type {shaka.extern.Chapter} */
|
|
4123
4128
|
const chapter = {
|
|
4129
|
+
id: id,
|
|
4124
4130
|
title: cue.text,
|
|
4125
4131
|
startTime: cue.startTime,
|
|
4126
4132
|
endTime: cue.endTime,
|
|
4127
4133
|
};
|
|
4128
|
-
|
|
4134
|
+
if (!uniqueChapters.has(id)) {
|
|
4135
|
+
chapters.push(chapter);
|
|
4136
|
+
uniqueChapters.add(id);
|
|
4137
|
+
}
|
|
4129
4138
|
}
|
|
4130
4139
|
}
|
|
4131
4140
|
}
|
|
@@ -6648,7 +6657,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
6648
6657
|
* @define {string} A version number taken from git at compile time.
|
|
6649
6658
|
* @export
|
|
6650
6659
|
*/
|
|
6651
|
-
shaka.Player.version = 'v3.3.
|
|
6660
|
+
shaka.Player.version = 'v3.3.15-uncompiled';
|
|
6652
6661
|
|
|
6653
6662
|
// Initialize the deprecation system using the version string we just set
|
|
6654
6663
|
// on the player.
|
package/package.json
CHANGED
|
@@ -879,7 +879,7 @@ describe('Player', () => {
|
|
|
879
879
|
expect(getBufferedBehind()).toBe(20); // Buffered to start still.
|
|
880
880
|
video.currentTime = 50;
|
|
881
881
|
await waitUntilBuffered(30);
|
|
882
|
-
expect(getBufferedBehind()).toBeLessThan(
|
|
882
|
+
expect(getBufferedBehind()).toBeLessThan(40); // 30 + segment_size
|
|
883
883
|
|
|
884
884
|
player.configure('streaming.bufferBehind', 10);
|
|
885
885
|
// We only evict content when we append a segment, so increase the
|
|
@@ -906,7 +906,7 @@ describe('Player', () => {
|
|
|
906
906
|
}
|
|
907
907
|
|
|
908
908
|
async function waitUntilBuffered(amount) {
|
|
909
|
-
for (let i = 0; i <
|
|
909
|
+
for (let i = 0; i < 50; i++) {
|
|
910
910
|
// We buffer from an internal segment, so this shouldn't take long to
|
|
911
911
|
// buffer.
|
|
912
912
|
await Util.delay(0.1); // eslint-disable-line no-await-in-loop
|
|
@@ -914,7 +914,14 @@ describe('Player', () => {
|
|
|
914
914
|
return;
|
|
915
915
|
}
|
|
916
916
|
}
|
|
917
|
-
|
|
917
|
+
|
|
918
|
+
const ranges =
|
|
919
|
+
shaka.media.TimeRangesUtils.getBufferedInfo(video.buffered);
|
|
920
|
+
const currentTime = video.currentTime;
|
|
921
|
+
const target = currentTime + amount;
|
|
922
|
+
|
|
923
|
+
throw new Error('Timeout waiting to buffer! ' +
|
|
924
|
+
JSON.stringify({ranges, currentTime, target}));
|
|
918
925
|
}
|
|
919
926
|
}); // describe('buffering')
|
|
920
927
|
|
package/test/test/boot.js
CHANGED
|
@@ -66,22 +66,40 @@ function failTestsOnNamespacedElementOrAttributeNames() {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
69
|
+
* Fail the current test on a given error, constructed with a given header and
|
|
70
|
+
* the full stack trace of the error.
|
|
71
|
+
*
|
|
72
|
+
* @param {string} messageHeader
|
|
73
|
+
* @param {!Error} error
|
|
71
74
|
*/
|
|
72
|
-
function
|
|
75
|
+
function failOnError(messageHeader, error) {
|
|
76
|
+
let message = `${messageHeader}: ${error}`;
|
|
77
|
+
// Shaka errors have the stack trace in their toString() already, so don't
|
|
78
|
+
// add it again. For native errors, we need to see where it came from.
|
|
79
|
+
if (error && error.stack && !(error instanceof shaka.util.Error)) {
|
|
80
|
+
message += '\n' + error.stack;
|
|
81
|
+
}
|
|
82
|
+
fail(message);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Listen for unhandled errors and Promise rejections (which may occur after a
|
|
87
|
+
* test) and convert them into test failures.
|
|
88
|
+
*/
|
|
89
|
+
function failTestsOnUnhandledErrors() {
|
|
73
90
|
// https://developer.mozilla.org/en-US/docs/Web/Events/unhandledrejection
|
|
74
91
|
window.addEventListener('unhandledrejection', (event) => {
|
|
75
92
|
/** @type {?} */
|
|
76
93
|
const error = event.reason;
|
|
77
|
-
|
|
94
|
+
failOnError('Unhandled rejection in Promise', error);
|
|
95
|
+
});
|
|
78
96
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
97
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Window/error_event
|
|
98
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent
|
|
99
|
+
window.addEventListener('error', (event) => {
|
|
100
|
+
/** @type {?} */
|
|
101
|
+
const error = event['error'];
|
|
102
|
+
failOnError('Unhandled error', error);
|
|
85
103
|
});
|
|
86
104
|
}
|
|
87
105
|
|
|
@@ -387,7 +405,7 @@ function configureJasmineEnvironment() {
|
|
|
387
405
|
function setupTestEnvironment() {
|
|
388
406
|
failTestsOnFailedAssertions();
|
|
389
407
|
failTestsOnNamespacedElementOrAttributeNames();
|
|
390
|
-
|
|
408
|
+
failTestsOnUnhandledErrors();
|
|
391
409
|
disableScrollbars();
|
|
392
410
|
workAroundLegacyEdgePromiseIssues();
|
|
393
411
|
|
|
@@ -402,7 +402,7 @@ const sintelAudioSegment = {
|
|
|
402
402
|
mdhdOffset: 0x1b6,
|
|
403
403
|
segmentUri: '/base/test/test/assets/sintel-audio-segment.mp4',
|
|
404
404
|
tfdtOffset: 0x3c,
|
|
405
|
-
segmentDuration: 10
|
|
405
|
+
segmentDuration: 10,
|
|
406
406
|
mimeType: 'audio/mp4',
|
|
407
407
|
codecs: 'mp4a.40.2',
|
|
408
408
|
};
|
|
@@ -428,7 +428,7 @@ const sintelEncryptedAudio = {
|
|
|
428
428
|
mdhdOffset: 0x1b6,
|
|
429
429
|
segmentUri: '/base/test/test/assets/encrypted-sintel-audio-segment.mp4',
|
|
430
430
|
tfdtOffset: 0x3c,
|
|
431
|
-
segmentDuration: 10
|
|
431
|
+
segmentDuration: 10,
|
|
432
432
|
mimeType: 'audio/mp4',
|
|
433
433
|
codecs: 'mp4a.40.2',
|
|
434
434
|
initData:
|