shaka-player 3.1.1 → 3.1.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/AUTHORS +7 -2
- package/CHANGELOG.md +199 -0
- package/CONTRIBUTORS +9 -3
- package/build/generateExterns.js +1 -1
- package/build/misspellings.txt +1 -0
- package/build/shakaBuildHelpers.py +6 -5
- package/build/subprocessWindowsPatch.py +103 -0
- package/demo/common/assets.js +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 +7 -7
- package/dist/locales.js +35 -33
- package/dist/receiver.compiled.debug.js +1 -1
- package/dist/receiver.compiled.js +1 -1
- package/dist/shaka-player.compiled.d.ts +171 -3
- package/dist/shaka-player.compiled.debug.d.ts +171 -3
- package/dist/shaka-player.compiled.debug.externs.js +179 -1
- package/dist/shaka-player.compiled.debug.js +365 -344
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.externs.js +179 -1
- package/dist/shaka-player.compiled.js +806 -798
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.d.ts +171 -3
- package/dist/shaka-player.ui.debug.d.ts +171 -3
- package/dist/shaka-player.ui.debug.externs.js +181 -3
- package/dist/shaka-player.ui.debug.js +458 -435
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +181 -3
- package/dist/shaka-player.ui.js +927 -918
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/fairplay.md +1 -1
- package/docs/tutorials/faq.md +14 -0
- package/docs/tutorials/index.json +2 -2
- package/docs/tutorials/upgrade-v3.md +38 -0
- package/docs/tutorials/upgrade.md +3 -3
- package/externs/ima.js +4 -0
- package/externs/shaka/ads.js +2 -0
- package/externs/shaka/player.js +6 -0
- package/externs/shaka/text.js +10 -0
- package/karma.conf.js +1 -0
- package/lib/ads/ad_manager.js +29 -11
- package/lib/ads/client_side_ad_manager.js +76 -86
- package/lib/ads/server_side_ad_manager.js +26 -11
- 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/cea/sei_processor.js +24 -17
- package/lib/dash/dash_parser.js +100 -5
- package/lib/dash/segment_list.js +1 -1
- package/lib/dash/segment_template.js +7 -4
- package/lib/hls/hls_parser.js +44 -17
- package/lib/media/closed_caption_parser.js +3 -1
- package/lib/media/content_workarounds.js +12 -0
- package/lib/media/drm_engine.js +20 -1
- package/lib/media/gap_jumping_controller.js +8 -4
- package/lib/media/media_source_engine.js +1 -2
- package/lib/media/playhead.js +1 -1
- package/lib/media/presentation_timeline.js +3 -1
- package/lib/media/segment_reference.js +8 -0
- package/lib/media/streaming_engine.js +28 -19
- package/lib/net/networking_engine.js +2 -1
- package/lib/player.js +108 -54
- package/lib/polyfill/encryption_scheme.js +2 -0
- package/lib/polyfill/fullscreen.js +2 -0
- package/lib/polyfill/mathround.js +2 -0
- package/lib/polyfill/media_capabilities.js +76 -22
- package/lib/polyfill/mediasource.js +8 -0
- package/lib/polyfill/orientation.js +3 -1
- package/lib/polyfill/patchedmediakeys_apple.js +6 -4
- package/lib/polyfill/patchedmediakeys_ms.js +6 -4
- package/lib/polyfill/patchedmediakeys_nop.js +2 -0
- package/lib/polyfill/patchedmediakeys_webkit.js +6 -4
- package/lib/polyfill/pip_webkit.js +2 -0
- package/lib/polyfill/storage_estimate.js +2 -0
- package/lib/polyfill/video_play_promise.js +2 -0
- package/lib/polyfill/videoplaybackquality.js +2 -0
- package/lib/polyfill/vttcue.js +2 -0
- package/lib/text/cue.js +17 -0
- package/lib/text/mp4_ttml_parser.js +3 -0
- package/lib/text/text_engine.js +14 -2
- package/lib/text/ttml_text_parser.js +135 -87
- package/lib/text/ui_text_displayer.js +233 -83
- package/lib/text/vtt_text_parser.js +4 -2
- package/lib/util/fake_event.js +53 -7
- package/lib/util/mp4_box_parsers.js +1 -1
- package/lib/util/periods.js +111 -35
- package/lib/util/platform.js +13 -1
- package/lib/util/stream_utils.js +79 -10
- package/lib/util/xml_utils.js +19 -0
- package/package.json +2 -2
- package/test/cast/cast_proxy_unit.js +12 -6
- package/test/cast/cast_receiver_integration.js +1 -1
- package/test/cast/cast_utils_unit.js +1 -1
- package/test/cea/mp4_cea_parser_unit.js +26 -0
- package/test/dash/dash_parser_live_unit.js +1 -0
- package/test/dash/dash_parser_manifest_unit.js +220 -2
- package/test/dash/dash_parser_segment_template_unit.js +3 -3
- package/test/hls/hls_parser_unit.js +5 -1
- package/test/media/closed_caption_parser_unit.js +20 -0
- package/test/media/drm_engine_unit.js +56 -0
- package/test/media/playhead_unit.js +27 -1
- package/test/media/presentation_timeline_unit.js +19 -0
- package/test/media/streaming_engine_integration.js +2 -1
- package/test/media/streaming_engine_unit.js +148 -3
- package/test/player_integration.js +38 -0
- package/test/player_unit.js +101 -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/assets/empty_caption_video_init.mp4 +0 -0
- package/test/test/assets/empty_caption_video_segment.mp4 +0 -0
- package/test/test/util/fake_ad_manager.js +4 -1
- package/test/test/util/simple_fakes.js +5 -3
- package/test/test/util/ttml_utils.js +81 -0
- package/test/text/mp4_ttml_parser_unit.js +11 -18
- package/test/text/ttml_text_parser_unit.js +542 -220
- package/test/text/ui_text_displayer_unit.js +95 -18
- package/test/text/vtt_text_parser_unit.js +17 -1
- package/test/ui/localization_unit.js +15 -14
- package/test/ui/text_displayer_layout_unit.js +52 -1
- package/test/util/mp4_box_parsers_unit.js +28 -0
- package/test/util/periods_unit.js +190 -2
- package/test/util/stream_utils_unit.js +59 -2
- package/ui/airplay_button.js +5 -0
- package/ui/big_play_button.js +10 -0
- package/ui/cast_button.js +2 -3
- package/ui/controls.js +8 -6
- package/ui/less/buttons.less +0 -4
- package/ui/less/containers.less +10 -5
- package/ui/locales/en.json +1 -0
- package/ui/locales/ru.json +6 -6
- package/ui/locales/source.json +4 -0
- package/ui/localization.js +28 -51
- package/ui/pip_button.js +2 -3
- package/ui/play_button.js +10 -10
- package/ui/small_play_button.js +12 -0
- package/ui/text_selection.js +1 -0
- package/docs/tutorials/upgrade-v2-4.md +0 -481
|
@@ -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});
|
package/test/player_unit.js
CHANGED
|
@@ -10,6 +10,8 @@ goog.require('shaka.log');
|
|
|
10
10
|
goog.require('shaka.media.BufferingObserver');
|
|
11
11
|
goog.require('shaka.media.ManifestParser');
|
|
12
12
|
goog.require('shaka.media.PresentationTimeline');
|
|
13
|
+
goog.require('shaka.media.SegmentReference');
|
|
14
|
+
goog.require('shaka.media.SegmentIndex');
|
|
13
15
|
goog.require('shaka.test.FakeAbrManager');
|
|
14
16
|
goog.require('shaka.test.FakeDrmEngine');
|
|
15
17
|
goog.require('shaka.test.FakeManifestParser');
|
|
@@ -3532,6 +3534,105 @@ describe('Player', () => {
|
|
|
3532
3534
|
]);
|
|
3533
3535
|
});
|
|
3534
3536
|
});
|
|
3537
|
+
|
|
3538
|
+
describe('getThumbnails', () => {
|
|
3539
|
+
it('returns correct thumbnail position for supplied time', async () => {
|
|
3540
|
+
const uris = () => ['thumbnail'];
|
|
3541
|
+
const ref = new shaka.media.SegmentReference(
|
|
3542
|
+
0, 60, uris, 0, null, null, 0, 0, Infinity, [],
|
|
3543
|
+
);
|
|
3544
|
+
const index = new shaka.media.SegmentIndex([ref]);
|
|
3545
|
+
|
|
3546
|
+
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
3547
|
+
manifest.addVariant(0, (variant) => {
|
|
3548
|
+
variant.addVideo(1);
|
|
3549
|
+
});
|
|
3550
|
+
manifest.addImageStream(5, (stream) => {
|
|
3551
|
+
stream.originalId = 'thumbnail';
|
|
3552
|
+
stream.width = 200;
|
|
3553
|
+
stream.height = 150;
|
|
3554
|
+
stream.mimeType = 'image/jpeg';
|
|
3555
|
+
stream.tilesLayout = '2x3';
|
|
3556
|
+
stream.segmentIndex = index;
|
|
3557
|
+
});
|
|
3558
|
+
});
|
|
3559
|
+
|
|
3560
|
+
await player.load(fakeManifestUri, 0, fakeMimeType);
|
|
3561
|
+
|
|
3562
|
+
const thumbnail0 = await player.getThumbnails(5, 0);
|
|
3563
|
+
const thumbnail1 = await player.getThumbnails(5, 11);
|
|
3564
|
+
const thumbnail2 = await player.getThumbnails(5, 21);
|
|
3565
|
+
const thumbnail5 = await player.getThumbnails(5, 51);
|
|
3566
|
+
expect(thumbnail0).toEqual(jasmine.objectContaining({
|
|
3567
|
+
positionX: 0,
|
|
3568
|
+
positionY: 0,
|
|
3569
|
+
width: 100,
|
|
3570
|
+
height: 50,
|
|
3571
|
+
}));
|
|
3572
|
+
expect(thumbnail1).toEqual(jasmine.objectContaining({
|
|
3573
|
+
positionX: 100,
|
|
3574
|
+
positionY: 0,
|
|
3575
|
+
width: 100,
|
|
3576
|
+
height: 50,
|
|
3577
|
+
}));
|
|
3578
|
+
expect(thumbnail2).toEqual(jasmine.objectContaining({
|
|
3579
|
+
positionX: 0,
|
|
3580
|
+
positionY: 50,
|
|
3581
|
+
width: 100,
|
|
3582
|
+
height: 50,
|
|
3583
|
+
}));
|
|
3584
|
+
expect(thumbnail5).toEqual(jasmine.objectContaining({
|
|
3585
|
+
positionX: 100,
|
|
3586
|
+
positionY: 100,
|
|
3587
|
+
width: 100,
|
|
3588
|
+
height: 50,
|
|
3589
|
+
}));
|
|
3590
|
+
});
|
|
3591
|
+
|
|
3592
|
+
it('returns correct duration for a partially-used segment', async () => {
|
|
3593
|
+
const uris = () => ['thumbnail'];
|
|
3594
|
+
|
|
3595
|
+
const ref1 = new shaka.media.SegmentReference(
|
|
3596
|
+
0, 60, uris, 0, null, null, 0, 0, Infinity);
|
|
3597
|
+
const ref2 = new shaka.media.SegmentReference(
|
|
3598
|
+
60, 90, uris, 0, null, null, 0, 0, Infinity);
|
|
3599
|
+
ref2.trueEndTime = 120;
|
|
3600
|
+
|
|
3601
|
+
const index = new shaka.media.SegmentIndex([ref1, ref2]);
|
|
3602
|
+
|
|
3603
|
+
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
3604
|
+
manifest.addVariant(0, (variant) => {
|
|
3605
|
+
variant.addVideo(1);
|
|
3606
|
+
});
|
|
3607
|
+
manifest.addImageStream(5, (stream) => {
|
|
3608
|
+
stream.originalId = 'thumbnail';
|
|
3609
|
+
stream.width = 200;
|
|
3610
|
+
stream.height = 150;
|
|
3611
|
+
stream.mimeType = 'image/jpeg';
|
|
3612
|
+
stream.tilesLayout = '2x3';
|
|
3613
|
+
stream.segmentIndex = index;
|
|
3614
|
+
});
|
|
3615
|
+
});
|
|
3616
|
+
|
|
3617
|
+
await player.load(fakeManifestUri, 0, fakeMimeType);
|
|
3618
|
+
|
|
3619
|
+
const thumbnail0 = await player.getThumbnails(5, 0);
|
|
3620
|
+
expect(thumbnail0.startTime).toBe(0);
|
|
3621
|
+
expect(thumbnail0.duration).toBe(10);
|
|
3622
|
+
|
|
3623
|
+
const thumbnail1 = await player.getThumbnails(5, 10);
|
|
3624
|
+
expect(thumbnail1.startTime).toBe(10);
|
|
3625
|
+
expect(thumbnail1.duration).toBe(10);
|
|
3626
|
+
|
|
3627
|
+
const thumbnail6 = await player.getThumbnails(5, 60);
|
|
3628
|
+
expect(thumbnail6.startTime).toBe(60);
|
|
3629
|
+
expect(thumbnail6.duration).toBe(10);
|
|
3630
|
+
|
|
3631
|
+
const thumbnail8 = await player.getThumbnails(5, 80);
|
|
3632
|
+
expect(thumbnail8.startTime).toBe(80);
|
|
3633
|
+
expect(thumbnail8.duration).toBe(10);
|
|
3634
|
+
});
|
|
3635
|
+
});
|
|
3535
3636
|
});
|
|
3536
3637
|
|
|
3537
3638
|
/**
|
|
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
|
|
Binary file
|
|
Binary file
|
|
@@ -25,6 +25,9 @@ shaka.test.FakeAdManager = class extends shaka.util.FakeEventTarget {
|
|
|
25
25
|
this.stats_ = new shaka.ads.AdsStats();
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
/** @override */
|
|
29
|
+
release() {}
|
|
30
|
+
|
|
28
31
|
/** @override */
|
|
29
32
|
setLocale(locale) {}
|
|
30
33
|
|
|
@@ -75,7 +78,7 @@ shaka.test.FakeAdManager = class extends shaka.util.FakeEventTarget {
|
|
|
75
78
|
*/
|
|
76
79
|
startAd(ad) {
|
|
77
80
|
const event = new shaka.util.FakeEvent(shaka.ads.AdManager.AD_STARTED,
|
|
78
|
-
|
|
81
|
+
(new Map()).set('ad', ad));
|
|
79
82
|
|
|
80
83
|
this.dispatchEvent(event);
|
|
81
84
|
}
|
|
@@ -90,13 +90,15 @@ shaka.test.FakeAbrManager = class {
|
|
|
90
90
|
/** @extends {shaka.media.StreamingEngine} */
|
|
91
91
|
shaka.test.FakeStreamingEngine = class {
|
|
92
92
|
constructor() {
|
|
93
|
-
const resolve = () => Promise.resolve();
|
|
94
|
-
|
|
95
93
|
let activeVariant = null;
|
|
96
94
|
let activeText = null;
|
|
97
95
|
|
|
98
96
|
/** @type {!jasmine.Spy} */
|
|
99
|
-
this.destroy = jasmine.createSpy('destroy').and.callFake(
|
|
97
|
+
this.destroy = jasmine.createSpy('destroy').and.callFake(() => {
|
|
98
|
+
activeVariant = null;
|
|
99
|
+
activeText = null;
|
|
100
|
+
return Promise.resolve();
|
|
101
|
+
});
|
|
100
102
|
|
|
101
103
|
/** @type {!jasmine.Spy} */
|
|
102
104
|
this.configure = jasmine.createSpy('configure');
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
goog.provide('shaka.test.TtmlUtils');
|
|
8
|
+
|
|
9
|
+
shaka.test.TtmlUtils = class {
|
|
10
|
+
/**
|
|
11
|
+
* @param {!Array} expectedCues
|
|
12
|
+
* @param {!Array} actualCues
|
|
13
|
+
* @param {!Object} bodyProperties
|
|
14
|
+
* @param {Object=} divProperties
|
|
15
|
+
*/
|
|
16
|
+
static verifyHelper(expectedCues, actualCues, bodyProperties, divProperties) {
|
|
17
|
+
const mapExpected = (cue) => {
|
|
18
|
+
if (cue.region) {
|
|
19
|
+
cue.region = jasmine.objectContaining(cue.region);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (cue.nestedCues && (cue.nestedCues instanceof Array)) {
|
|
23
|
+
cue.nestedCues = cue.nestedCues.map(mapExpected);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (cue.isContainer == undefined) {
|
|
27
|
+
// If not specified to be true, check for isContainer to be false.
|
|
28
|
+
cue.isContainer = false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return jasmine.objectContaining(cue);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {!Object} properties
|
|
36
|
+
* @return {!shaka.extern.Cue}
|
|
37
|
+
*/
|
|
38
|
+
const makeContainer = (properties) => {
|
|
39
|
+
const region = {
|
|
40
|
+
id: '',
|
|
41
|
+
viewportAnchorX: 0,
|
|
42
|
+
viewportAnchorY: 0,
|
|
43
|
+
regionAnchorX: 0,
|
|
44
|
+
regionAnchorY: 0,
|
|
45
|
+
width: 100,
|
|
46
|
+
height: 100,
|
|
47
|
+
widthUnits: shaka.text.CueRegion.units.PERCENTAGE,
|
|
48
|
+
heightUnits: shaka.text.CueRegion.units.PERCENTAGE,
|
|
49
|
+
viewportAnchorUnits: shaka.text.CueRegion.units.PERCENTAGE,
|
|
50
|
+
scroll: '',
|
|
51
|
+
};
|
|
52
|
+
const containerCue = /** @type {!shaka.extern.Cue} */ ({
|
|
53
|
+
region,
|
|
54
|
+
nestedCues: jasmine.any(Object),
|
|
55
|
+
payload: '',
|
|
56
|
+
startTime: 0,
|
|
57
|
+
endTime: Infinity,
|
|
58
|
+
isContainer: true,
|
|
59
|
+
});
|
|
60
|
+
Object.assign(containerCue, properties);
|
|
61
|
+
return mapExpected(containerCue);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
if (expectedCues.length == 0 && !divProperties) {
|
|
65
|
+
expect(actualCues.length).toBe(0);
|
|
66
|
+
} else {
|
|
67
|
+
// Body.
|
|
68
|
+
expect(actualCues.length).toBe(1);
|
|
69
|
+
const body = actualCues[0];
|
|
70
|
+
expect(body).toEqual(makeContainer(bodyProperties));
|
|
71
|
+
|
|
72
|
+
// Div.
|
|
73
|
+
expect(body.nestedCues.length).toBe(1);
|
|
74
|
+
const div = body.nestedCues[0];
|
|
75
|
+
expect(div).toEqual(makeContainer(divProperties || bodyProperties));
|
|
76
|
+
|
|
77
|
+
// Cues.
|
|
78
|
+
expect(div.nestedCues).toEqual(expectedCues.map(mapExpected));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
};
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
goog.require('shaka.test.TtmlUtils');
|
|
7
8
|
goog.require('shaka.test.Util');
|
|
8
9
|
goog.require('shaka.text.Mp4TtmlParser');
|
|
9
10
|
goog.require('shaka.util.BufferUtils');
|
|
@@ -48,7 +49,14 @@ describe('Mp4TtmlParser', () => {
|
|
|
48
49
|
parser.parseInit(ttmlInitSegment);
|
|
49
50
|
const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0};
|
|
50
51
|
const ret = parser.parseMedia(ttmlSegmentMultipleMDAT, time);
|
|
51
|
-
|
|
52
|
+
// Bodies.
|
|
53
|
+
expect(ret.length).toBe(2);
|
|
54
|
+
// Divs.
|
|
55
|
+
expect(ret[0].nestedCues.length).toBe(1);
|
|
56
|
+
expect(ret[1].nestedCues.length).toBe(1);
|
|
57
|
+
// Cues.
|
|
58
|
+
expect(ret[0].nestedCues[0].nestedCues.length).toBe(10);
|
|
59
|
+
expect(ret[1].nestedCues[0].nestedCues.length).toBe(10);
|
|
52
60
|
});
|
|
53
61
|
|
|
54
62
|
it('accounts for offset', () => {
|
|
@@ -159,22 +167,7 @@ describe('Mp4TtmlParser', () => {
|
|
|
159
167
|
parser.parseInit(ttmlInitSegment);
|
|
160
168
|
const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0};
|
|
161
169
|
const result = parser.parseMedia(ttmlSegment, time);
|
|
162
|
-
verifyHelper(
|
|
170
|
+
shaka.test.TtmlUtils.verifyHelper(
|
|
171
|
+
cues, result, {startTime: 23, endTime: 53.5});
|
|
163
172
|
});
|
|
164
|
-
|
|
165
|
-
function verifyHelper(/** !Array */ expected, /** !Array */ actual) {
|
|
166
|
-
const mapExpected = (cue) => {
|
|
167
|
-
if (cue.region) {
|
|
168
|
-
cue.region = jasmine.objectContaining(cue.region);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (cue.nestedCues) {
|
|
172
|
-
cue.nestedCues = cue.nestedCues.map(mapExpected);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return jasmine.objectContaining(cue);
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
expect(actual).toEqual(expected.map(mapExpected));
|
|
179
|
-
}
|
|
180
173
|
});
|