shaka-player 4.2.3 → 4.3.0
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/sync-labels.yaml +1 -1
- package/.github/workflows/update-issues.yaml +1 -1
- package/AUTHORS +5 -0
- package/CHANGELOG.md +85 -39
- package/CONTRIBUTORS +5 -0
- package/README.md +14 -0
- package/demo/common/assets.js +58 -0
- package/demo/common/message_ids.js +22 -1
- package/demo/config.js +89 -5
- package/demo/demo.less +7 -1
- package/demo/index.html +8 -1
- package/demo/locales/en.json +21 -1
- package/demo/locales/source.json +82 -2
- package/demo/main.js +57 -1
- package/demo/search.js +2 -0
- package/demo/visualizer.js +337 -0
- package/demo/visualizer_button.js +103 -0
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +83 -58
- package/dist/demo.compiled.debug.map +4 -4
- package/dist/demo.compiled.js +83 -58
- package/dist/demo.compiled.map +4 -4
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +18 -11
- package/dist/locales.js +32 -32
- package/dist/receiver.compiled.debug.js +23 -19
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +23 -19
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +178 -27
- package/dist/shaka-player.compiled.debug.d.ts +178 -27
- package/dist/shaka-player.compiled.debug.externs.js +163 -32
- package/dist/shaka-player.compiled.debug.js +488 -422
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +163 -32
- package/dist/shaka-player.compiled.js +895 -857
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +178 -27
- package/dist/shaka-player.ui.debug.d.ts +178 -27
- package/dist/shaka-player.ui.debug.externs.js +163 -32
- package/dist/shaka-player.ui.debug.js +519 -450
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +163 -32
- package/dist/shaka-player.ui.js +1053 -1015
- package/dist/shaka-player.ui.map +4 -4
- package/docs/design/lcevc-architecture.png +0 -0
- package/docs/design/lcevc-demo.png +0 -0
- package/docs/design/lcevc-integration.md +72 -0
- package/docs/tutorials/fairplay.md +7 -0
- package/docs/tutorials/faq.md +1 -1
- package/docs/tutorials/ui.md +7 -7
- package/docs/tutorials/upgrade.md +6 -0
- package/externs/ima.js +13 -1
- package/externs/lcevc.js +81 -0
- package/externs/mux.js +4 -42
- package/externs/shaka/ads.js +11 -1
- package/externs/shaka/manifest_parser.js +5 -1
- package/externs/shaka/player.js +178 -15
- package/lib/abr/simple_abr_manager.js +7 -0
- package/lib/ads/ad_manager.js +0 -8
- package/lib/ads/client_side_ad.js +15 -0
- package/lib/ads/client_side_ad_manager.js +21 -8
- package/lib/ads/server_side_ad.js +15 -0
- package/lib/ads/server_side_ad_manager.js +3 -3
- package/lib/cast/cast_proxy.js +2 -1
- package/lib/cast/cast_receiver.js +19 -5
- package/lib/cast/cast_sender.js +2 -1
- package/lib/cast/cast_utils.js +18 -6
- package/lib/cea/dummy_cea_parser.js +28 -0
- package/lib/cea/i_cea_parser.js +14 -2
- package/lib/cea/mp4_cea_parser.js +87 -5
- package/lib/config/auto_show_text.js +33 -0
- package/lib/dash/dash_parser.js +1 -1
- package/lib/hls/hls_parser.js +799 -376
- package/lib/lcevc/lcevc_dil.js +152 -0
- package/lib/media/closed_caption_parser.js +9 -6
- package/lib/media/drm_engine.js +14 -6
- package/lib/media/media_source_engine.js +112 -26
- package/lib/media/playhead.js +23 -1
- package/lib/media/presentation_timeline.js +26 -11
- package/lib/media/segment_reference.js +49 -1
- package/lib/media/streaming_engine.js +145 -24
- package/lib/media/transmuxer.js +79 -18
- package/lib/offline/storage.js +1 -0
- package/lib/player.js +477 -85
- package/lib/polyfill/patchedmediakeys_apple.js +55 -1
- package/lib/text/ui_text_displayer.js +5 -5
- package/lib/text/vtt_text_parser.js +35 -1
- package/lib/util/dom_utils.js +0 -1
- package/lib/util/error.js +17 -0
- package/lib/util/fake_event.js +2 -0
- package/lib/util/id3_utils.js +300 -0
- package/lib/util/manifest_parser_utils.js +4 -0
- package/lib/util/mime_utils.js +3 -6
- package/lib/util/mp4_box_parsers.js +15 -5
- package/lib/util/platform.js +9 -1
- package/lib/util/player_configuration.js +23 -1
- package/lib/util/ts_parser.js +499 -0
- package/maintained-branches.md +2 -2
- package/package.json +4 -1
- package/roadmap.md +27 -7
- package/test/ads/ad_manager_unit.js +180 -29
- package/test/cast/cast_receiver_integration.js +97 -16
- package/test/cast/cast_receiver_unit.js +17 -12
- package/test/cast/cast_utils_unit.js +4 -1
- package/test/dash/dash_parser_content_protection_unit.js +1 -0
- package/test/dash/dash_parser_live_unit.js +1 -0
- package/test/dash/dash_parser_manifest_unit.js +93 -1
- package/test/dash/dash_parser_segment_base_unit.js +1 -0
- package/test/dash/dash_parser_segment_list_unit.js +1 -0
- package/test/dash/dash_parser_segment_template_unit.js +1 -0
- package/test/demo/demo_unit.js +2 -1
- package/test/hls/hls_live_unit.js +253 -19
- package/test/hls/hls_parser_unit.js +500 -12
- package/test/media/closed_caption_parser_unit.js +2 -1
- package/test/media/drm_engine_integration.js +3 -1
- package/test/media/media_source_engine_integration.js +102 -6
- package/test/media/media_source_engine_unit.js +10 -5
- package/test/media/playhead_unit.js +41 -0
- package/test/media/streaming_engine_integration.js +17 -1
- package/test/media/streaming_engine_unit.js +180 -24
- package/test/media/transmuxer_integration.js +21 -10
- package/test/player_integration.js +224 -82
- package/test/player_unit.js +92 -2
- package/test/polyfill/patchedmediakeys_apple_unit.js +124 -0
- package/test/test/assets/id3-metadata.aac +0 -0
- package/test/test/assets/id3-metadata.ts +0 -0
- package/test/test/assets/thumbnails-sprites.vtt +10 -0
- package/test/test/assets/thumbnails.vtt +10 -0
- package/test/test/util/dash_parser_util.js +2 -0
- package/test/test/util/fake_ad.js +21 -0
- package/test/test/util/fake_media_source_engine.js +7 -0
- package/test/test/util/id3_generator.js +100 -0
- package/test/test/util/manifest_generator.js +3 -6
- package/test/test/util/simple_fakes.js +7 -0
- package/test/test/util/stream_generator.js +38 -0
- package/test/test/util/test_scheme.js +43 -14
- package/test/text/vtt_text_parser_unit.js +11 -0
- package/test/ui/text_displayer_layout_unit.js +14 -0
- package/test/util/id3_utils_unit.js +116 -0
- package/test/util/ts_parser_unit.js +77 -0
- package/ui/controls.js +4 -1
- package/ui/less/containers.less +7 -0
- package/ui/settings_menu.js +11 -2
- package/ui/ui.js +43 -4
|
@@ -74,6 +74,8 @@ describe('StreamingEngine', () => {
|
|
|
74
74
|
let streamingEngine;
|
|
75
75
|
/** @type {!jasmine.Spy} */
|
|
76
76
|
let beforeAppendSegment;
|
|
77
|
+
/** @type {!jasmine.Spy} */
|
|
78
|
+
let onMetadata;
|
|
77
79
|
|
|
78
80
|
/** @type {function(function(), number)} */
|
|
79
81
|
let realSetTimeout;
|
|
@@ -432,6 +434,7 @@ describe('StreamingEngine', () => {
|
|
|
432
434
|
onManifestUpdate = jasmine.createSpy('onManifestUpdate');
|
|
433
435
|
onSegmentAppended = jasmine.createSpy('onSegmentAppended');
|
|
434
436
|
beforeAppendSegment = jasmine.createSpy('beforeAppendSegment');
|
|
437
|
+
onMetadata = jasmine.createSpy('onMetadata');
|
|
435
438
|
getBandwidthEstimate = jasmine.createSpy('getBandwidthEstimate');
|
|
436
439
|
getBandwidthEstimate.and.returnValue(1e3);
|
|
437
440
|
|
|
@@ -461,6 +464,7 @@ describe('StreamingEngine', () => {
|
|
|
461
464
|
onSegmentAppended: Util.spyFunc(onSegmentAppended),
|
|
462
465
|
onInitSegmentAppended: () => {},
|
|
463
466
|
beforeAppendSegment: Util.spyFunc(beforeAppendSegment),
|
|
467
|
+
onMetadata: Util.spyFunc(onMetadata),
|
|
464
468
|
};
|
|
465
469
|
streamingEngine = new shaka.media.StreamingEngine(
|
|
466
470
|
/** @type {shaka.extern.Manifest} */(manifest), playerInterface);
|
|
@@ -517,7 +521,7 @@ describe('StreamingEngine', () => {
|
|
|
517
521
|
expectedMseInit.set(ContentType.TEXT, textStream);
|
|
518
522
|
|
|
519
523
|
expect(mediaSourceEngine.init).toHaveBeenCalledWith(expectedMseInit,
|
|
520
|
-
/**
|
|
524
|
+
/** forceTransmux= */ false, /** sequenceMode= */ false);
|
|
521
525
|
expect(mediaSourceEngine.init).toHaveBeenCalledTimes(1);
|
|
522
526
|
|
|
523
527
|
expect(mediaSourceEngine.setDuration).toHaveBeenCalledTimes(1);
|
|
@@ -878,7 +882,7 @@ describe('StreamingEngine', () => {
|
|
|
878
882
|
|
|
879
883
|
const config = shaka.util.PlayerConfiguration.createDefault().streaming;
|
|
880
884
|
config.bufferingGoal = 60;
|
|
881
|
-
config.failureCallback = () => streamingEngine.retry();
|
|
885
|
+
config.failureCallback = () => streamingEngine.retry(0.1);
|
|
882
886
|
createStreamingEngine(config);
|
|
883
887
|
|
|
884
888
|
// Make requests for different types take different amounts of time.
|
|
@@ -1737,8 +1741,23 @@ describe('StreamingEngine', () => {
|
|
|
1737
1741
|
beforeEach(() => {
|
|
1738
1742
|
setupLive();
|
|
1739
1743
|
mediaSourceEngine = new shaka.test.FakeMediaSourceEngine(segmentData, 0);
|
|
1740
|
-
|
|
1744
|
+
|
|
1745
|
+
// Retry on failure for live streams.
|
|
1746
|
+
const config = shaka.util.PlayerConfiguration.createDefault().streaming;
|
|
1747
|
+
config.failureCallback = () => streamingEngine.retry(0.1);
|
|
1748
|
+
|
|
1749
|
+
createStreamingEngine(config);
|
|
1741
1750
|
presentationTimeInSeconds = 100;
|
|
1751
|
+
|
|
1752
|
+
// Ignore 404 errors in live stream tests.
|
|
1753
|
+
onError.and.callFake((error) => {
|
|
1754
|
+
if (error.code == shaka.util.Error.Code.BAD_HTTP_STATUS &&
|
|
1755
|
+
error.data[1] == 404) {
|
|
1756
|
+
// 404 error
|
|
1757
|
+
} else {
|
|
1758
|
+
fail(error);
|
|
1759
|
+
}
|
|
1760
|
+
});
|
|
1742
1761
|
});
|
|
1743
1762
|
|
|
1744
1763
|
it('outside segment availability window', async () => {
|
|
@@ -1768,24 +1787,22 @@ describe('StreamingEngine', () => {
|
|
|
1768
1787
|
const originalAppendBuffer =
|
|
1769
1788
|
// eslint-disable-next-line no-restricted-syntax
|
|
1770
1789
|
shaka.test.FakeMediaSourceEngine.prototype.appendBufferImpl;
|
|
1771
|
-
mediaSourceEngine.appendBuffer.and.callFake(
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
originalAppendBuffer);
|
|
1783
|
-
}
|
|
1790
|
+
mediaSourceEngine.appendBuffer.and.callFake((type, data, reference) => {
|
|
1791
|
+
expect(presentationTimeInSeconds).toBe(125);
|
|
1792
|
+
// Ignore a possible call for the first Period.
|
|
1793
|
+
if (reference && reference.startTime >= 100) {
|
|
1794
|
+
expect(Util.invokeSpy(timeline.getSegmentAvailabilityStart))
|
|
1795
|
+
.not.toBeLessThan(100);
|
|
1796
|
+
expect(Util.invokeSpy(timeline.getSegmentAvailabilityEnd))
|
|
1797
|
+
.not.toBeLessThan(120);
|
|
1798
|
+
playing = true;
|
|
1799
|
+
mediaSourceEngine.appendBuffer.and.callFake(originalAppendBuffer);
|
|
1800
|
+
}
|
|
1784
1801
|
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1802
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
1803
|
+
return originalAppendBuffer.call(
|
|
1804
|
+
mediaSourceEngine, type, data, reference);
|
|
1805
|
+
});
|
|
1789
1806
|
|
|
1790
1807
|
await runTest(slideSegmentAvailabilityWindow);
|
|
1791
1808
|
// Verify buffers.
|
|
@@ -2001,7 +2018,7 @@ describe('StreamingEngine', () => {
|
|
|
2001
2018
|
mediaSourceEngine = new shaka.test.FakeMediaSourceEngine(segmentData);
|
|
2002
2019
|
|
|
2003
2020
|
const config = shaka.util.PlayerConfiguration.createDefault().streaming;
|
|
2004
|
-
config.failureCallback = () => streamingEngine.retry();
|
|
2021
|
+
config.failureCallback = () => streamingEngine.retry(0.1);
|
|
2005
2022
|
createStreamingEngine(config);
|
|
2006
2023
|
|
|
2007
2024
|
presentationTimeInSeconds = 100;
|
|
@@ -2162,7 +2179,7 @@ describe('StreamingEngine', () => {
|
|
|
2162
2179
|
netEngine.request.calls.reset();
|
|
2163
2180
|
|
|
2164
2181
|
// Retry streaming.
|
|
2165
|
-
expect(streamingEngine.retry()).toBe(true);
|
|
2182
|
+
expect(streamingEngine.retry(0.1)).toBe(true);
|
|
2166
2183
|
});
|
|
2167
2184
|
|
|
2168
2185
|
// Here we go!
|
|
@@ -2192,7 +2209,7 @@ describe('StreamingEngine', () => {
|
|
|
2192
2209
|
|
|
2193
2210
|
// Retry streaming, which should fail and return false.
|
|
2194
2211
|
netEngine.request.calls.reset();
|
|
2195
|
-
expect(streamingEngine.retry()).toBe(false);
|
|
2212
|
+
expect(streamingEngine.retry(0.1)).toBe(false);
|
|
2196
2213
|
});
|
|
2197
2214
|
|
|
2198
2215
|
// Here we go!
|
|
@@ -2244,7 +2261,7 @@ describe('StreamingEngine', () => {
|
|
|
2244
2261
|
|
|
2245
2262
|
// Retry streaming, which should fail and return false.
|
|
2246
2263
|
netEngine.request.calls.reset();
|
|
2247
|
-
expect(streamingEngine.retry()).toBe(false);
|
|
2264
|
+
expect(streamingEngine.retry(0.1)).toBe(false);
|
|
2248
2265
|
}
|
|
2249
2266
|
});
|
|
2250
2267
|
|
|
@@ -2848,6 +2865,52 @@ describe('StreamingEngine', () => {
|
|
|
2848
2865
|
expect(onEvent).not.toHaveBeenCalled();
|
|
2849
2866
|
expect(onManifestUpdate).toHaveBeenCalled();
|
|
2850
2867
|
});
|
|
2868
|
+
|
|
2869
|
+
it('triggers metadata event', async () => {
|
|
2870
|
+
// This is an 'emsg' box that contains a scheme of
|
|
2871
|
+
// https://aomedia.org/emsg/ID to indicate a ID3 metadata.
|
|
2872
|
+
segmentData[ContentType.VIDEO].segments[0] =
|
|
2873
|
+
Uint8ArrayUtils.fromHex((
|
|
2874
|
+
// 105 bytes emsg box v0, flags 0
|
|
2875
|
+
'00 00 00 69 65 6d 73 67 00 00 00 00' +
|
|
2876
|
+
|
|
2877
|
+
// scheme id uri (13 bytes) 'https://aomedia.org/emsg/ID3'
|
|
2878
|
+
'68 74 74 70 73 3a 2f 2f 61 6f 6d 65 64 69 61 2e' +
|
|
2879
|
+
'6f 72 67 2f 65 6d 73 67 2f 49 44 33 00' +
|
|
2880
|
+
|
|
2881
|
+
// value (1 byte) ''
|
|
2882
|
+
'00' +
|
|
2883
|
+
|
|
2884
|
+
// timescale (4 bytes) 49
|
|
2885
|
+
'00 00 00 31' +
|
|
2886
|
+
|
|
2887
|
+
// presentation time delta (4 bytes) 8
|
|
2888
|
+
'00 00 00 08' +
|
|
2889
|
+
|
|
2890
|
+
// event duration (4 bytes) 255
|
|
2891
|
+
'00 00 00 ff' +
|
|
2892
|
+
|
|
2893
|
+
// id (4 bytes) 51
|
|
2894
|
+
'00 00 00 33' +
|
|
2895
|
+
|
|
2896
|
+
// message data (47 bytes)
|
|
2897
|
+
'49 44 33 03 00 40 00 00 00 1b 00 00 00 06 00 00' +
|
|
2898
|
+
'00 00 00 02 54 58 58 58 00 00 00 07 e0 00 03 00' +
|
|
2899
|
+
'53 68 61 6b 61 33 44 49 03 00 40 00 00 00 1b'
|
|
2900
|
+
).replace(/\s/g, ''));
|
|
2901
|
+
|
|
2902
|
+
videoStream.emsgSchemeIdUris = ['https://aomedia.org/emsg/ID3'];
|
|
2903
|
+
|
|
2904
|
+
// Here we go!
|
|
2905
|
+
streamingEngine.switchVariant(variant);
|
|
2906
|
+
streamingEngine.switchTextStream(textStream);
|
|
2907
|
+
await streamingEngine.start();
|
|
2908
|
+
playing = true;
|
|
2909
|
+
await runTest();
|
|
2910
|
+
|
|
2911
|
+
expect(onEvent).not.toHaveBeenCalled();
|
|
2912
|
+
expect(onMetadata).toHaveBeenCalled();
|
|
2913
|
+
});
|
|
2851
2914
|
});
|
|
2852
2915
|
|
|
2853
2916
|
describe('embedded emsg boxes with non zero timestamps', () => {
|
|
@@ -2912,6 +2975,99 @@ describe('StreamingEngine', () => {
|
|
|
2912
2975
|
});
|
|
2913
2976
|
});
|
|
2914
2977
|
|
|
2978
|
+
describe('embedded prft boxes', () => {
|
|
2979
|
+
const prftSegment = Uint8ArrayUtils.fromHex(
|
|
2980
|
+
'00000020707266740100000000000001E683B62E8E63CC580000001B319D5767');
|
|
2981
|
+
const mdhdSegment = Uint8ArrayUtils.fromHex(
|
|
2982
|
+
'000000446D6F6F760000003C7472616B000000346D6469610000002C6D646864'+
|
|
2983
|
+
'0100000000000000DF22526500000000DF22526500989680FFFFFFFFFFFFFFFF'+
|
|
2984
|
+
'15C70000');
|
|
2985
|
+
|
|
2986
|
+
const prftEventObj = {
|
|
2987
|
+
wallClockTime: 1658402734556,
|
|
2988
|
+
startDate: new Date(1658391054904.7898),
|
|
2989
|
+
};
|
|
2990
|
+
|
|
2991
|
+
beforeEach(() => {
|
|
2992
|
+
setupVod();
|
|
2993
|
+
mediaSourceEngine = new shaka.test.FakeMediaSourceEngine(segmentData);
|
|
2994
|
+
const config = shaka.util.PlayerConfiguration.createDefault().streaming;
|
|
2995
|
+
config.parsePrftBox = true;
|
|
2996
|
+
createStreamingEngine(config);
|
|
2997
|
+
});
|
|
2998
|
+
|
|
2999
|
+
it('raises an event for registered prft v1', async () => {
|
|
3000
|
+
segmentData[ContentType.VIDEO].segments[0] = prftSegment;
|
|
3001
|
+
segmentData[ContentType.VIDEO].initSegments[0] = mdhdSegment;
|
|
3002
|
+
|
|
3003
|
+
streamingEngine.switchVariant(variant);
|
|
3004
|
+
streamingEngine.switchTextStream(textStream);
|
|
3005
|
+
await streamingEngine.start();
|
|
3006
|
+
playing = true;
|
|
3007
|
+
await runTest();
|
|
3008
|
+
expect(onEvent).toHaveBeenCalled();
|
|
3009
|
+
|
|
3010
|
+
const event = onEvent.calls.argsFor(0)[0];
|
|
3011
|
+
expect(event.detail.wallClockTime).toBe(prftEventObj.wallClockTime);
|
|
3012
|
+
expect(event.detail.programStartDate.getUTCMilliseconds()).toBe(
|
|
3013
|
+
prftEventObj.startDate.getUTCMilliseconds());
|
|
3014
|
+
expect(event.detail.programStartDate.toUTCString()).toBe(
|
|
3015
|
+
prftEventObj.startDate.toUTCString());
|
|
3016
|
+
});
|
|
3017
|
+
|
|
3018
|
+
it('raises an event for registered prft v0', async () => {
|
|
3019
|
+
const prftSegment = Uint8ArrayUtils.fromHex(
|
|
3020
|
+
'0000001C707266740000000000000001E683B62E8E63CC5819999999');
|
|
3021
|
+
const expectedStartDate = new Date(1658402691606.3271);
|
|
3022
|
+
segmentData[ContentType.VIDEO].segments[0] = prftSegment;
|
|
3023
|
+
segmentData[ContentType.VIDEO].initSegments[0] = mdhdSegment;
|
|
3024
|
+
|
|
3025
|
+
streamingEngine.switchVariant(variant);
|
|
3026
|
+
streamingEngine.switchTextStream(textStream);
|
|
3027
|
+
await streamingEngine.start();
|
|
3028
|
+
playing = true;
|
|
3029
|
+
await runTest();
|
|
3030
|
+
expect(onEvent).toHaveBeenCalled();
|
|
3031
|
+
|
|
3032
|
+
const event = onEvent.calls.argsFor(0)[0];
|
|
3033
|
+
expect(event.detail.wallClockTime).toBe(prftEventObj.wallClockTime);
|
|
3034
|
+
expect(event.detail.programStartDate.getUTCMilliseconds()).toBe(
|
|
3035
|
+
expectedStartDate.getUTCMilliseconds());
|
|
3036
|
+
expect(event.detail.programStartDate.toUTCString()).toBe(
|
|
3037
|
+
expectedStartDate.toUTCString());
|
|
3038
|
+
});
|
|
3039
|
+
|
|
3040
|
+
it('does not raise event if mediatime exceeds Number.MAX_VALUE',
|
|
3041
|
+
async () => {
|
|
3042
|
+
const prftSegment = Uint8ArrayUtils.fromHex(
|
|
3043
|
+
'00000020707266740100000000000001E683B62E8E63CC58'+
|
|
3044
|
+
'FFFFFFFFFFFFFFFF');
|
|
3045
|
+
segmentData[ContentType.VIDEO].segments[0] = prftSegment;
|
|
3046
|
+
segmentData[ContentType.VIDEO].initSegments[0] = mdhdSegment;
|
|
3047
|
+
|
|
3048
|
+
streamingEngine.switchVariant(variant);
|
|
3049
|
+
streamingEngine.switchTextStream(textStream);
|
|
3050
|
+
await streamingEngine.start();
|
|
3051
|
+
playing = true;
|
|
3052
|
+
await runTest();
|
|
3053
|
+
expect(onEvent).not.toHaveBeenCalled();
|
|
3054
|
+
});
|
|
3055
|
+
|
|
3056
|
+
it('raises an event once only', async () => {
|
|
3057
|
+
segmentData[ContentType.VIDEO].segments[0] =
|
|
3058
|
+
shaka.util.Uint8ArrayUtils.concat(prftSegment, prftSegment);
|
|
3059
|
+
segmentData[ContentType.VIDEO].segments[1] = prftSegment;
|
|
3060
|
+
segmentData[ContentType.VIDEO].initSegments[0] = mdhdSegment;
|
|
3061
|
+
|
|
3062
|
+
streamingEngine.switchVariant(variant);
|
|
3063
|
+
streamingEngine.switchTextStream(textStream);
|
|
3064
|
+
await streamingEngine.start();
|
|
3065
|
+
playing = true;
|
|
3066
|
+
await runTest();
|
|
3067
|
+
expect(onEvent).toHaveBeenCalledTimes(1);
|
|
3068
|
+
});
|
|
3069
|
+
});
|
|
3070
|
+
|
|
2915
3071
|
describe('network downgrading', () => {
|
|
2916
3072
|
/** @type {shaka.extern.Variant} */
|
|
2917
3073
|
let initialVariant;
|
|
@@ -12,6 +12,9 @@ describe('Transmuxer', () => {
|
|
|
12
12
|
const mp4MimeType = 'video/mp4; codecs="avc1.42E01E"';
|
|
13
13
|
const transportStreamVideoMimeType = 'video/mp2t; codecs="avc1.42E01E"';
|
|
14
14
|
const transportStreamAudioMimeType = 'video/mp2t; codecs="mp4a.40.2"';
|
|
15
|
+
const aacAudioMimeType = 'audio/aac';
|
|
16
|
+
|
|
17
|
+
const transmuxerMimeType = 'fake/mimeType';
|
|
15
18
|
|
|
16
19
|
/** @type {!ArrayBuffer} */
|
|
17
20
|
let videoSegment;
|
|
@@ -35,7 +38,7 @@ describe('Transmuxer', () => {
|
|
|
35
38
|
});
|
|
36
39
|
|
|
37
40
|
beforeEach(() => {
|
|
38
|
-
transmuxer = new shaka.media.Transmuxer();
|
|
41
|
+
transmuxer = new shaka.media.Transmuxer(transmuxerMimeType);
|
|
39
42
|
});
|
|
40
43
|
|
|
41
44
|
afterEach(async () => {
|
|
@@ -59,42 +62,50 @@ describe('Transmuxer', () => {
|
|
|
59
62
|
});
|
|
60
63
|
});
|
|
61
64
|
|
|
62
|
-
describe('
|
|
63
|
-
const
|
|
64
|
-
(type, codecs) => shaka.media.Transmuxer.
|
|
65
|
+
describe('convertCodecs', () => {
|
|
66
|
+
const convertCodecs =
|
|
67
|
+
(type, codecs) => shaka.media.Transmuxer.convertCodecs(type, codecs);
|
|
65
68
|
|
|
66
69
|
it('returns converted codecs', () => {
|
|
67
70
|
const convertedVideoCodecs =
|
|
68
|
-
|
|
71
|
+
convertCodecs(ContentType.VIDEO, transportStreamVideoMimeType);
|
|
69
72
|
const convertedAudioCodecs =
|
|
70
|
-
|
|
73
|
+
convertCodecs(ContentType.AUDIO, transportStreamAudioMimeType);
|
|
74
|
+
const convertedAacCodecs =
|
|
75
|
+
convertCodecs(ContentType.AUDIO, aacAudioMimeType);
|
|
71
76
|
const expectedVideoCodecs = 'video/mp4; codecs="avc1.42E01E"';
|
|
72
77
|
const expectedAudioCodecs = 'audio/mp4; codecs="mp4a.40.2"';
|
|
78
|
+
const expectedAacCodecs = 'audio/mp4; codecs="mp4a.40.2"';
|
|
73
79
|
expect(convertedVideoCodecs).toBe(expectedVideoCodecs);
|
|
74
80
|
expect(convertedAudioCodecs).toBe(expectedAudioCodecs);
|
|
81
|
+
expect(convertedAacCodecs).toBe(expectedAacCodecs);
|
|
75
82
|
});
|
|
76
83
|
|
|
77
84
|
it('converts legacy avc1 codec strings', () => {
|
|
78
85
|
expect(
|
|
79
|
-
|
|
86
|
+
convertCodecs(
|
|
80
87
|
ContentType.VIDEO, 'video/mp2t; codecs="avc1.100.42"'))
|
|
81
88
|
.toBe('video/mp4; codecs="avc1.64002a"');
|
|
82
89
|
expect(
|
|
83
|
-
|
|
90
|
+
convertCodecs(ContentType.VIDEO, 'video/mp2t; codecs="avc1.77.80"'))
|
|
84
91
|
.toBe('video/mp4; codecs="avc1.4d0050"');
|
|
85
92
|
expect(
|
|
86
|
-
|
|
93
|
+
convertCodecs(ContentType.VIDEO, 'video/mp2t; codecs="avc1.66.1"'))
|
|
87
94
|
.toBe('video/mp4; codecs="avc1.420001"');
|
|
88
95
|
});
|
|
89
96
|
|
|
90
97
|
// Issue #1991
|
|
91
98
|
it('handles upper-case MIME types', () => {
|
|
92
|
-
expect(
|
|
99
|
+
expect(convertCodecs(
|
|
93
100
|
ContentType.VIDEO, 'video/MP2T; codecs="avc1.420001"'))
|
|
94
101
|
.toBe('video/mp4; codecs="avc1.420001"');
|
|
95
102
|
});
|
|
96
103
|
});
|
|
97
104
|
|
|
105
|
+
it('getOrginalMimeType returns the correct mimeType', () => {
|
|
106
|
+
expect(transmuxer.getOrginalMimeType()).toBe(transmuxerMimeType);
|
|
107
|
+
});
|
|
108
|
+
|
|
98
109
|
describe('transmuxing', () => {
|
|
99
110
|
it('transmux video from TS to MP4', async () => {
|
|
100
111
|
let sawMDAT = false;
|