shaka-player 4.3.2 → 4.3.3
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/CHANGELOG.md +20 -0
- package/dist/deps.js +1 -1
- package/dist/locales.js +32 -32
- package/dist/shaka-player.compiled.d.ts +10 -0
- package/dist/shaka-player.compiled.debug.d.ts +10 -0
- package/dist/shaka-player.compiled.debug.externs.js +12 -0
- package/dist/shaka-player.compiled.debug.js +120 -117
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.externs.js +12 -0
- package/dist/shaka-player.compiled.js +622 -619
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.d.ts +10 -0
- package/dist/shaka-player.ui.debug.d.ts +10 -0
- package/dist/shaka-player.ui.debug.externs.js +12 -0
- package/dist/shaka-player.ui.debug.js +132 -130
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.externs.js +12 -0
- package/dist/shaka-player.ui.js +408 -406
- package/dist/shaka-player.ui.map +3 -3
- package/lib/hls/hls_parser.js +39 -15
- package/lib/media/media_source_engine.js +34 -4
- package/lib/media/segment_index.js +5 -10
- package/lib/media/segment_reference.js +39 -0
- package/lib/media/streaming_engine.js +15 -3
- package/lib/player.js +7 -1
- package/lib/text/ui_text_displayer.js +24 -4
- package/lib/text/web_vtt_generator.js +21 -9
- package/lib/util/dom_utils.js +3 -1
- package/lib/util/stream_utils.js +6 -0
- package/lib/util/timer.js +17 -0
- package/package.json +1 -1
- package/test/hls/hls_live_unit.js +8 -30
- package/test/hls/hls_parser_unit.js +30 -0
- package/test/media/segment_index_unit.js +28 -0
- package/test/media/streaming_engine_unit.js +91 -119
- package/test/player_integration.js +27 -0
- package/test/player_unit.js +4 -2
- package/test/text/ui_text_displayer_unit.js +70 -0
|
@@ -2728,9 +2728,67 @@ describe('StreamingEngine', () => {
|
|
|
2728
2728
|
});
|
|
2729
2729
|
|
|
2730
2730
|
describe('embedded emsg boxes', () => {
|
|
2731
|
-
|
|
2731
|
+
// V0 box format
|
|
2732
|
+
const emsgSegmentV0 = Uint8ArrayUtils.fromHex(
|
|
2732
2733
|
'0000003b656d736700000000666f6f3a6261723a637573746f6d646174617363' +
|
|
2733
2734
|
'68656d6500310000000001000000080000ffff0000000174657374');
|
|
2735
|
+
|
|
2736
|
+
// V1 box format
|
|
2737
|
+
const emsgSegmentV1 = Uint8ArrayUtils.fromHex(
|
|
2738
|
+
'0000003f656d7367010000000000000100000000000000080000ffff00000001' +
|
|
2739
|
+
'666f6f3a6261723a637573746f6d64617461736368656d6500310074657374');
|
|
2740
|
+
|
|
2741
|
+
// V1 box format, non-zero start time
|
|
2742
|
+
const emsgSegmentV1NonZeroStart = Uint8ArrayUtils.fromHex(
|
|
2743
|
+
'0000003f656d7367010000000000000100000000000000120000ffff00000001' +
|
|
2744
|
+
'666f6f3a6261723a637573746f6d64617461736368656d6500310074657374');
|
|
2745
|
+
|
|
2746
|
+
const dummyBox = Uint8ArrayUtils.fromHex('0000000c6672656501020304');
|
|
2747
|
+
|
|
2748
|
+
const emsgSegmentV0Twice =
|
|
2749
|
+
Uint8ArrayUtils.concat(emsgSegmentV0, dummyBox, emsgSegmentV0);
|
|
2750
|
+
|
|
2751
|
+
// This is an 'emsg' box that contains a scheme of
|
|
2752
|
+
// urn:mpeg:dash:event:2012 to indicate a manifest update.
|
|
2753
|
+
const emsgSegmentV0ReloadManifest = Uint8ArrayUtils.fromHex(
|
|
2754
|
+
'0000003a656d73670000000075726e3a6d7065673a646173683a6576656e743a' +
|
|
2755
|
+
'3230313200000000003100000008000000ff0000000c74657374');
|
|
2756
|
+
|
|
2757
|
+
const reloadManifestSchemeUri = 'urn:mpeg:dash:event:2012';
|
|
2758
|
+
|
|
2759
|
+
// This is an 'emsg' box that contains a scheme of
|
|
2760
|
+
// https://aomedia.org/emsg/ID to indicate a ID3 metadata.
|
|
2761
|
+
const emsgSegmentV0ID3 = Uint8ArrayUtils.fromHex((
|
|
2762
|
+
// 105 bytes emsg box v0, flags 0
|
|
2763
|
+
'00 00 00 69 65 6d 73 67 00 00 00 00' +
|
|
2764
|
+
|
|
2765
|
+
// scheme id uri (13 bytes) 'https://aomedia.org/emsg/ID3'
|
|
2766
|
+
'68 74 74 70 73 3a 2f 2f 61 6f 6d 65 64 69 61 2e' +
|
|
2767
|
+
'6f 72 67 2f 65 6d 73 67 2f 49 44 33 00' +
|
|
2768
|
+
|
|
2769
|
+
// value (1 byte) ''
|
|
2770
|
+
'00' +
|
|
2771
|
+
|
|
2772
|
+
// timescale (4 bytes) 49
|
|
2773
|
+
'00 00 00 31' +
|
|
2774
|
+
|
|
2775
|
+
// presentation time delta (4 bytes) 8
|
|
2776
|
+
'00 00 00 08' +
|
|
2777
|
+
|
|
2778
|
+
// event duration (4 bytes) 255
|
|
2779
|
+
'00 00 00 ff' +
|
|
2780
|
+
|
|
2781
|
+
// id (4 bytes) 51
|
|
2782
|
+
'00 00 00 33' +
|
|
2783
|
+
|
|
2784
|
+
// message data (47 bytes)
|
|
2785
|
+
'49 44 33 03 00 40 00 00 00 1b 00 00 00 06 00 00' +
|
|
2786
|
+
'00 00 00 02 54 58 58 58 00 00 00 07 e0 00 03 00' +
|
|
2787
|
+
'53 68 61 6b 61 33 44 49 03 00 40 00 00 00 1b'
|
|
2788
|
+
).replace(/\s/g, ''));
|
|
2789
|
+
|
|
2790
|
+
const id3SchemeUri = 'https://aomedia.org/emsg/ID3';
|
|
2791
|
+
|
|
2734
2792
|
const emsgObj = {
|
|
2735
2793
|
startTime: 8,
|
|
2736
2794
|
endTime: 0xffff + 8,
|
|
@@ -2743,14 +2801,31 @@ describe('StreamingEngine', () => {
|
|
|
2743
2801
|
messageData: new Uint8Array([0x74, 0x65, 0x73, 0x74]),
|
|
2744
2802
|
};
|
|
2745
2803
|
|
|
2804
|
+
const emsgObjWithOffset = {
|
|
2805
|
+
startTime: -2,
|
|
2806
|
+
endTime: 0xffff - 2,
|
|
2807
|
+
schemeIdUri: 'foo:bar:customdatascheme',
|
|
2808
|
+
value: '1',
|
|
2809
|
+
timescale: 1,
|
|
2810
|
+
presentationTimeDelta: -2,
|
|
2811
|
+
eventDuration: 0xffff,
|
|
2812
|
+
id: 1,
|
|
2813
|
+
messageData: new Uint8Array([0x74, 0x65, 0x73, 0x74]),
|
|
2814
|
+
};
|
|
2815
|
+
|
|
2746
2816
|
beforeEach(() => {
|
|
2747
|
-
|
|
2817
|
+
// setup an offset for the timestamps.
|
|
2818
|
+
setupVod(false, 10);
|
|
2748
2819
|
mediaSourceEngine = new shaka.test.FakeMediaSourceEngine(segmentData);
|
|
2749
2820
|
createStreamingEngine();
|
|
2750
2821
|
});
|
|
2751
2822
|
|
|
2823
|
+
function setSegment0(emsgBox) {
|
|
2824
|
+
segmentData[ContentType.VIDEO].segments[0] = emsgBox;
|
|
2825
|
+
}
|
|
2826
|
+
|
|
2752
2827
|
it('raises an event for registered embedded emsg boxes', async () => {
|
|
2753
|
-
|
|
2828
|
+
setSegment0(emsgSegmentV0);
|
|
2754
2829
|
videoStream.emsgSchemeIdUris = [emsgObj.schemeIdUri];
|
|
2755
2830
|
|
|
2756
2831
|
// Here we go!
|
|
@@ -2767,12 +2842,8 @@ describe('StreamingEngine', () => {
|
|
|
2767
2842
|
});
|
|
2768
2843
|
|
|
2769
2844
|
it('raises an event for registered embedded v1 emsg boxes', async () => {
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
'0000003f656d7367010000000000000100000000000000080000ffff00000001' +
|
|
2773
|
-
'666f6f3a6261723a637573746f6d64617461736368656d6500310074657374');
|
|
2774
|
-
segmentData[ContentType.VIDEO].segments[0] = v1EmsgSegment;
|
|
2775
|
-
videoStream.emsgSchemeIdUris = [emsgObj.schemeIdUri];
|
|
2845
|
+
setSegment0(emsgSegmentV1);
|
|
2846
|
+
videoStream.emsgSchemeIdUris = [emsgObjWithOffset.schemeIdUri];
|
|
2776
2847
|
|
|
2777
2848
|
// Here we go!
|
|
2778
2849
|
streamingEngine.switchVariant(variant);
|
|
@@ -2784,14 +2855,11 @@ describe('StreamingEngine', () => {
|
|
|
2784
2855
|
expect(onEvent).toHaveBeenCalledTimes(1);
|
|
2785
2856
|
|
|
2786
2857
|
const event = onEvent.calls.argsFor(0)[0];
|
|
2787
|
-
expect(event.detail).toEqual(
|
|
2858
|
+
expect(event.detail).toEqual(emsgObjWithOffset);
|
|
2788
2859
|
});
|
|
2789
2860
|
|
|
2790
2861
|
it('raises multiple events', async () => {
|
|
2791
|
-
|
|
2792
|
-
shaka.util.Uint8ArrayUtils.fromHex('0000000c6672656501020304');
|
|
2793
|
-
segmentData[ContentType.VIDEO].segments[0] =
|
|
2794
|
-
shaka.util.Uint8ArrayUtils.concat(emsgSegment, dummyBox, emsgSegment);
|
|
2862
|
+
setSegment0(emsgSegmentV0Twice);
|
|
2795
2863
|
videoStream.emsgSchemeIdUris = [emsgObj.schemeIdUri];
|
|
2796
2864
|
|
|
2797
2865
|
// Here we go!
|
|
@@ -2804,8 +2872,8 @@ describe('StreamingEngine', () => {
|
|
|
2804
2872
|
expect(onEvent).toHaveBeenCalledTimes(2);
|
|
2805
2873
|
});
|
|
2806
2874
|
|
|
2807
|
-
it('won\'t raise an event
|
|
2808
|
-
|
|
2875
|
+
it('won\'t raise an event for an unregistered emsg box', async () => {
|
|
2876
|
+
setSegment0(emsgSegmentV0);
|
|
2809
2877
|
|
|
2810
2878
|
// Here we go!
|
|
2811
2879
|
streamingEngine.switchVariant(variant);
|
|
@@ -2830,30 +2898,9 @@ describe('StreamingEngine', () => {
|
|
|
2830
2898
|
expect(onEvent).not.toHaveBeenCalled();
|
|
2831
2899
|
});
|
|
2832
2900
|
|
|
2833
|
-
it('won\'t raise an event for an unregistered emsg box', async () => {
|
|
2834
|
-
segmentData[ContentType.VIDEO].segments[0] = emsgSegment;
|
|
2835
|
-
|
|
2836
|
-
// Here we go!
|
|
2837
|
-
streamingEngine.switchVariant(variant);
|
|
2838
|
-
streamingEngine.switchTextStream(textStream);
|
|
2839
|
-
await streamingEngine.start();
|
|
2840
|
-
playing = true;
|
|
2841
|
-
await runTest();
|
|
2842
|
-
|
|
2843
|
-
expect(onEvent).not.toHaveBeenCalled();
|
|
2844
|
-
});
|
|
2845
|
-
|
|
2846
2901
|
it('triggers manifest updates', async () => {
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
segmentData[ContentType.VIDEO].segments[0] =
|
|
2850
|
-
Uint8ArrayUtils
|
|
2851
|
-
.fromHex(
|
|
2852
|
-
'0000003a656d73670000000075726e3a' +
|
|
2853
|
-
'6d7065673a646173683a6576656e743a' +
|
|
2854
|
-
'32303132000000000031000000080000' +
|
|
2855
|
-
'00ff0000000c74657374');
|
|
2856
|
-
videoStream.emsgSchemeIdUris = ['urn:mpeg:dash:event:2012'];
|
|
2902
|
+
setSegment0(emsgSegmentV0ReloadManifest);
|
|
2903
|
+
videoStream.emsgSchemeIdUris = [reloadManifestSchemeUri];
|
|
2857
2904
|
|
|
2858
2905
|
// Here we go!
|
|
2859
2906
|
streamingEngine.switchVariant(variant);
|
|
@@ -2867,39 +2914,8 @@ describe('StreamingEngine', () => {
|
|
|
2867
2914
|
});
|
|
2868
2915
|
|
|
2869
2916
|
it('triggers metadata event', async () => {
|
|
2870
|
-
|
|
2871
|
-
|
|
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'];
|
|
2917
|
+
setSegment0(emsgSegmentV0ID3);
|
|
2918
|
+
videoStream.emsgSchemeIdUris = [id3SchemeUri];
|
|
2903
2919
|
|
|
2904
2920
|
// Here we go!
|
|
2905
2921
|
streamingEngine.switchVariant(variant);
|
|
@@ -2911,54 +2927,10 @@ describe('StreamingEngine', () => {
|
|
|
2911
2927
|
expect(onEvent).not.toHaveBeenCalled();
|
|
2912
2928
|
expect(onMetadata).toHaveBeenCalled();
|
|
2913
2929
|
});
|
|
2914
|
-
});
|
|
2915
|
-
|
|
2916
|
-
describe('embedded emsg boxes with non zero timestamps', () => {
|
|
2917
|
-
const emsgSegment = Uint8ArrayUtils.fromHex(
|
|
2918
|
-
'0000003b656d736700000000666f6f3a6261723a637573746f6d646174617363' +
|
|
2919
|
-
'68656d6500310000000001000000080000ffff0000000174657374');
|
|
2920
|
-
const emsgObj = {
|
|
2921
|
-
startTime: 8,
|
|
2922
|
-
endTime: 0xffff + 8,
|
|
2923
|
-
schemeIdUri: 'foo:bar:customdatascheme',
|
|
2924
|
-
value: '1',
|
|
2925
|
-
timescale: 1,
|
|
2926
|
-
presentationTimeDelta: 8,
|
|
2927
|
-
eventDuration: 0xffff,
|
|
2928
|
-
id: 1,
|
|
2929
|
-
messageData: new Uint8Array([0x74, 0x65, 0x73, 0x74]),
|
|
2930
|
-
};
|
|
2931
|
-
|
|
2932
|
-
beforeEach(() => {
|
|
2933
|
-
// setup an offset for the timestamps.
|
|
2934
|
-
setupVod(false, 10);
|
|
2935
|
-
mediaSourceEngine = new shaka.test.FakeMediaSourceEngine(segmentData);
|
|
2936
|
-
createStreamingEngine();
|
|
2937
|
-
});
|
|
2938
|
-
|
|
2939
|
-
it('event start matches presentation times for emsg boxes', async () => {
|
|
2940
|
-
segmentData[ContentType.VIDEO].segments[0] = emsgSegment;
|
|
2941
|
-
videoStream.emsgSchemeIdUris = [emsgObj.schemeIdUri];
|
|
2942
|
-
|
|
2943
|
-
// Here we go!
|
|
2944
|
-
streamingEngine.switchVariant(variant);
|
|
2945
|
-
streamingEngine.switchTextStream(textStream);
|
|
2946
|
-
await streamingEngine.start();
|
|
2947
|
-
playing = true;
|
|
2948
|
-
await runTest();
|
|
2949
|
-
|
|
2950
|
-
expect(onEvent).toHaveBeenCalledTimes(1);
|
|
2951
|
-
|
|
2952
|
-
const event = onEvent.calls.argsFor(0)[0];
|
|
2953
|
-
expect(event.detail).toEqual(emsgObj);
|
|
2954
|
-
});
|
|
2955
2930
|
|
|
2956
|
-
it('event start matches presentation time
|
|
2957
|
-
//
|
|
2958
|
-
|
|
2959
|
-
'0000003f656d7367010000000000000100000000000000120000ffff00000001' +
|
|
2960
|
-
'666f6f3a6261723a637573746f6d64617461736368656d6500310074657374');
|
|
2961
|
-
segmentData[ContentType.VIDEO].segments[0] = v1EmsgSegment;
|
|
2931
|
+
it('event start matches presentation time', async () => {
|
|
2932
|
+
// This box has a non-zero event time, which doesn't matter.
|
|
2933
|
+
setSegment0(emsgSegmentV1NonZeroStart);
|
|
2962
2934
|
videoStream.emsgSchemeIdUris = [emsgObj.schemeIdUri];
|
|
2963
2935
|
|
|
2964
2936
|
// Here we go!
|
|
@@ -72,6 +72,33 @@ describe('Player', () => {
|
|
|
72
72
|
});
|
|
73
73
|
}); // describe('attach')
|
|
74
74
|
|
|
75
|
+
describe('destroy', () => {
|
|
76
|
+
// Regression test for:
|
|
77
|
+
// https://github.com/shaka-project/shaka-player/issues/4850
|
|
78
|
+
it('does not leave any lingering timers', async () => {
|
|
79
|
+
shaka.util.Timer.activeTimers.clear();
|
|
80
|
+
|
|
81
|
+
// Unlike the other tests in this file, this uses an uncompiled build of
|
|
82
|
+
// Shaka, so that we don't need to expose shaka.util.Timer.activeTimers.
|
|
83
|
+
player = new shaka.Player(video);
|
|
84
|
+
waiter.setPlayer(player);
|
|
85
|
+
|
|
86
|
+
// Play the video for a little while.
|
|
87
|
+
await player.load('test:sintel');
|
|
88
|
+
video.play();
|
|
89
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 1, 10);
|
|
90
|
+
|
|
91
|
+
// Destroy the player.
|
|
92
|
+
await player.destroy();
|
|
93
|
+
|
|
94
|
+
// Are there any timers left?
|
|
95
|
+
for (const timer of shaka.util.Timer.activeTimers.keys()) {
|
|
96
|
+
const stackTrace = shaka.util.Timer.activeTimers.get(timer);
|
|
97
|
+
fail('Lingering timer exists! Stack trace of creation: ' + stackTrace);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
75
102
|
describe('updateStartTime() in manifestparsed event handler', () => {
|
|
76
103
|
it('does not get segments prior to startTime', async () => {
|
|
77
104
|
player.addEventListener('manifestparsed', () => {
|
package/test/player_unit.js
CHANGED
|
@@ -3393,7 +3393,9 @@ describe('Player', () => {
|
|
|
3393
3393
|
variant.addAudio(0, (stream) => {
|
|
3394
3394
|
stream.channelsCount = 6;
|
|
3395
3395
|
stream.audioSamplingRate = 48000;
|
|
3396
|
-
|
|
3396
|
+
// ac-3 is rewritten as ec-3 on Tizen, so for the stability of this
|
|
3397
|
+
// test case, use ec-3.
|
|
3398
|
+
stream.codecs = 'ec-3';
|
|
3397
3399
|
});
|
|
3398
3400
|
});
|
|
3399
3401
|
|
|
@@ -3418,7 +3420,7 @@ describe('Player', () => {
|
|
|
3418
3420
|
expect(abrManager.variants.length).toBe(1);
|
|
3419
3421
|
// It should be the 6-channel variant, based on our preference.
|
|
3420
3422
|
expect(abrManager.variants[0].audio.channelsCount).toBe(6);
|
|
3421
|
-
expect(abrManager.variants[0].audio.codecs).toBe('
|
|
3423
|
+
expect(abrManager.variants[0].audio.codecs).toBe('ec-3');
|
|
3422
3424
|
});
|
|
3423
3425
|
});
|
|
3424
3426
|
|
|
@@ -537,4 +537,74 @@ describe('UITextDisplayer', () => {
|
|
|
537
537
|
'.shaka-text-region');
|
|
538
538
|
expect(allRegionElements.length).toBe(1);
|
|
539
539
|
});
|
|
540
|
+
|
|
541
|
+
it('creates separate regions when dimensions differ but id same', () => {
|
|
542
|
+
const identicalRegionId = 'regionId';
|
|
543
|
+
|
|
544
|
+
const cueRegion1 = new shaka.text.CueRegion();
|
|
545
|
+
const cueRegion2 = new shaka.text.CueRegion();
|
|
546
|
+
cueRegion1.id = identicalRegionId;
|
|
547
|
+
cueRegion2.id = identicalRegionId;
|
|
548
|
+
|
|
549
|
+
cueRegion1.height = 80;
|
|
550
|
+
cueRegion1.heightUnits = shaka.text.CueRegion.units.PERCENTAGE;
|
|
551
|
+
cueRegion1.width = 80;
|
|
552
|
+
cueRegion1.widthUnits = shaka.text.CueRegion.units.PERCENTAGE;
|
|
553
|
+
|
|
554
|
+
cueRegion2.height = 160; // the only difference!
|
|
555
|
+
cueRegion2.heightUnits = shaka.text.CueRegion.units.PERCENTAGE;
|
|
556
|
+
cueRegion2.width = 80;
|
|
557
|
+
cueRegion2.widthUnits = shaka.text.CueRegion.units.PERCENTAGE;
|
|
558
|
+
|
|
559
|
+
cueRegion1.viewportAnchorX = 10;
|
|
560
|
+
cueRegion1.viewportAnchorY = 10;
|
|
561
|
+
cueRegion1.viewportAnchorUnits = shaka.text.CueRegion.units.PERCENTAGE;
|
|
562
|
+
|
|
563
|
+
cueRegion2.viewportAnchorX = 10;
|
|
564
|
+
cueRegion2.viewportAnchorY = 10;
|
|
565
|
+
cueRegion2.viewportAnchorUnits = shaka.text.CueRegion.units.PERCENTAGE;
|
|
566
|
+
|
|
567
|
+
// These all attach to the same region, but only one region element should
|
|
568
|
+
// be created.
|
|
569
|
+
const firstBatchOfCues = [
|
|
570
|
+
new shaka.text.Cue(0, 100, ''),
|
|
571
|
+
new shaka.text.Cue(0, 100, ''),
|
|
572
|
+
new shaka.text.Cue(0, 100, ''),
|
|
573
|
+
];
|
|
574
|
+
for (const cue of firstBatchOfCues) {
|
|
575
|
+
cue.displayAlign = shaka.text.Cue.displayAlign.CENTER;
|
|
576
|
+
cue.region = cueRegion1;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// Another batch for the other region
|
|
580
|
+
const secondBatchOfCues = [
|
|
581
|
+
new shaka.text.Cue(0, 100, ''),
|
|
582
|
+
new shaka.text.Cue(0, 100, ''),
|
|
583
|
+
new shaka.text.Cue(0, 100, ''),
|
|
584
|
+
];
|
|
585
|
+
for (const cue of secondBatchOfCues) {
|
|
586
|
+
cue.displayAlign = shaka.text.Cue.displayAlign.CENTER;
|
|
587
|
+
cue.region = cueRegion2;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
textDisplayer.setTextVisibility(true);
|
|
591
|
+
textDisplayer.append(firstBatchOfCues);
|
|
592
|
+
textDisplayer.append(secondBatchOfCues);
|
|
593
|
+
updateCaptions();
|
|
594
|
+
|
|
595
|
+
const textContainer = videoContainer.querySelector('.shaka-text-container');
|
|
596
|
+
const allRegionElements = textContainer.querySelectorAll(
|
|
597
|
+
'.shaka-text-region');
|
|
598
|
+
|
|
599
|
+
// Verify that the nested cues are attached to respective region element.
|
|
600
|
+
expect(allRegionElements.length).toBe(2);
|
|
601
|
+
|
|
602
|
+
const childrenOfOne = Array.from(allRegionElements[0].childNodes).filter(
|
|
603
|
+
(e) => e.nodeType == Node.ELEMENT_NODE);
|
|
604
|
+
expect(childrenOfOne.length).toBe(3);
|
|
605
|
+
|
|
606
|
+
const childrenOfTwo = Array.from(allRegionElements[1].childNodes).filter(
|
|
607
|
+
(e) => e.nodeType == Node.ELEMENT_NODE);
|
|
608
|
+
expect(childrenOfTwo.length).toBe(3);
|
|
609
|
+
});
|
|
540
610
|
});
|