shaka-player 3.2.1 → 3.2.2
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/AUTHORS +3 -0
- package/CHANGELOG.md +57 -0
- package/CONTRIBUTORS +3 -0
- package/build/generateExterns.js +1 -1
- package/demo/common/assets.js +1 -1
- package/demo/index.html +1 -1
- package/dist/controls.css +2 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +1 -1
- package/dist/demo.compiled.js +1 -1
- package/dist/deps.js +1 -1
- package/dist/locales.js +37 -37
- package/dist/receiver.compiled.debug.js +1 -1
- package/dist/receiver.compiled.js +1 -1
- package/dist/shaka-player.compiled.d.ts +1 -1
- package/dist/shaka-player.compiled.debug.d.ts +1 -1
- package/dist/shaka-player.compiled.debug.externs.js +1 -1
- package/dist/shaka-player.compiled.debug.js +188 -181
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.externs.js +1 -1
- package/dist/shaka-player.compiled.js +795 -790
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.d.ts +1 -1
- package/dist/shaka-player.ui.debug.d.ts +1 -1
- package/dist/shaka-player.ui.debug.externs.js +3 -3
- package/dist/shaka-player.ui.debug.js +217 -210
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +3 -3
- package/dist/shaka-player.ui.js +945 -940
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/fairplay.md +1 -1
- package/docs/tutorials/ui.md +5 -5
- package/karma.conf.js +1 -0
- package/lib/ads/client_side_ad_manager.js +46 -86
- package/lib/ads/server_side_ad_manager.js +7 -10
- package/lib/cast/cast_proxy.js +3 -2
- package/lib/cast/cast_receiver.js +2 -1
- package/lib/cast/cast_sender.js +2 -2
- package/lib/dash/dash_parser.js +93 -2
- package/lib/dash/segment_list.js +1 -1
- package/lib/dash/segment_template.js +1 -1
- package/lib/hls/hls_parser.js +30 -17
- package/lib/media/drm_engine.js +7 -0
- package/lib/media/gap_jumping_controller.js +4 -2
- package/lib/media/media_source_engine.js +1 -2
- package/lib/media/streaming_engine.js +2 -1
- package/lib/net/networking_engine.js +2 -1
- package/lib/player.js +26 -25
- package/lib/polyfill/media_capabilities.js +7 -1
- package/lib/polyfill/mediasource.js +6 -0
- package/lib/polyfill/orientation.js +1 -1
- package/lib/polyfill/patchedmediakeys_apple.js +4 -4
- package/lib/polyfill/patchedmediakeys_ms.js +4 -4
- package/lib/polyfill/patchedmediakeys_webkit.js +4 -4
- package/lib/text/mp4_ttml_parser.js +3 -0
- package/lib/text/text_engine.js +14 -2
- package/lib/text/ttml_text_parser.js +5 -0
- package/lib/text/ui_text_displayer.js +85 -37
- package/lib/util/fake_event.js +53 -7
- package/lib/util/periods.js +4 -1
- package/lib/util/platform.js +13 -1
- package/lib/util/stream_utils.js +13 -0
- package/package.json +1 -1
- package/test/cast/cast_proxy_unit.js +12 -6
- package/test/cast/cast_utils_unit.js +1 -1
- package/test/dash/dash_parser_manifest_unit.js +187 -1
- package/test/hls/hls_parser_unit.js +5 -1
- package/test/media/closed_caption_parser_unit.js +6 -1
- package/test/media/drm_engine_unit.js +44 -0
- package/test/player_integration.js +38 -0
- package/test/test/assets/3675/chunk-stream0-00001.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00002.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00003.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00004.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00005.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00006.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00007.m4s +0 -0
- package/test/test/assets/3675/dash_0.mpd +30 -0
- package/test/test/assets/3675/dash_1.mpd +30 -0
- package/test/test/assets/3675/dash_2.mpd +30 -0
- package/test/test/assets/3675/dash_3.mpd +30 -0
- package/test/test/assets/3675/dash_4.mpd +30 -0
- package/test/test/assets/3675/dash_5.mpd +26 -0
- package/test/test/assets/3675/init-stream0.m4s +0 -0
- package/test/test/util/fake_ad_manager.js +1 -1
- package/test/text/ttml_text_parser_unit.js +9 -0
- package/test/text/ui_text_displayer_unit.js +29 -17
- package/test/ui/localization_unit.js +15 -14
- package/test/ui/text_displayer_layout_unit.js +13 -1
- package/test/util/stream_utils_unit.js +35 -0
- package/ui/cast_button.js +2 -3
- package/ui/controls.js +4 -6
- package/ui/less/containers.less +3 -7
- package/ui/locales/ru.json +6 -6
- package/ui/localization.js +28 -51
- package/ui/pip_button.js +2 -3
|
@@ -38,6 +38,14 @@ describe('DashParser Manifest', () => {
|
|
|
38
38
|
|
|
39
39
|
/** @type {string} */
|
|
40
40
|
const thumbnailScheme = 'http://dashif.org/guidelines/thumbnail_tile';
|
|
41
|
+
/**
|
|
42
|
+
* CICP scheme. parameter must be one of the following: "ColourPrimaries",
|
|
43
|
+
* "TransferCharacteristics", or "MatrixCoefficients".
|
|
44
|
+
*
|
|
45
|
+
* @param {string} parameter
|
|
46
|
+
* @return {string}
|
|
47
|
+
*/
|
|
48
|
+
const cicpScheme = (parameter) => `urn:mpeg:mpegB:cicp:${parameter}`;
|
|
41
49
|
|
|
42
50
|
beforeAll(async () => {
|
|
43
51
|
mp4Index = await shaka.test.Util.fetch(mp4IndexSegmentUri);
|
|
@@ -1896,7 +1904,8 @@ describe('DashParser Manifest', () => {
|
|
|
1896
1904
|
expect(textStream.forced).toBe(true);
|
|
1897
1905
|
});
|
|
1898
1906
|
|
|
1899
|
-
it('supports HDR signaling', async () => {
|
|
1907
|
+
it('supports HDR signaling via profiles', async () => {
|
|
1908
|
+
// (DASH-IF IOP v4.3 10.3.3.)
|
|
1900
1909
|
const hdrProfile =
|
|
1901
1910
|
'http://dashif.org/guidelines/dash-if-uhd#hevc-hdr-pq10';
|
|
1902
1911
|
const manifestText = [
|
|
@@ -1927,6 +1936,110 @@ describe('DashParser Manifest', () => {
|
|
|
1927
1936
|
expect(stream.hdr).toBe('PQ');
|
|
1928
1937
|
});
|
|
1929
1938
|
|
|
1939
|
+
it('supports HDR signaling via SupplementalProperty', async () => {
|
|
1940
|
+
// (DASH-IF IOP v4.3 6.2.5.1.)
|
|
1941
|
+
const hdrScheme = cicpScheme('TransferCharacteristics');
|
|
1942
|
+
const pq = 16;
|
|
1943
|
+
const manifestText = [
|
|
1944
|
+
'<MPD minBufferTime="PT75S">',
|
|
1945
|
+
' <Period id="1" duration="PT30S">',
|
|
1946
|
+
' <AdaptationSet id="2" mimeType="video/mp4">',
|
|
1947
|
+
` <SupplementalProperty schemeIdUri="${hdrScheme}" value="${pq}" />`,
|
|
1948
|
+
' <Representation codecs="hvc1.2.4.L150.90">',
|
|
1949
|
+
' <BaseURL>v-sd.mp4</BaseURL>',
|
|
1950
|
+
' <SegmentBase indexRange="100-200" />',
|
|
1951
|
+
' </Representation>',
|
|
1952
|
+
' </AdaptationSet>',
|
|
1953
|
+
' <AdaptationSet id="3" mimeType="audio/mp4">',
|
|
1954
|
+
' <Representation id="audio-en">',
|
|
1955
|
+
' <BaseURL>a-en.mp4</BaseURL>',
|
|
1956
|
+
' <SegmentBase indexRange="100-200" />',
|
|
1957
|
+
' </Representation>',
|
|
1958
|
+
' </AdaptationSet>',
|
|
1959
|
+
' </Period>',
|
|
1960
|
+
'</MPD>',
|
|
1961
|
+
].join('\n');
|
|
1962
|
+
|
|
1963
|
+
fakeNetEngine.setResponseText('dummy://foo', manifestText);
|
|
1964
|
+
|
|
1965
|
+
/** @type {shaka.extern.Manifest} */
|
|
1966
|
+
const manifest = await parser.start('dummy://foo', playerInterface);
|
|
1967
|
+
expect(manifest.variants.length).toBe(1);
|
|
1968
|
+
const stream = manifest.variants[0].video;
|
|
1969
|
+
expect(stream.hdr).toBe('PQ');
|
|
1970
|
+
});
|
|
1971
|
+
|
|
1972
|
+
it('supports HDR signaling via EssentialProperty', async () => {
|
|
1973
|
+
// (DASH-IF IOP v4.3 6.2.5.1.)
|
|
1974
|
+
const hdrScheme = cicpScheme('TransferCharacteristics');
|
|
1975
|
+
const hlg = 18;
|
|
1976
|
+
const manifestText = [
|
|
1977
|
+
'<MPD minBufferTime="PT75S">',
|
|
1978
|
+
' <Period id="1" duration="PT30S">',
|
|
1979
|
+
' <AdaptationSet id="2" mimeType="video/mp4">',
|
|
1980
|
+
` <EssentialProperty schemeIdUri="${hdrScheme}" value="${hlg}" />`,
|
|
1981
|
+
' <Representation codecs="hvc1.2.4.L153.B0">',
|
|
1982
|
+
' <BaseURL>v-sd.mp4</BaseURL>',
|
|
1983
|
+
' <SegmentBase indexRange="100-200" />',
|
|
1984
|
+
' </Representation>',
|
|
1985
|
+
' </AdaptationSet>',
|
|
1986
|
+
' <AdaptationSet id="3" mimeType="audio/mp4">',
|
|
1987
|
+
' <Representation id="audio-en">',
|
|
1988
|
+
' <BaseURL>a-en.mp4</BaseURL>',
|
|
1989
|
+
' <SegmentBase indexRange="100-200" />',
|
|
1990
|
+
' </Representation>',
|
|
1991
|
+
' </AdaptationSet>',
|
|
1992
|
+
' </Period>',
|
|
1993
|
+
'</MPD>',
|
|
1994
|
+
].join('\n');
|
|
1995
|
+
|
|
1996
|
+
fakeNetEngine.setResponseText('dummy://foo', manifestText);
|
|
1997
|
+
|
|
1998
|
+
/** @type {shaka.extern.Manifest} */
|
|
1999
|
+
const manifest = await parser.start('dummy://foo', playerInterface);
|
|
2000
|
+
expect(manifest.variants.length).toBe(1);
|
|
2001
|
+
const stream = manifest.variants[0].video;
|
|
2002
|
+
expect(stream.hdr).toBe('HLG');
|
|
2003
|
+
});
|
|
2004
|
+
|
|
2005
|
+
it('supports SDR signalling via EssentialProperty', async () => {
|
|
2006
|
+
// (DASH-IF IOP v4.3 6.2.5.1.)
|
|
2007
|
+
const scheme = cicpScheme('TransferCharacteristics');
|
|
2008
|
+
const sdrValues = [1, 6, 13, 14, 15];
|
|
2009
|
+
const manifestPromises = [];
|
|
2010
|
+
for (const value of sdrValues) {
|
|
2011
|
+
const manifestText = [
|
|
2012
|
+
'<MPD minBufferTime="PT75S">',
|
|
2013
|
+
' <Period id="1" duration="PT30S">',
|
|
2014
|
+
' <AdaptationSet id="2" mimeType="video/mp4">',
|
|
2015
|
+
` <EssentialProperty schemeIdUri="${scheme}" value="${value}" />`,
|
|
2016
|
+
' <Representation codecs="avc1.640028">',
|
|
2017
|
+
' <BaseURL>v-sd.mp4</BaseURL>',
|
|
2018
|
+
' <SegmentBase indexRange="100-200" />',
|
|
2019
|
+
' </Representation>',
|
|
2020
|
+
' </AdaptationSet>',
|
|
2021
|
+
' <AdaptationSet id="3" mimeType="audio/mp4">',
|
|
2022
|
+
' <Representation id="audio-en">',
|
|
2023
|
+
' <BaseURL>a-en.mp4</BaseURL>',
|
|
2024
|
+
' <SegmentBase indexRange="100-200" />',
|
|
2025
|
+
' </Representation>',
|
|
2026
|
+
' </AdaptationSet>',
|
|
2027
|
+
' </Period>',
|
|
2028
|
+
'</MPD>',
|
|
2029
|
+
].join('\n');
|
|
2030
|
+
|
|
2031
|
+
fakeNetEngine.setResponseText('dummy://foo', manifestText);
|
|
2032
|
+
|
|
2033
|
+
manifestPromises.push(parser.start('dummy://foo', playerInterface));
|
|
2034
|
+
}
|
|
2035
|
+
const manifests = await Promise.all(manifestPromises);
|
|
2036
|
+
for (const manifest of manifests) {
|
|
2037
|
+
expect(manifest.variants.length).toBe(1);
|
|
2038
|
+
const stream = manifest.variants[0].video;
|
|
2039
|
+
expect(stream.hdr).toBe('SDR');
|
|
2040
|
+
}
|
|
2041
|
+
});
|
|
2042
|
+
|
|
1930
2043
|
it('Does not error when image adaptation sets are present', async () => {
|
|
1931
2044
|
const manifestText = [
|
|
1932
2045
|
'<MPD minBufferTime="PT75S">',
|
|
@@ -2150,4 +2263,77 @@ describe('DashParser Manifest', () => {
|
|
|
2150
2263
|
expect(uri).not.toContain('/p2/');
|
|
2151
2264
|
}
|
|
2152
2265
|
});
|
|
2266
|
+
|
|
2267
|
+
/**
|
|
2268
|
+
* @param {!Array.<number>} periods Start time of multiple periods
|
|
2269
|
+
* @return {string}
|
|
2270
|
+
*/
|
|
2271
|
+
function buildManifestWithPeriodStartTime(periods) {
|
|
2272
|
+
const mpdTemplate = [
|
|
2273
|
+
`<MPD type="dynamic"`,
|
|
2274
|
+
'availabilityStartTime="1970-01-01T00:00:00Z"',
|
|
2275
|
+
'timeShiftBufferDepth="PT10H">',
|
|
2276
|
+
' %(periods)s',
|
|
2277
|
+
'</MPD>',
|
|
2278
|
+
].join('\n');
|
|
2279
|
+
const periodTemplate = (id, period, duration) => {
|
|
2280
|
+
return [
|
|
2281
|
+
` <Period id="${id}" start="PT${period}S">`,
|
|
2282
|
+
' <AdaptationSet mimeType="video/mp4" lang="en" group="1">',
|
|
2283
|
+
' <SegmentTemplate startNumber="1" media="l-$Number$.mp4">',
|
|
2284
|
+
' <SegmentTimeline>',
|
|
2285
|
+
` <S t="0" d="${duration}" />`,
|
|
2286
|
+
' </SegmentTimeline>',
|
|
2287
|
+
' </SegmentTemplate>',
|
|
2288
|
+
' <Representation id="1"/>',
|
|
2289
|
+
' </AdaptationSet>',
|
|
2290
|
+
' </Period>',
|
|
2291
|
+
].join('\n');
|
|
2292
|
+
};
|
|
2293
|
+
const periodXmls = periods.map((period, i) => {
|
|
2294
|
+
const duration = i+1 === periods.length ? 10 : periods[i+1] - period;
|
|
2295
|
+
// Period start time as ID here. If we use index then there will be
|
|
2296
|
+
// periods with same period ID and different start time which are invalid.
|
|
2297
|
+
return periodTemplate(period, period, duration);
|
|
2298
|
+
});
|
|
2299
|
+
return sprintf(mpdTemplate, {
|
|
2300
|
+
periods: periodXmls.join('\n'),
|
|
2301
|
+
});
|
|
2302
|
+
}
|
|
2303
|
+
|
|
2304
|
+
// Bug description: Inconsistent period start time in the manifests due
|
|
2305
|
+
// to failover triggered in backend servers
|
|
2306
|
+
|
|
2307
|
+
// When one of the servers is down, the manifest will be served by other
|
|
2308
|
+
// redundant servers. The period start time might become out of sync
|
|
2309
|
+
// during the switch-over/recovery.
|
|
2310
|
+
|
|
2311
|
+
it('skip periods that are earlier than max period start time', async () => {
|
|
2312
|
+
const sources = [
|
|
2313
|
+
buildManifestWithPeriodStartTime([5, 15]),
|
|
2314
|
+
buildManifestWithPeriodStartTime([6, 15]), // simulate out-of-sync of +1s
|
|
2315
|
+
buildManifestWithPeriodStartTime([4, 15]), // simulate out-of-sync of -1s
|
|
2316
|
+
];
|
|
2317
|
+
const segments = [];
|
|
2318
|
+
|
|
2319
|
+
for (const source of sources) {
|
|
2320
|
+
fakeNetEngine.setResponseText('dummy://foo', source);
|
|
2321
|
+
/** @type {shaka.extern.Manifest} */
|
|
2322
|
+
// eslint-disable-next-line no-await-in-loop
|
|
2323
|
+
const manifest = await parser.start('dummy://foo', playerInterface);
|
|
2324
|
+
const video = manifest.variants[0].video;
|
|
2325
|
+
// eslint-disable-next-line no-await-in-loop
|
|
2326
|
+
await video.createSegmentIndex();
|
|
2327
|
+
goog.asserts.assert(video.segmentIndex, 'Null segmentIndex!');
|
|
2328
|
+
segments.push(Array.from(video.segmentIndex));
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
// Expect identical segments
|
|
2332
|
+
expect(segments[0].length).toBe(2);
|
|
2333
|
+
expect(segments[1].length).toBe(2);
|
|
2334
|
+
expect(segments[0][0].startTime).toBe(5);
|
|
2335
|
+
expect(segments[1][0].startTime).toBe(5);
|
|
2336
|
+
expect(segments[0][1].startTime).toBe(15);
|
|
2337
|
+
expect(segments[1][1].startTime).toBe(15);
|
|
2338
|
+
});
|
|
2153
2339
|
});
|
|
@@ -783,7 +783,7 @@ describe('HlsParser', () => {
|
|
|
783
783
|
'RESOLUTION=960x540,FRAME-RATE=120,AUDIO="aud2"\n',
|
|
784
784
|
'video2\n',
|
|
785
785
|
'#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aud1",LANGUAGE="eng",',
|
|
786
|
-
'URI="audio"\n',
|
|
786
|
+
'DEFAULT=YES,URI="audio"\n',
|
|
787
787
|
'#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aud2",LANGUAGE="fr",',
|
|
788
788
|
'URI="audio2"\n',
|
|
789
789
|
].join('');
|
|
@@ -801,6 +801,7 @@ describe('HlsParser', () => {
|
|
|
801
801
|
manifest.anyTimeline();
|
|
802
802
|
manifest.addPartialVariant((variant) => {
|
|
803
803
|
variant.bandwidth = 200;
|
|
804
|
+
variant.primary = true;
|
|
804
805
|
variant.addPartialStream(ContentType.VIDEO, (stream) => {
|
|
805
806
|
stream.size(960, 540);
|
|
806
807
|
});
|
|
@@ -810,6 +811,7 @@ describe('HlsParser', () => {
|
|
|
810
811
|
});
|
|
811
812
|
manifest.addPartialVariant((variant) => {
|
|
812
813
|
variant.bandwidth = 300;
|
|
814
|
+
variant.primary = false;
|
|
813
815
|
variant.addPartialStream(ContentType.VIDEO, (stream) => {
|
|
814
816
|
stream.size(960, 540);
|
|
815
817
|
});
|
|
@@ -1307,6 +1309,8 @@ describe('HlsParser', () => {
|
|
|
1307
1309
|
// stream.
|
|
1308
1310
|
const timeline = actual.presentationTimeline;
|
|
1309
1311
|
expect(timeline.getDuration()).toBe(10);
|
|
1312
|
+
expect(timeline.getSeekRangeStart()).toBe(0);
|
|
1313
|
+
expect(timeline.getSeekRangeEnd()).toBe(10);
|
|
1310
1314
|
|
|
1311
1315
|
expect(actual.textStreams.length).toBe(1);
|
|
1312
1316
|
expect(actual.variants.length).toBe(1);
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
goog.require('shaka.media.ClosedCaptionParser');
|
|
2
8
|
goog.require('shaka.test.Util');
|
|
3
9
|
|
|
@@ -12,4 +18,3 @@ describe('ClosedCaptionParser', () => {
|
|
|
12
18
|
parser.parseFrom(videoSegment);
|
|
13
19
|
});
|
|
14
20
|
});
|
|
15
|
-
|
|
@@ -2152,6 +2152,50 @@ describe('DrmEngine', () => {
|
|
|
2152
2152
|
[drmInfoAudio]);
|
|
2153
2153
|
expect(returned).toEqual([drmInfoDesired]);
|
|
2154
2154
|
});
|
|
2155
|
+
|
|
2156
|
+
it('dedupes the merged init data based on keyId matching', () => {
|
|
2157
|
+
const serverCert = new Uint8Array(0);
|
|
2158
|
+
const drmInfoVideo = {
|
|
2159
|
+
keySystem: 'drm.abc',
|
|
2160
|
+
licenseServerUri: 'http://abc.drm/license',
|
|
2161
|
+
distinctiveIdentifierRequired: false,
|
|
2162
|
+
persistentStateRequired: true,
|
|
2163
|
+
videoRobustness: 'really_really_ridiculously_good',
|
|
2164
|
+
serverCertificate: serverCert,
|
|
2165
|
+
serverCertificateUri: '',
|
|
2166
|
+
initData: [{keyId: 'v-init'}],
|
|
2167
|
+
keyIds: new Set(['deadbeefdeadbeefdeadbeefdeadbeef']),
|
|
2168
|
+
};
|
|
2169
|
+
const drmInfoAudio = {
|
|
2170
|
+
keySystem: 'drm.abc',
|
|
2171
|
+
licenseServerUri: undefined,
|
|
2172
|
+
distinctiveIdentifierRequired: true,
|
|
2173
|
+
persistentStateRequired: false,
|
|
2174
|
+
audioRobustness: 'good',
|
|
2175
|
+
serverCertificate: undefined,
|
|
2176
|
+
serverCertificateUri: '',
|
|
2177
|
+
initData: [{keyId: 'v-init'}, {keyId: 'a-init'}],
|
|
2178
|
+
keyIds: new Set(['eadbeefdeadbeefdeadbeefdeadbeefd']),
|
|
2179
|
+
};
|
|
2180
|
+
const drmInfoDesired = {
|
|
2181
|
+
keySystem: 'drm.abc',
|
|
2182
|
+
licenseServerUri: 'http://abc.drm/license',
|
|
2183
|
+
distinctiveIdentifierRequired: true,
|
|
2184
|
+
persistentStateRequired: true,
|
|
2185
|
+
audioRobustness: 'good',
|
|
2186
|
+
videoRobustness: 'really_really_ridiculously_good',
|
|
2187
|
+
serverCertificate: serverCert,
|
|
2188
|
+
serverCertificateUri: '',
|
|
2189
|
+
initData: [{keyId: 'v-init'}, {keyId: 'a-init'}],
|
|
2190
|
+
keyIds: new Set([
|
|
2191
|
+
'deadbeefdeadbeefdeadbeefdeadbeef',
|
|
2192
|
+
'eadbeefdeadbeefdeadbeefdeadbeefd',
|
|
2193
|
+
]),
|
|
2194
|
+
};
|
|
2195
|
+
const returned = shaka.media.DrmEngine.getCommonDrmInfos([drmInfoVideo],
|
|
2196
|
+
[drmInfoAudio]);
|
|
2197
|
+
expect(returned).toEqual([drmInfoDesired]);
|
|
2198
|
+
});
|
|
2155
2199
|
}); // describe('getCommonDrmInfos')
|
|
2156
2200
|
|
|
2157
2201
|
describe('configure', () => {
|
|
@@ -652,6 +652,44 @@ describe('Player', () => {
|
|
|
652
652
|
});
|
|
653
653
|
});
|
|
654
654
|
|
|
655
|
+
describe('seek range', () => {
|
|
656
|
+
// Regression test for Issue #3675.
|
|
657
|
+
it('has a reasonable seek range after going from live to VOD', async () => {
|
|
658
|
+
const netEngine = player.getNetworkingEngine();
|
|
659
|
+
const startTime = Date.now();
|
|
660
|
+
netEngine.registerRequestFilter((type, request) => {
|
|
661
|
+
if (type != shaka.net.NetworkingEngine.RequestType.MANIFEST) {
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
// Simulate a live stream by providing different manifests over time.
|
|
665
|
+
const time = (Date.now() - startTime) / 1000;
|
|
666
|
+
const manifestNumber = Math.min(5, Math.floor(0.5 + time / 2));
|
|
667
|
+
request.uris = [
|
|
668
|
+
'/base/test/test/assets/3675/dash_' + manifestNumber + '.mpd',
|
|
669
|
+
];
|
|
670
|
+
console.log('getting manifest', request.uris);
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
// Play the stream.
|
|
674
|
+
await player.load('/base/test/test/assets/3675/dash_0.mpd');
|
|
675
|
+
video.play();
|
|
676
|
+
|
|
677
|
+
// Wait for the stream to be over.
|
|
678
|
+
eventManager.listen(player, 'error', Util.spyFunc(onErrorSpy));
|
|
679
|
+
/** @type {shaka.test.Waiter} */
|
|
680
|
+
const waiter = new shaka.test.Waiter(eventManager)
|
|
681
|
+
.timeoutAfter(20).failOnTimeout(true);
|
|
682
|
+
await waiter.waitForEnd(video);
|
|
683
|
+
|
|
684
|
+
// The stream should have transitioned to VOD by now.
|
|
685
|
+
expect(player.isLive()).toBe(false);
|
|
686
|
+
|
|
687
|
+
// Check that the final seek range is as expected.
|
|
688
|
+
const seekRange = player.seekRange();
|
|
689
|
+
expect(seekRange.end).toBe(14);
|
|
690
|
+
});
|
|
691
|
+
});
|
|
692
|
+
|
|
655
693
|
describe('buffering', () => {
|
|
656
694
|
const startBuffering = jasmine.objectContaining({buffering: true});
|
|
657
695
|
const endBuffering = jasmine.objectContaining({buffering: false});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
3
|
+
xmlns="urn:mpeg:dash:schema:mpd:2011"
|
|
4
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
5
|
+
xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
|
|
6
|
+
profiles="urn:mpeg:dash:profile:isoff-live:2011"
|
|
7
|
+
type="dynamic"
|
|
8
|
+
minimumUpdatePeriod="PT2S"
|
|
9
|
+
suggestedPresentationDelay="PT2S"
|
|
10
|
+
availabilityStartTime="2021-10-28T07:36:27.755Z"
|
|
11
|
+
publishTime="2021-10-28T07:36:29.744Z"
|
|
12
|
+
timeShiftBufferDepth="PT10.0S"
|
|
13
|
+
maxSegmentDuration="PT2.0S"
|
|
14
|
+
minBufferTime="PT4.0S">
|
|
15
|
+
<ProgramInformation>
|
|
16
|
+
</ProgramInformation>
|
|
17
|
+
<ServiceDescription id="0">
|
|
18
|
+
</ServiceDescription>
|
|
19
|
+
<Period id="0" start="PT0.0S">
|
|
20
|
+
<AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
|
|
21
|
+
<Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
|
|
22
|
+
<SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
|
|
23
|
+
<SegmentTimeline>
|
|
24
|
+
<S t="0" d="30720" />
|
|
25
|
+
</SegmentTimeline>
|
|
26
|
+
</SegmentTemplate>
|
|
27
|
+
</Representation>
|
|
28
|
+
</AdaptationSet>
|
|
29
|
+
</Period>
|
|
30
|
+
</MPD>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
3
|
+
xmlns="urn:mpeg:dash:schema:mpd:2011"
|
|
4
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
5
|
+
xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
|
|
6
|
+
profiles="urn:mpeg:dash:profile:isoff-live:2011"
|
|
7
|
+
type="dynamic"
|
|
8
|
+
minimumUpdatePeriod="PT2S"
|
|
9
|
+
suggestedPresentationDelay="PT2S"
|
|
10
|
+
availabilityStartTime="2021-10-28T07:36:27.755Z"
|
|
11
|
+
publishTime="2021-10-28T07:36:31.750Z"
|
|
12
|
+
timeShiftBufferDepth="PT10.0S"
|
|
13
|
+
maxSegmentDuration="PT2.0S"
|
|
14
|
+
minBufferTime="PT4.0S">
|
|
15
|
+
<ProgramInformation>
|
|
16
|
+
</ProgramInformation>
|
|
17
|
+
<ServiceDescription id="0">
|
|
18
|
+
</ServiceDescription>
|
|
19
|
+
<Period id="0" start="PT0.0S">
|
|
20
|
+
<AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
|
|
21
|
+
<Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
|
|
22
|
+
<SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
|
|
23
|
+
<SegmentTimeline>
|
|
24
|
+
<S t="0" d="30720" r="1" />
|
|
25
|
+
</SegmentTimeline>
|
|
26
|
+
</SegmentTemplate>
|
|
27
|
+
</Representation>
|
|
28
|
+
</AdaptationSet>
|
|
29
|
+
</Period>
|
|
30
|
+
</MPD>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
3
|
+
xmlns="urn:mpeg:dash:schema:mpd:2011"
|
|
4
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
5
|
+
xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
|
|
6
|
+
profiles="urn:mpeg:dash:profile:isoff-live:2011"
|
|
7
|
+
type="dynamic"
|
|
8
|
+
minimumUpdatePeriod="PT2S"
|
|
9
|
+
suggestedPresentationDelay="PT2S"
|
|
10
|
+
availabilityStartTime="2021-10-28T07:36:27.755Z"
|
|
11
|
+
publishTime="2021-10-28T07:36:35.752Z"
|
|
12
|
+
timeShiftBufferDepth="PT10.0S"
|
|
13
|
+
maxSegmentDuration="PT2.0S"
|
|
14
|
+
minBufferTime="PT4.0S">
|
|
15
|
+
<ProgramInformation>
|
|
16
|
+
</ProgramInformation>
|
|
17
|
+
<ServiceDescription id="0">
|
|
18
|
+
</ServiceDescription>
|
|
19
|
+
<Period id="0" start="PT0.0S">
|
|
20
|
+
<AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
|
|
21
|
+
<Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
|
|
22
|
+
<SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
|
|
23
|
+
<SegmentTimeline>
|
|
24
|
+
<S t="0" d="30720" r="3" />
|
|
25
|
+
</SegmentTimeline>
|
|
26
|
+
</SegmentTemplate>
|
|
27
|
+
</Representation>
|
|
28
|
+
</AdaptationSet>
|
|
29
|
+
</Period>
|
|
30
|
+
</MPD>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
3
|
+
xmlns="urn:mpeg:dash:schema:mpd:2011"
|
|
4
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
5
|
+
xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
|
|
6
|
+
profiles="urn:mpeg:dash:profile:isoff-live:2011"
|
|
7
|
+
type="dynamic"
|
|
8
|
+
minimumUpdatePeriod="PT2S"
|
|
9
|
+
suggestedPresentationDelay="PT2S"
|
|
10
|
+
availabilityStartTime="2021-10-28T07:36:27.755Z"
|
|
11
|
+
publishTime="2021-10-28T07:36:37.752Z"
|
|
12
|
+
timeShiftBufferDepth="PT10.0S"
|
|
13
|
+
maxSegmentDuration="PT2.0S"
|
|
14
|
+
minBufferTime="PT4.0S">
|
|
15
|
+
<ProgramInformation>
|
|
16
|
+
</ProgramInformation>
|
|
17
|
+
<ServiceDescription id="0">
|
|
18
|
+
</ServiceDescription>
|
|
19
|
+
<Period id="0" start="PT0.0S">
|
|
20
|
+
<AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
|
|
21
|
+
<Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
|
|
22
|
+
<SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
|
|
23
|
+
<SegmentTimeline>
|
|
24
|
+
<S t="0" d="30720" r="4" />
|
|
25
|
+
</SegmentTimeline>
|
|
26
|
+
</SegmentTemplate>
|
|
27
|
+
</Representation>
|
|
28
|
+
</AdaptationSet>
|
|
29
|
+
</Period>
|
|
30
|
+
</MPD>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
3
|
+
xmlns="urn:mpeg:dash:schema:mpd:2011"
|
|
4
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
5
|
+
xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
|
|
6
|
+
profiles="urn:mpeg:dash:profile:isoff-live:2011"
|
|
7
|
+
type="dynamic"
|
|
8
|
+
minimumUpdatePeriod="PT2S"
|
|
9
|
+
suggestedPresentationDelay="PT2S"
|
|
10
|
+
availabilityStartTime="2021-10-28T07:36:27.755Z"
|
|
11
|
+
publishTime="2021-10-28T07:36:41.751Z"
|
|
12
|
+
timeShiftBufferDepth="PT10.0S"
|
|
13
|
+
maxSegmentDuration="PT2.0S"
|
|
14
|
+
minBufferTime="PT4.0S">
|
|
15
|
+
<ProgramInformation>
|
|
16
|
+
</ProgramInformation>
|
|
17
|
+
<ServiceDescription id="0">
|
|
18
|
+
</ServiceDescription>
|
|
19
|
+
<Period id="0" start="PT0.0S">
|
|
20
|
+
<AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
|
|
21
|
+
<Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
|
|
22
|
+
<SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="3">
|
|
23
|
+
<SegmentTimeline>
|
|
24
|
+
<S t="61440" d="30720" r="4" />
|
|
25
|
+
</SegmentTimeline>
|
|
26
|
+
</SegmentTemplate>
|
|
27
|
+
</Representation>
|
|
28
|
+
</AdaptationSet>
|
|
29
|
+
</Period>
|
|
30
|
+
</MPD>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
3
|
+
xmlns="urn:mpeg:dash:schema:mpd:2011"
|
|
4
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
5
|
+
xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
|
|
6
|
+
profiles="urn:mpeg:dash:profile:isoff-live:2011"
|
|
7
|
+
type="static"
|
|
8
|
+
mediaPresentationDuration="PT14.0S"
|
|
9
|
+
maxSegmentDuration="PT2.0S"
|
|
10
|
+
minBufferTime="PT4.0S">
|
|
11
|
+
<ProgramInformation>
|
|
12
|
+
</ProgramInformation>
|
|
13
|
+
<ServiceDescription id="0">
|
|
14
|
+
</ServiceDescription>
|
|
15
|
+
<Period id="0" start="PT0.0S">
|
|
16
|
+
<AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
|
|
17
|
+
<Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
|
|
18
|
+
<SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="3">
|
|
19
|
+
<SegmentTimeline>
|
|
20
|
+
<S t="61440" d="30720" r="4" />
|
|
21
|
+
</SegmentTimeline>
|
|
22
|
+
</SegmentTemplate>
|
|
23
|
+
</Representation>
|
|
24
|
+
</AdaptationSet>
|
|
25
|
+
</Period>
|
|
26
|
+
</MPD>
|
|
Binary file
|
|
@@ -476,6 +476,15 @@ describe('TtmlTextParser', () => {
|
|
|
476
476
|
{periodStart: 0, segmentStart: 0, segmentEnd: 0});
|
|
477
477
|
});
|
|
478
478
|
|
|
479
|
+
it('supports comments in the body', () => {
|
|
480
|
+
verifyHelper(
|
|
481
|
+
[],
|
|
482
|
+
'<tt><body><div>' +
|
|
483
|
+
'<!-- text-based TTML -->' +
|
|
484
|
+
'</div></body></tt>',
|
|
485
|
+
{periodStart: 0, segmentStart: 0, segmentEnd: 0});
|
|
486
|
+
});
|
|
487
|
+
|
|
479
488
|
it('parses alignment from textAlign attribute of a region', () => {
|
|
480
489
|
verifyHelper(
|
|
481
490
|
[
|