shaka-player 4.0.1 → 4.0.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/AUTHORS +1 -0
- package/CHANGELOG.md +37 -0
- package/CONTRIBUTORS +3 -0
- package/README.md +20 -6
- package/demo/common/assets.js +1 -1
- package/demo/demo.less +0 -1
- package/demo/index.html +0 -2
- package/demo/main.js +3 -3
- package/dist/controls.css +3 -3
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +3 -3
- package/dist/demo.compiled.debug.map +2 -2
- package/dist/demo.compiled.js +3 -3
- package/dist/demo.compiled.map +2 -2
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +4 -4
- package/dist/locales.js +34 -34
- package/dist/receiver.compiled.debug.js +1 -1
- package/dist/receiver.compiled.debug.map +1 -1
- package/dist/receiver.compiled.js +1 -1
- package/dist/receiver.compiled.map +1 -1
- package/dist/shaka-player.compiled.d.ts +11 -0
- package/dist/shaka-player.compiled.debug.d.ts +11 -0
- package/dist/shaka-player.compiled.debug.externs.js +51 -39
- package/dist/shaka-player.compiled.debug.js +247 -237
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +51 -39
- package/dist/shaka-player.compiled.js +799 -792
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +11 -0
- package/dist/shaka-player.ui.debug.d.ts +11 -0
- package/dist/shaka-player.ui.debug.externs.js +51 -39
- package/dist/shaka-player.ui.debug.js +273 -262
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +51 -39
- package/dist/shaka-player.ui.js +957 -952
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/upgrade.md +1 -0
- package/docs/tutorials/welcome.md +6 -3
- package/externs/shaka/player.js +4 -2
- package/lib/abr/simple_abr_manager.js +2 -1
- package/lib/dash/dash_parser.js +5 -0
- package/lib/hls/hls_parser.js +197 -73
- package/lib/media/drm_engine.js +3 -0
- package/lib/media/media_source_engine.js +57 -24
- package/lib/media/presentation_timeline.js +24 -1
- package/lib/media/segment_index.js +26 -1
- package/lib/media/segment_reference.js +10 -3
- package/lib/media/streaming_engine.js +3 -4
- package/lib/media/time_ranges_utils.js +46 -0
- package/lib/player.js +1 -1
- package/lib/polyfill/media_capabilities.js +3 -0
- package/lib/polyfill/videoplaybackquality.js +3 -1
- package/lib/util/mime_utils.js +14 -5
- package/lib/util/platform.js +19 -1
- package/lib/util/stream_utils.js +1 -0
- package/lib/util/string_utils.js +56 -14
- package/maintained-branches.md +15 -0
- package/package.json +3 -5
- package/test/hls/hls_live_unit.js +57 -7
- package/test/hls/hls_parser_unit.js +102 -8
- package/test/media/drm_engine_integration.js +24 -8
- 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/test/util/fake_media_source_engine.js +10 -9
- package/ui/less/containers.less +1 -1
- package/ui/less/general.less +1 -1
- package/ui/less/range_elements.less +1 -0
- package/.github/pull_request_template.md +0 -10
- 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
|
@@ -539,11 +539,13 @@ describe('HlsParser live', () => {
|
|
|
539
539
|
ManifestParser.verifySegmentIndex(video, [ref1, ref2]);
|
|
540
540
|
});
|
|
541
541
|
|
|
542
|
+
// Test for https://github.com/shaka-project/shaka-player/issues/4223
|
|
542
543
|
it('parses streams with partial and preload hinted segments', async () => {
|
|
543
544
|
playerInterface.isLowLatencyMode = () => true;
|
|
544
545
|
const mediaWithPartialSegments = [
|
|
545
546
|
'#EXTM3U\n',
|
|
546
547
|
'#EXT-X-TARGETDURATION:5\n',
|
|
548
|
+
'#EXT-X-PART-INF:PART-TARGET=1.5\n',
|
|
547
549
|
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
548
550
|
'#EXT-X-MEDIA-SEQUENCE:0\n',
|
|
549
551
|
// ref includes partialRef, partialRef2
|
|
@@ -576,26 +578,73 @@ describe('HlsParser live', () => {
|
|
|
576
578
|
'test:/partial2.mp4', 2, 4, /* syncTime= */ null,
|
|
577
579
|
/* baseUri= */ '', /* startByte= */ 200, /* endByte= */ 429);
|
|
578
580
|
|
|
581
|
+
const ref = makeReference(
|
|
582
|
+
'test:/main.mp4', 0, 4, /* syncTime= */ null,
|
|
583
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 429,
|
|
584
|
+
/* timestampOffset= */ 0, [partialRef, partialRef2]);
|
|
585
|
+
|
|
579
586
|
const partialRef3 = makeReference(
|
|
580
587
|
'test:/partial.mp4', 4, 6, /* syncTime= */ null,
|
|
581
588
|
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 209);
|
|
582
589
|
|
|
583
|
-
// A preload hinted partial segment doesn't have duration information,
|
|
584
|
-
// so its startTime and endTime are the same.
|
|
585
590
|
const preloadRef = makeReference(
|
|
586
|
-
'test:/partial.mp4', 6,
|
|
591
|
+
'test:/partial.mp4', 6, 7.5, /* syncTime= */ null,
|
|
587
592
|
/* baseUri= */ '', /* startByte= */ 210, /* endByte= */ null);
|
|
588
593
|
|
|
594
|
+
// ref2 is not fully published yet, so it doesn't have a segment uri.
|
|
595
|
+
const ref2 = makeReference(
|
|
596
|
+
'', 4, 7.5, /* syncTime= */ null,
|
|
597
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
|
|
598
|
+
/* timestampOffset= */ 0, [partialRef3, preloadRef]);
|
|
599
|
+
|
|
600
|
+
const manifest = await parser.start('test:/master', playerInterface);
|
|
601
|
+
const video = manifest.variants[0].video;
|
|
602
|
+
await video.createSegmentIndex();
|
|
603
|
+
ManifestParser.verifySegmentIndex(video, [ref, ref2]);
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
// Test for https://github.com/shaka-project/shaka-player/issues/4223
|
|
607
|
+
it('ignores preload hinted segments without target duration', async () => {
|
|
608
|
+
playerInterface.isLowLatencyMode = () => true;
|
|
609
|
+
|
|
610
|
+
// Missing PART-TARGET, so preload hints are skipped.
|
|
611
|
+
const mediaWithPartialSegments = [
|
|
612
|
+
'#EXTM3U\n',
|
|
613
|
+
'#EXT-X-TARGETDURATION:5\n',
|
|
614
|
+
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
615
|
+
'#EXT-X-MEDIA-SEQUENCE:0\n',
|
|
616
|
+
'#EXTINF:4,\n',
|
|
617
|
+
// ref1
|
|
618
|
+
'main.mp4\n',
|
|
619
|
+
// ref2 includes partialRef, but not preloadRef
|
|
620
|
+
// partialRef
|
|
621
|
+
'#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=210@0\n',
|
|
622
|
+
// preloadRef
|
|
623
|
+
'#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4",BYTERANGE-START=210\n',
|
|
624
|
+
].join('');
|
|
625
|
+
|
|
626
|
+
fakeNetEngine
|
|
627
|
+
.setResponseText('test:/master', master)
|
|
628
|
+
.setResponseText('test:/video', mediaWithPartialSegments)
|
|
629
|
+
.setResponseValue('test:/init.mp4', initSegmentData)
|
|
630
|
+
.setResponseValue('test:/main.mp4', segmentData)
|
|
631
|
+
.setResponseValue('test:/partial.mp4', segmentData)
|
|
632
|
+
.setResponseValue('test:/partial2.mp4', segmentData);
|
|
633
|
+
|
|
589
634
|
const ref = makeReference(
|
|
590
635
|
'test:/main.mp4', 0, 4, /* syncTime= */ null,
|
|
591
|
-
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */
|
|
592
|
-
/* timestampOffset= */ 0, [
|
|
636
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
|
|
637
|
+
/* timestampOffset= */ 0, []);
|
|
638
|
+
|
|
639
|
+
const partialRef = makeReference(
|
|
640
|
+
'test:/partial.mp4', 4, 6, /* syncTime= */ null,
|
|
641
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 209);
|
|
593
642
|
|
|
594
643
|
// ref2 is not fully published yet, so it doesn't have a segment uri.
|
|
595
644
|
const ref2 = makeReference(
|
|
596
645
|
'', 4, 6, /* syncTime= */ null,
|
|
597
|
-
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */
|
|
598
|
-
/* timestampOffset= */ 0, [
|
|
646
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 209,
|
|
647
|
+
/* timestampOffset= */ 0, [partialRef]);
|
|
599
648
|
|
|
600
649
|
const manifest = await parser.start('test:/master', playerInterface);
|
|
601
650
|
const video = manifest.variants[0].video;
|
|
@@ -611,6 +660,7 @@ describe('HlsParser live', () => {
|
|
|
611
660
|
const mediaWithPartialSegments = [
|
|
612
661
|
'#EXTM3U\n',
|
|
613
662
|
'#EXT-X-TARGETDURATION:5\n',
|
|
663
|
+
'#EXT-X-PART-INF:PART-TARGET=1.5\n',
|
|
614
664
|
'#EXTINF:4,\n',
|
|
615
665
|
'main.mp4\n',
|
|
616
666
|
'#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=210@0\n',
|
|
@@ -2021,6 +2021,10 @@ describe('HlsParser', () => {
|
|
|
2021
2021
|
});
|
|
2022
2022
|
|
|
2023
2023
|
describe('produces syncTime', () => {
|
|
2024
|
+
// Corresponds to "2000-01-01T00:00:00.00Z".
|
|
2025
|
+
// All the PROGRAM-DATE-TIME values in the tests below are at or after this.
|
|
2026
|
+
const syncTimeBase = 946684800;
|
|
2027
|
+
|
|
2024
2028
|
/**
|
|
2025
2029
|
* @param {number} startTime
|
|
2026
2030
|
* @param {number} endTime
|
|
@@ -2039,9 +2043,10 @@ describe('HlsParser', () => {
|
|
|
2039
2043
|
/**
|
|
2040
2044
|
* @param {string} media
|
|
2041
2045
|
* @param {!Array.<number>} startTimes
|
|
2046
|
+
* @param {number} syncTimeOffset
|
|
2042
2047
|
* @param {(function(!shaka.media.SegmentReference))=} modifyFn
|
|
2043
2048
|
*/
|
|
2044
|
-
async function test(media, startTimes, modifyFn) {
|
|
2049
|
+
async function test(media, startTimes, syncTimeOffset, modifyFn) {
|
|
2045
2050
|
const master = [
|
|
2046
2051
|
'#EXTM3U\n',
|
|
2047
2052
|
'#EXT-X-STREAM-INF:BANDWIDTH=200,CODECS="avc1,vtt",',
|
|
@@ -2053,7 +2058,8 @@ describe('HlsParser', () => {
|
|
|
2053
2058
|
for (let i = 0; i < startTimes.length - 1; i++) {
|
|
2054
2059
|
const startTime = startTimes[i];
|
|
2055
2060
|
const endTime = startTimes[i + 1];
|
|
2056
|
-
const reference = makeReference(
|
|
2061
|
+
const reference = makeReference(
|
|
2062
|
+
startTime, endTime, syncTimeOffset + startTime);
|
|
2057
2063
|
if (modifyFn) {
|
|
2058
2064
|
modifyFn(reference);
|
|
2059
2065
|
}
|
|
@@ -2100,7 +2106,7 @@ describe('HlsParser', () => {
|
|
|
2100
2106
|
'#EXT-X-PROGRAM-DATE-TIME:2000-01-01T00:00:25.00Z\n',
|
|
2101
2107
|
'#EXTINF:5,\n',
|
|
2102
2108
|
'main.mp4',
|
|
2103
|
-
].join(''), [0, 5, 10, 15, 20, 25]);
|
|
2109
|
+
].join(''), [0, 5, 10, 15, 20, 25], syncTimeBase + 5);
|
|
2104
2110
|
});
|
|
2105
2111
|
|
|
2106
2112
|
it('when some EXT-X-PROGRAM-DATE-TIME values are missing', async () => {
|
|
@@ -2122,7 +2128,7 @@ describe('HlsParser', () => {
|
|
|
2122
2128
|
'main.mp4\n',
|
|
2123
2129
|
'#EXTINF:4,\n',
|
|
2124
2130
|
'main.mp4',
|
|
2125
|
-
].join(''), [0, 2, 7, 12, 17, 19, 23]);
|
|
2131
|
+
].join(''), [0, 2, 7, 12, 17, 19, 23], syncTimeBase + 8);
|
|
2126
2132
|
});
|
|
2127
2133
|
|
|
2128
2134
|
it('except when ignoreManifestProgramDateTime is set', async () => {
|
|
@@ -2148,7 +2154,7 @@ describe('HlsParser', () => {
|
|
|
2148
2154
|
'#EXT-X-PROGRAM-DATE-TIME:2000-01-01T00:00:25.00Z\n',
|
|
2149
2155
|
'#EXTINF:5,\n',
|
|
2150
2156
|
'main.mp4',
|
|
2151
|
-
].join(''), [0, 5, 10, 15, 20, 25], (reference) => {
|
|
2157
|
+
].join(''), [0, 5, 10, 15, 20, 25], syncTimeBase + 5, (reference) => {
|
|
2152
2158
|
reference.syncTime = null;
|
|
2153
2159
|
});
|
|
2154
2160
|
});
|
|
@@ -2176,11 +2182,11 @@ describe('HlsParser', () => {
|
|
|
2176
2182
|
'#EXT-X-PROGRAM-DATE-TIME:2000-01-01T00:00:25.00Z\n',
|
|
2177
2183
|
'#EXTINF:5,\n',
|
|
2178
2184
|
'main.mp4',
|
|
2179
|
-
].join(''), [0, 5, 10, 15, 20, 25], (reference) => {
|
|
2185
|
+
].join(''), [0, 5, 10, 15, 20, 25], syncTimeBase + 5, (reference) => {
|
|
2180
2186
|
if (reference.startTime == 10) {
|
|
2181
2187
|
reference.partialReferences = [
|
|
2182
|
-
makeReference(10, 12.5,
|
|
2183
|
-
makeReference(12.5, 15,
|
|
2188
|
+
makeReference(10, 12.5, syncTimeBase + 15),
|
|
2189
|
+
makeReference(12.5, 15, syncTimeBase + 17.5),
|
|
2184
2190
|
];
|
|
2185
2191
|
}
|
|
2186
2192
|
});
|
|
@@ -3555,4 +3561,92 @@ describe('HlsParser', () => {
|
|
|
3555
3561
|
|
|
3556
3562
|
await testHlsParser(media, '', manifest);
|
|
3557
3563
|
});
|
|
3564
|
+
|
|
3565
|
+
it('syncs on sequence with ignoreManifestProgramDateTime', async () => {
|
|
3566
|
+
const config = shaka.util.PlayerConfiguration.createDefault().manifest;
|
|
3567
|
+
config.hls.ignoreManifestProgramDateTime = true;
|
|
3568
|
+
parser.configure(config);
|
|
3569
|
+
|
|
3570
|
+
const master = [
|
|
3571
|
+
'#EXTM3U\n',
|
|
3572
|
+
'#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aud1",LANGUAGE="eng",URI="audio"\n',
|
|
3573
|
+
'#EXT-X-STREAM-INF:BANDWIDTH=200,CODECS="avc1,mp4a",',
|
|
3574
|
+
'RESOLUTION=960x540,FRAME-RATE=60,AUDIO="aud1"\n',
|
|
3575
|
+
'video\n',
|
|
3576
|
+
].join('');
|
|
3577
|
+
|
|
3578
|
+
const video = [
|
|
3579
|
+
'#EXTM3U\n',
|
|
3580
|
+
'#EXT-X-TARGETDURATION:5\n',
|
|
3581
|
+
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
3582
|
+
'#EXT-X-MEDIA-SEQUENCE:1\n',
|
|
3583
|
+
'#EXTINF:5,\n',
|
|
3584
|
+
'video1.mp4\n',
|
|
3585
|
+
'#EXTINF:5,\n',
|
|
3586
|
+
'video2.mp4\n',
|
|
3587
|
+
'#EXTINF:5,\n',
|
|
3588
|
+
'video3.mp4\n',
|
|
3589
|
+
].join('');
|
|
3590
|
+
|
|
3591
|
+
const audio = [
|
|
3592
|
+
'#EXTM3U\n',
|
|
3593
|
+
'#EXT-X-TARGETDURATION:5\n',
|
|
3594
|
+
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
3595
|
+
'#EXT-X-MEDIA-SEQUENCE:3\n',
|
|
3596
|
+
'#EXTINF:5,\n',
|
|
3597
|
+
'audio3.mp4\n',
|
|
3598
|
+
'#EXTINF:5,\n',
|
|
3599
|
+
'audio4.mp4\n',
|
|
3600
|
+
].join('');
|
|
3601
|
+
|
|
3602
|
+
const manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
3603
|
+
manifest.sequenceMode = true;
|
|
3604
|
+
manifest.anyTimeline();
|
|
3605
|
+
manifest.addPartialVariant((variant) => {
|
|
3606
|
+
variant.language = 'en';
|
|
3607
|
+
variant.bandwidth = 200;
|
|
3608
|
+
variant.addPartialStream(ContentType.VIDEO, (stream) => {
|
|
3609
|
+
stream.mime('video/mp4', 'avc1');
|
|
3610
|
+
stream.size(960, 540);
|
|
3611
|
+
stream.frameRate = 60;
|
|
3612
|
+
});
|
|
3613
|
+
variant.addPartialStream(ContentType.AUDIO, (stream) => {
|
|
3614
|
+
stream.language = 'en';
|
|
3615
|
+
stream.mime('audio/mp4', 'mp4a');
|
|
3616
|
+
});
|
|
3617
|
+
});
|
|
3618
|
+
});
|
|
3619
|
+
|
|
3620
|
+
fakeNetEngine
|
|
3621
|
+
.setResponseText('test:/master', master)
|
|
3622
|
+
.setResponseText('test:/audio', audio)
|
|
3623
|
+
.setResponseText('test:/video', video)
|
|
3624
|
+
.setResponseValue('test:/init.mp4', initSegmentData);
|
|
3625
|
+
|
|
3626
|
+
const actualManifest = await parser.start('test:/master', playerInterface);
|
|
3627
|
+
expect(actualManifest).toEqual(manifest);
|
|
3628
|
+
|
|
3629
|
+
const actualVideo = actualManifest.variants[0].video;
|
|
3630
|
+
await actualVideo.createSegmentIndex();
|
|
3631
|
+
goog.asserts.assert(actualVideo.segmentIndex != null, 'Null segmentIndex!');
|
|
3632
|
+
|
|
3633
|
+
const actualAudio = actualManifest.variants[0].audio;
|
|
3634
|
+
await actualAudio.createSegmentIndex();
|
|
3635
|
+
goog.asserts.assert(actualAudio.segmentIndex != null, 'Null segmentIndex!');
|
|
3636
|
+
|
|
3637
|
+
// Verify that the references are aligned on sequence number.
|
|
3638
|
+
const videoSegments = Array.from(actualVideo.segmentIndex);
|
|
3639
|
+
const audioSegments = Array.from(actualAudio.segmentIndex);
|
|
3640
|
+
|
|
3641
|
+
// The first two were dropped to align with the audio.
|
|
3642
|
+
expect(videoSegments.map((ref) => ref.getUris()[0])).toEqual([
|
|
3643
|
+
'test:/video3.mp4',
|
|
3644
|
+
]);
|
|
3645
|
+
// Audio has a 4th segment that video doesn't, but that doesn't get clipped
|
|
3646
|
+
// or used as the base. Alignment is truly based on media sequence number.
|
|
3647
|
+
expect(audioSegments.map((ref) => ref.getUris()[0])).toEqual([
|
|
3648
|
+
'test:/audio3.mp4',
|
|
3649
|
+
'test:/audio4.mp4',
|
|
3650
|
+
]);
|
|
3651
|
+
});
|
|
3558
3652
|
});
|
|
@@ -209,10 +209,10 @@ describe('DrmEngine', () => {
|
|
|
209
209
|
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
210
210
|
await drmEngine.attach(video);
|
|
211
211
|
await mediaSourceEngine.appendBuffer(
|
|
212
|
-
ContentType.VIDEO, videoInitSegment, null,
|
|
212
|
+
ContentType.VIDEO, videoInitSegment, null,
|
|
213
213
|
/* hasClosedCaptions= */ false);
|
|
214
214
|
await mediaSourceEngine.appendBuffer(
|
|
215
|
-
ContentType.AUDIO, audioInitSegment, null,
|
|
215
|
+
ContentType.AUDIO, audioInitSegment, null,
|
|
216
216
|
/* hasClosedCaptions= */ false);
|
|
217
217
|
await encryptedEventSeen;
|
|
218
218
|
// With PlayReady, a persistent license policy can cause a different
|
|
@@ -245,11 +245,13 @@ describe('DrmEngine', () => {
|
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
+
const reference = dummyReference(0, 10);
|
|
249
|
+
|
|
248
250
|
await mediaSourceEngine.appendBuffer(
|
|
249
|
-
ContentType.VIDEO, videoSegment,
|
|
251
|
+
ContentType.VIDEO, videoSegment, reference,
|
|
250
252
|
/* hasClosedCaptions= */ false);
|
|
251
253
|
await mediaSourceEngine.appendBuffer(
|
|
252
|
-
ContentType.AUDIO, audioSegment,
|
|
254
|
+
ContentType.AUDIO, audioSegment, reference,
|
|
253
255
|
/* hasClosedCaptions= */ false);
|
|
254
256
|
|
|
255
257
|
expect(video.buffered.end(0)).toBeGreaterThan(0);
|
|
@@ -305,10 +307,10 @@ describe('DrmEngine', () => {
|
|
|
305
307
|
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
306
308
|
await drmEngine.attach(video);
|
|
307
309
|
await mediaSourceEngine.appendBuffer(
|
|
308
|
-
ContentType.VIDEO, videoInitSegment, null,
|
|
310
|
+
ContentType.VIDEO, videoInitSegment, null,
|
|
309
311
|
/* hasClosedCaptions= */ false);
|
|
310
312
|
await mediaSourceEngine.appendBuffer(
|
|
311
|
-
ContentType.AUDIO, audioInitSegment, null,
|
|
313
|
+
ContentType.AUDIO, audioInitSegment, null,
|
|
312
314
|
/* hasClosedCaptions= */ false);
|
|
313
315
|
await encryptedEventSeen;
|
|
314
316
|
|
|
@@ -326,11 +328,13 @@ describe('DrmEngine', () => {
|
|
|
326
328
|
}
|
|
327
329
|
}
|
|
328
330
|
|
|
331
|
+
const reference = dummyReference(0, 10);
|
|
332
|
+
|
|
329
333
|
await mediaSourceEngine.appendBuffer(
|
|
330
|
-
ContentType.VIDEO, videoSegment,
|
|
334
|
+
ContentType.VIDEO, videoSegment, reference,
|
|
331
335
|
/* hasClosedCaptions= */ false);
|
|
332
336
|
await mediaSourceEngine.appendBuffer(
|
|
333
|
-
ContentType.AUDIO, audioSegment,
|
|
337
|
+
ContentType.AUDIO, audioSegment, reference,
|
|
334
338
|
/* hasClosedCaptions= */ false);
|
|
335
339
|
|
|
336
340
|
expect(video.buffered.end(0)).toBeGreaterThan(0);
|
|
@@ -345,4 +349,16 @@ describe('DrmEngine', () => {
|
|
|
345
349
|
expect(video.currentTime).toBeGreaterThan(0);
|
|
346
350
|
});
|
|
347
351
|
}); // describe('ClearKey')
|
|
352
|
+
|
|
353
|
+
function dummyReference(startTime, endTime) {
|
|
354
|
+
return new shaka.media.SegmentReference(
|
|
355
|
+
startTime, endTime,
|
|
356
|
+
/* uris= */ () => ['foo://bar'],
|
|
357
|
+
/* startByte= */ 0,
|
|
358
|
+
/* endByte= */ null,
|
|
359
|
+
/* initSegmentReference= */ null,
|
|
360
|
+
/* timestampOffset= */ 0,
|
|
361
|
+
/* appendWindowStart= */ 0,
|
|
362
|
+
/* appendWindowEnd= */ Infinity);
|
|
363
|
+
}
|
|
348
364
|
});
|
|
@@ -57,32 +57,32 @@ describe('MediaSourceEngine', () => {
|
|
|
57
57
|
|
|
58
58
|
function appendInit(type) {
|
|
59
59
|
const segment = generators[type].getInitSegment(Date.now() / 1000);
|
|
60
|
+
const reference = null;
|
|
60
61
|
return mediaSourceEngine.appendBuffer(
|
|
61
|
-
type, segment,
|
|
62
|
+
type, segment, reference, /* hasClosedCaptions= */ false);
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
function append(type, segmentNumber) {
|
|
65
66
|
const segment = generators[type]
|
|
66
67
|
.getSegment(segmentNumber, Date.now() / 1000);
|
|
68
|
+
const reference = dummyReference(type, segmentNumber);
|
|
67
69
|
return mediaSourceEngine.appendBuffer(
|
|
68
|
-
type, segment,
|
|
70
|
+
type, segment, reference, /* hasClosedCaptions= */ false);
|
|
69
71
|
}
|
|
70
72
|
|
|
71
|
-
// The start time and end time should be null for init segment with closed
|
|
72
|
-
// captions.
|
|
73
73
|
function appendInitWithClosedCaptions(type) {
|
|
74
74
|
const segment = generators[type].getInitSegment(Date.now() / 1000);
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
const reference = null;
|
|
76
|
+
return mediaSourceEngine.appendBuffer(
|
|
77
|
+
type, segment, reference, /* hasClosedCaptions= */ true);
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
// The start time and end time should be valid for the segments with closed
|
|
80
|
-
// captions.
|
|
81
80
|
function appendWithClosedCaptions(type, segmentNumber) {
|
|
82
81
|
const segment = generators[type]
|
|
83
82
|
.getSegment(segmentNumber, Date.now() / 1000);
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
const reference = dummyReference(type, segmentNumber);
|
|
84
|
+
return mediaSourceEngine.appendBuffer(
|
|
85
|
+
type, segment, reference, /* hasClosedCaptions= */ true);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
function buffered(type, time) {
|
|
@@ -93,6 +93,20 @@ describe('MediaSourceEngine', () => {
|
|
|
93
93
|
return mediaSourceEngine.bufferStart(type);
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
function dummyReference(type, segmentNumber) {
|
|
97
|
+
const start = segmentNumber * metadata[type].segmentDuration;
|
|
98
|
+
const end = (segmentNumber + 1) * metadata[type].segmentDuration;
|
|
99
|
+
return new shaka.media.SegmentReference(
|
|
100
|
+
start, end,
|
|
101
|
+
/* uris= */ () => ['foo://bar'],
|
|
102
|
+
/* startByte= */ 0,
|
|
103
|
+
/* endByte= */ null,
|
|
104
|
+
/* initSegmentReference= */ null,
|
|
105
|
+
/* timestampOffset= */ 0,
|
|
106
|
+
/* appendWindowStart= */ 0,
|
|
107
|
+
/* appendWindowEnd= */ Infinity);
|
|
108
|
+
}
|
|
109
|
+
|
|
96
110
|
function remove(type, segmentNumber) {
|
|
97
111
|
const start = segmentNumber * metadata[type].segmentDuration;
|
|
98
112
|
const end = (segmentNumber + 1) * metadata[type].segmentDuration;
|