@@ -28,6 +28,7 @@ import {
28
28
oneSecond as oneSecondSegment ,
29
29
audio as audioSegment ,
30
30
video as videoSegment ,
31
+ videoDiffPtsDts as videoDiffPtsDtsSegment ,
31
32
videoOneSecond as videoOneSecondSegment ,
32
33
videoOneSecond1 as videoOneSecond1Segment ,
33
34
videoOneSecond2 as videoOneSecond2Segment ,
@@ -1145,6 +1146,192 @@ QUnit.module('SegmentLoader', function(hooks) {
1145
1146
} ) ;
1146
1147
} ) ;
1147
1148
1149
+ QUnit . test ( 'should use video PTS value for timestamp offset calculation when useDtsForTimestampOffset set as false' , function ( assert ) {
1150
+ loader = new SegmentLoader ( LoaderCommonSettings . call ( this , {
1151
+ loaderType : 'main' ,
1152
+ segmentMetadataTrack : this . segmentMetadataTrack ,
1153
+ useDtsForTimestampOffset : false
1154
+ } ) , { } ) ;
1155
+
1156
+ const playlist = playlistWithDuration ( 20 , { uri : 'playlist.m3u8' } ) ;
1157
+
1158
+ return this . setupMediaSource ( loader . mediaSource_ , loader . sourceUpdater_ ) . then ( ( ) => {
1159
+ return new Promise ( ( resolve , reject ) => {
1160
+ loader . one ( 'appended' , resolve ) ;
1161
+ loader . one ( 'error' , reject ) ;
1162
+
1163
+ loader . playlist ( playlist ) ;
1164
+ loader . load ( ) ;
1165
+
1166
+ this . clock . tick ( 100 ) ;
1167
+
1168
+ standardXHRResponse ( this . requests . shift ( ) , videoDiffPtsDtsSegment ( ) ) ;
1169
+ } ) ;
1170
+ } ) . then ( ( ) => {
1171
+ assert . equal (
1172
+ loader . sourceUpdater_ . videoTimestampOffset ( ) ,
1173
+ - playlist . segments [ 0 ] . videoTimingInfo . transmuxedPresentationStart ,
1174
+ 'set video timestampOffset'
1175
+ ) ;
1176
+
1177
+ assert . equal (
1178
+ loader . sourceUpdater_ . audioTimestampOffset ( ) ,
1179
+ - playlist . segments [ 0 ] . videoTimingInfo . transmuxedPresentationStart ,
1180
+ 'set audio timestampOffset'
1181
+ ) ;
1182
+ } ) ;
1183
+ } ) ;
1184
+
1185
+ QUnit . test ( 'should use video DTS value for timestamp offset calculation when useDtsForTimestampOffset set as true' , function ( assert ) {
1186
+ loader = new SegmentLoader ( LoaderCommonSettings . call ( this , {
1187
+ loaderType : 'main' ,
1188
+ segmentMetadataTrack : this . segmentMetadataTrack ,
1189
+ useDtsForTimestampOffset : true
1190
+ } ) , { } ) ;
1191
+
1192
+ const playlist = playlistWithDuration ( 20 , { uri : 'playlist.m3u8' } ) ;
1193
+
1194
+ return this . setupMediaSource ( loader . mediaSource_ , loader . sourceUpdater_ ) . then ( ( ) => {
1195
+ return new Promise ( ( resolve , reject ) => {
1196
+ loader . one ( 'appended' , resolve ) ;
1197
+ loader . one ( 'error' , reject ) ;
1198
+
1199
+ loader . playlist ( playlist ) ;
1200
+ loader . load ( ) ;
1201
+
1202
+ this . clock . tick ( 100 ) ;
1203
+ // segment
1204
+ standardXHRResponse ( this . requests . shift ( ) , videoDiffPtsDtsSegment ( ) ) ;
1205
+ } ) ;
1206
+ } ) . then ( ( ) => {
1207
+ assert . equal (
1208
+ loader . sourceUpdater_ . videoTimestampOffset ( ) ,
1209
+ - playlist . segments [ 0 ] . videoTimingInfo . transmuxedDecodeStart ,
1210
+ 'set video timestampOffset'
1211
+ ) ;
1212
+
1213
+ assert . equal (
1214
+ loader . sourceUpdater_ . audioTimestampOffset ( ) ,
1215
+ - playlist . segments [ 0 ] . videoTimingInfo . transmuxedDecodeStart ,
1216
+ 'set audio timestampOffset'
1217
+ ) ;
1218
+ } ) ;
1219
+ } ) ;
1220
+
1221
+ QUnit . test ( 'should use video DTS value as primary for muxed segments (eg: audio and video together) for timestamp offset calculation when useDtsForTimestampOffset set as true' , function ( assert ) {
1222
+ loader = new SegmentLoader ( LoaderCommonSettings . call ( this , {
1223
+ loaderType : 'main' ,
1224
+ segmentMetadataTrack : this . segmentMetadataTrack ,
1225
+ useDtsForTimestampOffset : true
1226
+ } ) , { } ) ;
1227
+
1228
+ const playlist = playlistWithDuration ( 20 , { uri : 'playlist.m3u8' } ) ;
1229
+
1230
+ return this . setupMediaSource ( loader . mediaSource_ , loader . sourceUpdater_ ) . then ( ( ) => {
1231
+ return new Promise ( ( resolve , reject ) => {
1232
+ loader . one ( 'appended' , resolve ) ;
1233
+ loader . one ( 'error' , reject ) ;
1234
+
1235
+ loader . playlist ( playlist ) ;
1236
+ loader . load ( ) ;
1237
+
1238
+ this . clock . tick ( 100 ) ;
1239
+
1240
+ standardXHRResponse ( this . requests . shift ( ) , muxedSegment ( ) ) ;
1241
+ } ) ;
1242
+ } ) . then ( ( ) => {
1243
+ assert . equal (
1244
+ loader . sourceUpdater_ . videoTimestampOffset ( ) ,
1245
+ - playlist . segments [ 0 ] . videoTimingInfo . transmuxedDecodeStart ,
1246
+ 'set video timestampOffset'
1247
+ ) ;
1248
+
1249
+ assert . equal (
1250
+ loader . sourceUpdater_ . audioTimestampOffset ( ) ,
1251
+ - playlist . segments [ 0 ] . videoTimingInfo . transmuxedDecodeStart ,
1252
+ 'set audio timestampOffset'
1253
+ ) ;
1254
+ } ) ;
1255
+ } ) ;
1256
+
1257
+ QUnit . test ( 'should use audio DTS value for timestamp offset calculation when useDtsForTimestampOffset set as true and only audio' , function ( assert ) {
1258
+ loader = new SegmentLoader ( LoaderCommonSettings . call ( this , {
1259
+ loaderType : 'main' ,
1260
+ segmentMetadataTrack : this . segmentMetadataTrack ,
1261
+ useDtsForTimestampOffset : true
1262
+ } ) , { } ) ;
1263
+
1264
+ const playlist = playlistWithDuration ( 20 , { uri : 'playlist.m3u8' } ) ;
1265
+
1266
+ return this . setupMediaSource ( loader . mediaSource_ , loader . sourceUpdater_ , { isAudioOnly : true } ) . then ( ( ) => {
1267
+ return new Promise ( ( resolve , reject ) => {
1268
+ loader . one ( 'appended' , resolve ) ;
1269
+ loader . one ( 'error' , reject ) ;
1270
+
1271
+ loader . playlist ( playlist ) ;
1272
+ loader . load ( ) ;
1273
+
1274
+ this . clock . tick ( 100 ) ;
1275
+ // segment
1276
+ standardXHRResponse ( this . requests . shift ( ) , audioSegment ( ) ) ;
1277
+ } ) ;
1278
+ } ) . then ( ( ) => {
1279
+ assert . equal (
1280
+ loader . sourceUpdater_ . audioTimestampOffset ( ) ,
1281
+ - playlist . segments [ 0 ] . audioTimingInfo . transmuxedDecodeStart ,
1282
+ 'set audio timestampOffset'
1283
+ ) ;
1284
+ } ) ;
1285
+ } ) ;
1286
+
1287
+ QUnit . test ( 'should fallback to segment\'s start time when there is no transmuxed content (eg: mp4) and useDtsForTimestampOffset is set as true' , function ( assert ) {
1288
+ loader = new SegmentLoader ( LoaderCommonSettings . call ( this , {
1289
+ loaderType : 'main' ,
1290
+ segmentMetadataTrack : this . segmentMetadataTrack ,
1291
+ useDtsForTimestampOffset : true
1292
+ } ) , { } ) ;
1293
+
1294
+ const playlist = playlistWithDuration ( 10 ) ;
1295
+ const ogPost = loader . transmuxer_ . postMessage ;
1296
+
1297
+ loader . transmuxer_ . postMessage = ( message ) => {
1298
+ if ( message . action === 'probeMp4StartTime' ) {
1299
+ const evt = newEvent ( 'message' ) ;
1300
+
1301
+ evt . data = { action : 'probeMp4StartTime' , startTime : 11 , data : message . data } ;
1302
+
1303
+ loader . transmuxer_ . dispatchEvent ( evt ) ;
1304
+ return ;
1305
+ }
1306
+ return ogPost . call ( loader . transmuxer_ , message ) ;
1307
+ } ;
1308
+
1309
+ return this . setupMediaSource ( loader . mediaSource_ , loader . sourceUpdater_ ) . then ( ( ) => {
1310
+ return new Promise ( ( resolve , reject ) => {
1311
+ loader . one ( 'appended' , resolve ) ;
1312
+ loader . one ( 'error' , reject ) ;
1313
+
1314
+ playlist . segments . forEach ( ( segment ) => {
1315
+ segment . map = {
1316
+ resolvedUri : 'init.mp4' ,
1317
+ byterange : { length : Infinity , offset : 0 }
1318
+ } ;
1319
+ } ) ;
1320
+ loader . playlist ( playlist ) ;
1321
+ loader . load ( ) ;
1322
+
1323
+ this . clock . tick ( 100 ) ;
1324
+ // init
1325
+ standardXHRResponse ( this . requests . shift ( ) , mp4VideoInitSegment ( ) ) ;
1326
+ // segment
1327
+ standardXHRResponse ( this . requests . shift ( ) , mp4VideoSegment ( ) ) ;
1328
+ } ) ;
1329
+ } ) . then ( ( ) => {
1330
+ assert . equal ( loader . sourceUpdater_ . videoTimestampOffset ( ) , - 11 , 'set video timestampOffset' ) ;
1331
+ assert . equal ( loader . sourceUpdater_ . audioTimestampOffset ( ) , - 11 , 'set audio timestampOffset' ) ;
1332
+ } ) ;
1333
+ } ) ;
1334
+
1148
1335
QUnit . test ( 'updates timestamps when segments do not start at zero' , function ( assert ) {
1149
1336
const playlist = playlistWithDuration ( 10 ) ;
1150
1337
const ogPost = loader . transmuxer_ . postMessage ;
0 commit comments