shaka-player 3.3.4 → 3.3.5
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 +0 -1
- package/.github/workflows/release-please.yaml +1 -1
- package/.github/workflows/selenium-lab-tests.yaml +0 -1
- package/CHANGELOG.md +18 -0
- package/build/README.md +2 -2
- package/build/checkversion.py +1 -1
- package/build/generateTsDefs.py +0 -2
- package/build/test.py +7 -1
- package/build/types/core +0 -1
- package/dist/controls.css +1 -1
- package/dist/deps.js +1 -2
- package/dist/locales.js +30 -30
- package/dist/shaka-player.compiled.d.ts +238 -239
- package/dist/shaka-player.compiled.debug.d.ts +238 -239
- package/dist/shaka-player.compiled.debug.externs.js +1 -0
- package/dist/shaka-player.compiled.debug.js +149 -147
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +1 -0
- package/dist/shaka-player.compiled.js +844 -842
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +282 -283
- package/dist/shaka-player.ui.debug.d.ts +282 -283
- package/dist/shaka-player.ui.debug.externs.js +1 -0
- package/dist/shaka-player.ui.debug.js +222 -220
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +1 -0
- package/dist/shaka-player.ui.js +956 -954
- package/dist/shaka-player.ui.map +4 -4
- package/karma.conf.js +4 -0
- package/lib/dash/dash_parser.js +2 -3
- package/lib/hls/hls_parser.js +23 -11
- package/lib/media/media_source_engine.js +7 -1
- package/lib/offline/indexeddb/storage_mechanism.js +4 -2
- package/lib/offline/storage.js +92 -91
- package/lib/player.js +165 -107
- package/lib/util/config_utils.js +25 -0
- package/lib/util/error.js +7 -0
- package/lib/util/manifest_parser_utils.js +1 -1
- package/lib/util/mime_utils.js +48 -1
- package/lib/util/periods.js +5 -4
- package/lib/util/player_configuration.js +9 -14
- package/lib/util/stream_utils.js +4 -2
- package/package.json +1 -1
- package/test/cast/cast_utils_unit.js +1 -0
- package/test/dash/dash_parser_manifest_unit.js +0 -24
- package/test/hls/hls_live_unit.js +26 -0
- package/test/hls/manifest_text_parser_unit.js +19 -0
- package/test/media/media_source_engine_integration.js +1 -0
- package/test/media/media_source_engine_unit.js +4 -4
- package/test/media/streaming_engine_integration.js +2 -0
- package/test/offline/indexeddb_storage_unit.js +1 -1
- package/test/offline/storage_compatibility_unit.js +1 -1
- package/test/player_external.js +7 -1
- package/test/player_integration.js +6 -10
- package/test/player_src_equals_integration.js +81 -83
- package/test/player_unit.js +98 -1
- package/test/test/boot.js +9 -0
- package/test/test/externs/filters.js +4 -0
- package/test/test/util/simple_fakes.js +31 -2
- package/test/util/mime_utils_unit.js +54 -0
- package/test/util/periods_unit.js +79 -0
- package/docs/tutorials/gsoc-ideas-list.md +0 -3
- package/lib/util/mutex.js +0 -52
|
@@ -152,9 +152,27 @@ shaka.test.FakeVideo = class {
|
|
|
152
152
|
constructor(currentTime) {
|
|
153
153
|
/** @const {!Object.<string, !Function>} */
|
|
154
154
|
this.on = {}; // event listeners
|
|
155
|
+
|
|
155
156
|
/** @type {!Array.<!TextTrack>} */
|
|
156
157
|
this.textTracks = [];
|
|
157
158
|
|
|
159
|
+
// In a real video element, textTracks is an event target.
|
|
160
|
+
// Since Player listens to events on textTracks, we need to fake that
|
|
161
|
+
// interface.
|
|
162
|
+
this.textTracksEventTarget = new shaka.util.FakeEventTarget();
|
|
163
|
+
this.textTracks.addEventListener =
|
|
164
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
165
|
+
this.textTracksEventTarget.addEventListener.bind(
|
|
166
|
+
this.textTracksEventTarget);
|
|
167
|
+
this.textTracks.removeEventListener =
|
|
168
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
169
|
+
this.textTracksEventTarget.removeEventListener.bind(
|
|
170
|
+
this.textTracksEventTarget);
|
|
171
|
+
this.textTracks.dispatchEvent =
|
|
172
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
173
|
+
this.textTracksEventTarget.dispatchEvent.bind(
|
|
174
|
+
this.textTracksEventTarget);
|
|
175
|
+
|
|
158
176
|
this.currentTime = currentTime || 0;
|
|
159
177
|
this.readyState = 0;
|
|
160
178
|
this.playbackRate = 1;
|
|
@@ -173,6 +191,10 @@ shaka.test.FakeVideo = class {
|
|
|
173
191
|
jasmine.createSpy('addTextTrack').and.callFake((kind, id) => {
|
|
174
192
|
const track = new shaka.test.FakeTextTrack();
|
|
175
193
|
this.textTracks.push(track);
|
|
194
|
+
|
|
195
|
+
const trackEvent = new shaka.util.FakeEvent('addtrack', {track});
|
|
196
|
+
this.textTracksEventTarget.dispatchEvent(trackEvent);
|
|
197
|
+
|
|
176
198
|
return track;
|
|
177
199
|
});
|
|
178
200
|
|
|
@@ -308,11 +330,18 @@ shaka.test.FakePlayhead = class {
|
|
|
308
330
|
/** @type {!jasmine.Spy} */
|
|
309
331
|
this.setRebufferingGoal = jasmine.createSpy('setRebufferingGoal');
|
|
310
332
|
|
|
333
|
+
/** @private {number} */
|
|
334
|
+
this.startTime_ = 0;
|
|
335
|
+
|
|
311
336
|
/** @type {!jasmine.Spy} */
|
|
312
|
-
this.setStartTime = jasmine.createSpy('setStartTime')
|
|
337
|
+
this.setStartTime = jasmine.createSpy('setStartTime')
|
|
338
|
+
.and.callFake((value) => {
|
|
339
|
+
this.startTime_ = value;
|
|
340
|
+
});
|
|
313
341
|
|
|
314
342
|
/** @type {!jasmine.Spy} */
|
|
315
|
-
this.getTime = jasmine.createSpy('getTime')
|
|
343
|
+
this.getTime = jasmine.createSpy('getTime')
|
|
344
|
+
.and.callFake(() => this.startTime_);
|
|
316
345
|
|
|
317
346
|
/** @type {!jasmine.Spy} */
|
|
318
347
|
this.setBuffering = jasmine.createSpy('setBuffering');
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
describe('MimeUtils', () => {
|
|
8
|
+
const getNormalizedCodec = (codecs) =>
|
|
9
|
+
shaka.util.MimeUtils.getNormalizedCodec(codecs);
|
|
10
|
+
|
|
11
|
+
it('normalizes codecs', () => {
|
|
12
|
+
expect(getNormalizedCodec('mp4a.66')).toBe('aac');
|
|
13
|
+
expect(getNormalizedCodec('mp4a.67')).toBe('aac');
|
|
14
|
+
expect(getNormalizedCodec('mp4a.68')).toBe('aac');
|
|
15
|
+
|
|
16
|
+
expect(getNormalizedCodec('mp3')).toBe('mp3');
|
|
17
|
+
expect(getNormalizedCodec('mp4a.69')).toBe('mp3');
|
|
18
|
+
expect(getNormalizedCodec('mp4a.6B')).toBe('mp3');
|
|
19
|
+
expect(getNormalizedCodec('mp4a.6b')).toBe('mp3');
|
|
20
|
+
|
|
21
|
+
expect(getNormalizedCodec('mp4a.40.2')).toBe('aac');
|
|
22
|
+
expect(getNormalizedCodec('mp4a.40.02')).toBe('aac');
|
|
23
|
+
expect(getNormalizedCodec('mp4a.40.5')).toBe('aac');
|
|
24
|
+
expect(getNormalizedCodec('mp4a.40.05')).toBe('aac');
|
|
25
|
+
expect(getNormalizedCodec('mp4a.40.29')).toBe('aac');
|
|
26
|
+
expect(getNormalizedCodec('mp4a.40.42')).toBe('aac');
|
|
27
|
+
|
|
28
|
+
expect(getNormalizedCodec('ac-3')).toBe('ac-3');
|
|
29
|
+
expect(getNormalizedCodec('mp4a.a5')).toBe('ac-3');
|
|
30
|
+
expect(getNormalizedCodec('mp4a.A5')).toBe('ac-3');
|
|
31
|
+
|
|
32
|
+
expect(getNormalizedCodec('ec-3')).toBe('ec-3');
|
|
33
|
+
expect(getNormalizedCodec('mp4a.a6')).toBe('ec-3');
|
|
34
|
+
expect(getNormalizedCodec('mp4a.A6')).toBe('ec-3');
|
|
35
|
+
|
|
36
|
+
expect(getNormalizedCodec('dtsc')).toBe('dtsc');
|
|
37
|
+
expect(getNormalizedCodec('mp4a.a9')).toBe('dtsc');
|
|
38
|
+
|
|
39
|
+
expect(getNormalizedCodec('dtsx')).toBe('dtsx');
|
|
40
|
+
expect(getNormalizedCodec('mp4a.b2')).toBe('dtsx');
|
|
41
|
+
|
|
42
|
+
expect(getNormalizedCodec('vp8')).toBe('vp8');
|
|
43
|
+
expect(getNormalizedCodec('vp8.0')).toBe('vp8');
|
|
44
|
+
|
|
45
|
+
expect(getNormalizedCodec('avc1')).toBe('avc');
|
|
46
|
+
expect(getNormalizedCodec('avc3')).toBe('avc');
|
|
47
|
+
|
|
48
|
+
expect(getNormalizedCodec('hvc1')).toBe('hevc');
|
|
49
|
+
expect(getNormalizedCodec('hev1')).toBe('hevc');
|
|
50
|
+
|
|
51
|
+
expect(getNormalizedCodec('dvh1.05')).toBe('dovi');
|
|
52
|
+
expect(getNormalizedCodec('dvhe.05')).toBe('dovi');
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -996,6 +996,85 @@ describe('PeriodCombiner', () => {
|
|
|
996
996
|
expect(audio2.originalId).toBe('2,4');
|
|
997
997
|
});
|
|
998
998
|
|
|
999
|
+
it('Matches streams with related codecs', async () => {
|
|
1000
|
+
const stream1 = makeVideoStream(1080);
|
|
1001
|
+
stream1.originalId = '1';
|
|
1002
|
+
stream1.bandwidth = 120000;
|
|
1003
|
+
stream1.codecs = 'hvc1.1.4.L126.B0';
|
|
1004
|
+
|
|
1005
|
+
const stream2 = makeVideoStream(1080);
|
|
1006
|
+
stream2.originalId = '2';
|
|
1007
|
+
stream2.bandwidth = 120000;
|
|
1008
|
+
stream2.codecs = 'hev1.2.4.L123.B0';
|
|
1009
|
+
|
|
1010
|
+
const stream3 = makeVideoStream(1080);
|
|
1011
|
+
stream3.originalId = '3';
|
|
1012
|
+
stream3.bandwidth = 120000;
|
|
1013
|
+
stream3.codecs = 'dvhe.05.01';
|
|
1014
|
+
|
|
1015
|
+
const stream4 = makeVideoStream(1080);
|
|
1016
|
+
stream4.originalId = '4';
|
|
1017
|
+
stream4.bandwidth = 120000;
|
|
1018
|
+
stream4.codecs = 'dvh1.05.01';
|
|
1019
|
+
|
|
1020
|
+
const stream5 = makeVideoStream(1080);
|
|
1021
|
+
stream5.originalId = '5';
|
|
1022
|
+
stream5.bandwidth = 120000;
|
|
1023
|
+
stream5.codecs = 'avc1.42001f';
|
|
1024
|
+
|
|
1025
|
+
const stream6 = makeVideoStream(1080);
|
|
1026
|
+
stream6.originalId = '6';
|
|
1027
|
+
stream6.bandwidth = 120000;
|
|
1028
|
+
stream6.codecs = 'avc3.42001f';
|
|
1029
|
+
|
|
1030
|
+
const stream7 = makeVideoStream(1080);
|
|
1031
|
+
stream7.originalId = '7';
|
|
1032
|
+
stream7.bandwidth = 120000;
|
|
1033
|
+
stream7.codecs = 'vp09.00.10.08';
|
|
1034
|
+
|
|
1035
|
+
const stream8 = makeVideoStream(1080);
|
|
1036
|
+
stream8.originalId = '8';
|
|
1037
|
+
stream8.bandwidth = 120000;
|
|
1038
|
+
stream8.codecs = 'vp09.01.20.08.01';
|
|
1039
|
+
|
|
1040
|
+
/** @type {!Array.<shaka.util.PeriodCombiner.Period>} */
|
|
1041
|
+
const periods = [
|
|
1042
|
+
{
|
|
1043
|
+
id: '0',
|
|
1044
|
+
videoStreams: [
|
|
1045
|
+
stream1, stream3, stream5, stream7,
|
|
1046
|
+
],
|
|
1047
|
+
audioStreams: [],
|
|
1048
|
+
textStreams: [],
|
|
1049
|
+
imageStreams: [],
|
|
1050
|
+
},
|
|
1051
|
+
{
|
|
1052
|
+
id: '1',
|
|
1053
|
+
videoStreams: [
|
|
1054
|
+
stream2, stream4, stream6, stream8,
|
|
1055
|
+
],
|
|
1056
|
+
audioStreams: [],
|
|
1057
|
+
textStreams: [],
|
|
1058
|
+
imageStreams: [],
|
|
1059
|
+
},
|
|
1060
|
+
];
|
|
1061
|
+
|
|
1062
|
+
await combiner.combinePeriods(periods, /* isDynamic= */ true);
|
|
1063
|
+
const variants = combiner.getVariants();
|
|
1064
|
+
expect(variants.length).toBe(4);
|
|
1065
|
+
// We can use the originalId field to see what each track is composed of.
|
|
1066
|
+
const video1 = variants[0].video;
|
|
1067
|
+
expect(video1.originalId).toBe('1,2');
|
|
1068
|
+
|
|
1069
|
+
const video2 = variants[1].video;
|
|
1070
|
+
expect(video2.originalId).toBe('3,4');
|
|
1071
|
+
|
|
1072
|
+
const video3 = variants[2].video;
|
|
1073
|
+
expect(video3.originalId).toBe('5,6');
|
|
1074
|
+
|
|
1075
|
+
const video4 = variants[3].video;
|
|
1076
|
+
expect(video4.originalId).toBe('7,8');
|
|
1077
|
+
});
|
|
999
1078
|
|
|
1000
1079
|
it('Matches streams with most roles in common', async () => {
|
|
1001
1080
|
const makeAudioStreamWithRoles = (roles) => {
|
package/lib/util/mutex.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/*! @license
|
|
2
|
-
* Shaka Player
|
|
3
|
-
* Copyright 2016 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
goog.provide('shaka.util.Mutex');
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @summary A simple mutex.
|
|
12
|
-
*/
|
|
13
|
-
shaka.util.Mutex = class {
|
|
14
|
-
/** Creates the mutex. */
|
|
15
|
-
constructor() {
|
|
16
|
-
/** @private {!Array.<function()>} */
|
|
17
|
-
this.waiting_ = [];
|
|
18
|
-
|
|
19
|
-
/** @private {number} */
|
|
20
|
-
this.nextMutexId_ = 0;
|
|
21
|
-
|
|
22
|
-
/** @private {number} */
|
|
23
|
-
this.acquiredMutexId_ = 0;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/** @return {!Promise.<number>} mutexId */
|
|
27
|
-
async acquire() {
|
|
28
|
-
const mutexId = ++this.nextMutexId_;
|
|
29
|
-
if (!this.acquiredMutexId_) {
|
|
30
|
-
this.acquiredMutexId_ = mutexId;
|
|
31
|
-
} else {
|
|
32
|
-
await (new Promise((resolve, reject) => {
|
|
33
|
-
this.waiting_.push(() => {
|
|
34
|
-
this.acquiredMutexId_ = mutexId;
|
|
35
|
-
resolve();
|
|
36
|
-
});
|
|
37
|
-
}));
|
|
38
|
-
}
|
|
39
|
-
return mutexId;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/** @param {number} mutexId */
|
|
43
|
-
release(mutexId) {
|
|
44
|
-
if (mutexId == this.acquiredMutexId_) {
|
|
45
|
-
this.acquiredMutexId_ = 0;
|
|
46
|
-
if (this.waiting_.length > 0) {
|
|
47
|
-
const callback = this.waiting_.shift();
|
|
48
|
-
callback();
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
};
|