@@ -120,8 +120,10 @@ describe('StreamingEngine', () => {
120
120
jasmine . clock ( ) . mockDate ( ) ;
121
121
} ) ;
122
122
123
- /** @param {boolean= } trickMode */
124
- function setupVod ( trickMode ) {
123
+ /** @param {boolean= } trickMode
124
+ * @param {number= } mediaOffset The offset from 0 for the segment start times
125
+ */
126
+ function setupVod ( trickMode , mediaOffset ) {
125
127
// For VOD, we fake a presentation that has 2 Periods of equal duration
126
128
// (20 seconds), where each Period has 1 Variant and 1 text stream.
127
129
//
@@ -132,6 +134,11 @@ describe('StreamingEngine', () => {
132
134
// first Period, and 2 audio, 2 video, and 2 text for the second Period.
133
135
// All media segments are (by default) 10 seconds long.
134
136
137
+ const offset = mediaOffset || 0 ;
138
+ // timestampOffset is -ve since it is added to bring the timeline to 0.
139
+ // -0 and 0 are not same so explicitly set to 0.
140
+ const timestampOffset = offset === 0 ? 0 : - offset ;
141
+
135
142
// Create SegmentData map for FakeMediaSourceEngine.
136
143
const initSegmentSizeAudio = initSegmentRanges [ ContentType . AUDIO ] [ 1 ] -
137
144
initSegmentRanges [ ContentType . AUDIO ] [ 0 ] + 1 ;
@@ -151,8 +158,9 @@ describe('StreamingEngine', () => {
151
158
makeBuffer ( segmentSizes [ ContentType . AUDIO ] ) ,
152
159
makeBuffer ( segmentSizes [ ContentType . AUDIO ] ) ,
153
160
] ,
154
- segmentStartTimes : [ 0 , 10 , 20 , 30 ] ,
161
+ segmentStartTimes : [ offset , offset + 10 , offset + 20 , offset + 30 ] ,
155
162
segmentDuration : 10 ,
163
+ timestampOffset : timestampOffset ,
156
164
} ,
157
165
video : {
158
166
initSegments : [
@@ -165,8 +173,9 @@ describe('StreamingEngine', () => {
165
173
makeBuffer ( segmentSizes [ ContentType . VIDEO ] ) ,
166
174
makeBuffer ( segmentSizes [ ContentType . VIDEO ] ) ,
167
175
] ,
168
- segmentStartTimes : [ 0 , 10 , 20 , 30 ] ,
176
+ segmentStartTimes : [ offset , offset + 10 , offset + 20 , offset + 30 ] ,
169
177
segmentDuration : 10 ,
178
+ timestampOffset : timestampOffset ,
170
179
} ,
171
180
text : {
172
181
initSegments : [ ] ,
@@ -176,8 +185,9 @@ describe('StreamingEngine', () => {
176
185
makeBuffer ( segmentSizes [ ContentType . TEXT ] ) ,
177
186
makeBuffer ( segmentSizes [ ContentType . TEXT ] ) ,
178
187
] ,
179
- segmentStartTimes : [ 0 , 10 , 20 , 30 ] ,
188
+ segmentStartTimes : [ offset , offset + 10 , offset + 20 , offset + 30 ] ,
180
189
segmentDuration : 10 ,
190
+ timestampOffset : timestampOffset ,
181
191
} ,
182
192
} ;
183
193
if ( trickMode ) {
@@ -192,8 +202,9 @@ describe('StreamingEngine', () => {
192
202
makeBuffer ( segmentSizes [ ContentType . VIDEO ] ) ,
193
203
makeBuffer ( segmentSizes [ ContentType . VIDEO ] ) ,
194
204
] ,
195
- segmentStartTimes : [ 0 , 10 , 20 , 30 ] ,
205
+ segmentStartTimes : [ offset , offset + 10 , offset + 20 , offset + 30 ] ,
196
206
segmentDuration : 10 ,
207
+ timestampOffset : timestampOffset ,
197
208
} ;
198
209
}
199
210
@@ -372,14 +383,24 @@ describe('StreamingEngine', () => {
372
383
video : segmentData [ ContentType . VIDEO ] . segmentDuration ,
373
384
text : segmentData [ ContentType . TEXT ] . segmentDuration ,
374
385
} ;
386
+
387
+ const timestampOffsets = {
388
+ audio : segmentData [ ContentType . AUDIO ] . timestampOffset ,
389
+ video : segmentData [ ContentType . VIDEO ] . timestampOffset ,
390
+ text : segmentData [ ContentType . TEXT ] . timestampOffset ,
391
+ } ;
392
+
375
393
if ( segmentData [ 'trickvideo' ] ) {
376
394
segmentDurations [ 'trickvideo' ] =
377
395
segmentData [ 'trickvideo' ] . segmentDuration ;
396
+ timestampOffsets [ 'trickvideo' ] =
397
+ segmentData [ 'trickvideo' ] . timestampOffset ;
378
398
}
379
399
manifest = shaka . test . StreamingEngineUtil . createManifest (
380
400
/** @type {!shaka.media.PresentationTimeline } */ ( timeline ) ,
381
401
[ firstPeriodStartTime , secondPeriodStartTime ] ,
382
- presentationDuration , segmentDurations , initSegmentRanges ) ;
402
+ presentationDuration , segmentDurations , initSegmentRanges ,
403
+ timestampOffsets ) ;
383
404
384
405
audioStream = manifest . variants [ 0 ] . audio ;
385
406
videoStream = manifest . variants [ 0 ] . video ;
@@ -2616,7 +2637,7 @@ describe('StreamingEngine', () => {
2616
2637
expect ( event . detail ) . toEqual ( emsgObj ) ;
2617
2638
} ) ;
2618
2639
2619
- it ( 'raises an event for registered embedded v1 emsg boxes ' , async ( ) => {
2640
+ it ( 'raises an event for registered embedded v1 emsg boxes' , async ( ) => {
2620
2641
// same event but verison 1.
2621
2642
const v1EmsgSegment = Uint8ArrayUtils . fromHex (
2622
2643
'0000003f656d7367010000000000000100000000000000080000ffff00000001' +
@@ -2717,6 +2738,68 @@ describe('StreamingEngine', () => {
2717
2738
} ) ;
2718
2739
} ) ;
2719
2740
2741
+ describe ( 'embedded emsg boxes with non zero timestamps' , ( ) => {
2742
+ const emsgSegment = Uint8ArrayUtils . fromHex (
2743
+ '0000003b656d736700000000666f6f3a6261723a637573746f6d646174617363' +
2744
+ '68656d6500310000000001000000080000ffff0000000174657374' ) ;
2745
+ const emsgObj = {
2746
+ startTime : 8 ,
2747
+ endTime : 0xffff + 8 ,
2748
+ schemeIdUri : 'foo:bar:customdatascheme' ,
2749
+ value : '1' ,
2750
+ timescale : 1 ,
2751
+ presentationTimeDelta : 8 ,
2752
+ eventDuration : 0xffff ,
2753
+ id : 1 ,
2754
+ messageData : new Uint8Array ( [ 0x74 , 0x65 , 0x73 , 0x74 ] ) ,
2755
+ } ;
2756
+
2757
+ beforeEach ( ( ) => {
2758
+ // setup an offset for the timestamps.
2759
+ setupVod ( false , 10 ) ;
2760
+ mediaSourceEngine = new shaka . test . FakeMediaSourceEngine ( segmentData ) ;
2761
+ createStreamingEngine ( ) ;
2762
+ } ) ;
2763
+
2764
+ it ( 'event start matches presentation times for emsg boxes' , async ( ) => {
2765
+ segmentData [ ContentType . VIDEO ] . segments [ 0 ] = emsgSegment ;
2766
+ videoStream . emsgSchemeIdUris = [ emsgObj . schemeIdUri ] ;
2767
+
2768
+ // Here we go!
2769
+ streamingEngine . switchVariant ( variant ) ;
2770
+ streamingEngine . switchTextStream ( textStream ) ;
2771
+ await streamingEngine . start ( ) ;
2772
+ playing = true ;
2773
+ await runTest ( ) ;
2774
+
2775
+ expect ( onEvent ) . toHaveBeenCalledTimes ( 1 ) ;
2776
+
2777
+ const event = onEvent . calls . argsFor ( 0 ) [ 0 ] ;
2778
+ expect ( event . detail ) . toEqual ( emsgObj ) ;
2779
+ } ) ;
2780
+
2781
+ it ( 'event start matches presentation time for v1 emsg boxes' , async ( ) => {
2782
+ // same event but verison 1. start time is 18.
2783
+ const v1EmsgSegment = Uint8ArrayUtils . fromHex (
2784
+ '0000003f656d7367010000000000000100000000000000120000ffff00000001' +
2785
+ '666f6f3a6261723a637573746f6d64617461736368656d6500310074657374' ) ;
2786
+ segmentData [ ContentType . VIDEO ] . segments [ 0 ] = v1EmsgSegment ;
2787
+ videoStream . emsgSchemeIdUris = [ emsgObj . schemeIdUri ] ;
2788
+
2789
+ // Here we go!
2790
+ streamingEngine . switchVariant ( variant ) ;
2791
+ streamingEngine . switchTextStream ( textStream ) ;
2792
+ await streamingEngine . start ( ) ;
2793
+ playing = true ;
2794
+ await runTest ( ) ;
2795
+
2796
+ expect ( onEvent ) . toHaveBeenCalledTimes ( 1 ) ;
2797
+
2798
+ const event = onEvent . calls . argsFor ( 0 ) [ 0 ] ;
2799
+ expect ( event . detail ) . toEqual ( emsgObj ) ;
2800
+ } ) ;
2801
+ } ) ;
2802
+
2720
2803
describe ( 'network downgrading' , ( ) => {
2721
2804
/** @type {shaka.extern.Variant } */
2722
2805
let initialVariant ;
0 commit comments