Skip to content

Commit e2c0023

Browse files
authored
Fix url anchor time (#3453)
* Fix url anchor time to be relative to 1st period * fix unit and functional tests * Fix url anchor time for live streams
1 parent db62fac commit e2c0023

File tree

6 files changed

+47
-18
lines changed

6 files changed

+47
-18
lines changed

src/streaming/controllers/PlaybackController.js

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ function PlaybackController() {
120120
const dvrWindow = dvrInfo ? dvrInfo.range : null;
121121
if (dvrWindow) {
122122
// #t shall be relative to period start
123-
const startTimeFromUri = getStartTimeFromUriParameters(streamInfo.start, true);
123+
const startTimeFromUri = getStartTimeFromUriParameters(true);
124124
if (!isNaN(startTimeFromUri)) {
125125
logger.info('Start time from URI parameters: ' + startTimeFromUri);
126126
startTime = Math.max(Math.min(startTime, startTimeFromUri), dvrWindow.start);
@@ -130,7 +130,7 @@ function PlaybackController() {
130130
// For static stream, start by default at period start
131131
startTime = streamInfo.start;
132132
// If start time in URI, take max value between period start and time from URI (if in period range)
133-
const startTimeFromUri = getStartTimeFromUriParameters(streamInfo.start, false);
133+
const startTimeFromUri = getStartTimeFromUriParameters(false);
134134
if (!isNaN(startTimeFromUri) && startTimeFromUri < (startTime + streamInfo.duration)) {
135135
logger.info('Start time from URI parameters: ' + startTimeFromUri);
136136
startTime = Math.max(startTime, startTimeFromUri);
@@ -371,22 +371,20 @@ function PlaybackController() {
371371
}
372372
}
373373

374-
function getStartTimeFromUriParameters(rangeStart, isDynamic) {
374+
function getStartTimeFromUriParameters(isDynamic) {
375375
const fragData = uriFragmentModel.getURIFragmentData();
376376
if (!fragData || !fragData.t) {
377377
return NaN;
378378
}
379-
380-
let startTime = NaN;
381-
379+
const refStream = streamController.getStreams()[0];
380+
const refStreamStartTime = refStream.getStreamInfo().start;
382381
// Consider only start time of MediaRange
383382
// TODO: consider end time of MediaRange to stop playback at provided end time
384383
fragData.t = fragData.t.split(',')[0];
385-
386-
// "t=<time>" : time is relative to period start (for static streams) or DVR window range start (for dynamic streams)
384+
// "t=<time>" : time is relative to 1st period start
387385
// "t=posix:<time>" : time is absolute start time as number of seconds since 01-01-1970
388-
startTime = (isDynamic && fragData.t.indexOf('posix:') !== -1) ? parseInt(fragData.t.substring(6)) : (rangeStart + parseInt(fragData.t));
389-
386+
const posix = fragData.t.indexOf('posix:') !== -1 ? fragData.t.substring(6) === 'now' ? Date.now() / 1000 : parseInt(fragData.t.substring(6)) : NaN;
387+
let startTime = (isDynamic && !isNaN(posix)) ? posix - availabilityStartTime / 1000 : parseInt(fragData.t) + refStreamStartTime;
390388
return startTime;
391389
}
392390

src/streaming/controllers/StreamController.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ function StreamController() {
730730

731731
// we need to figure out what the correct starting period is
732732
let initialStream = null;
733-
const startTimeFromUri = playbackController.getStartTimeFromUriParameters(streamsInfo[0].start, adapter.getIsDynamic());
733+
const startTimeFromUri = playbackController.getStartTimeFromUriParameters(adapter.getIsDynamic());
734734

735735
initialStream = getStreamForTime(startTimeFromUri);
736736

test/functional/tests/playFromTime.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ exports.register = function (stream) {
3535
stream_.url += '#t=' + startTime;
3636
} else {
3737
startTime = Math.floor(Date.now() / 1000) - TIME_OFFSET;
38-
stream_.url += '#t=' + startTime;
38+
stream_.url += '#t=posix:' + startTime;
3939
}
4040
utils.log(NAME, 'Playback start time: ' + startTime);
4141
await command.execute(player.loadStream, [stream_]);

test/unit/mocks/StreamControllerMock.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ class StreamControllerMock {
77
this.streamId = 'streamId';
88
}
99

10-
initialize() {
10+
initialize(streams) {
11+
this.streams = streams;
12+
}
13+
14+
getStreams() {
15+
return this.streams;
1116
}
1217

1318
getActiveStreamCommonEarliestTime() {

test/unit/mocks/StreamMock.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
function StreamMock () {
2+
3+
this.initialize = function (streamInfo) {
4+
this.streamInfo = streamInfo;
5+
};
6+
27
this.getStreamInfo = function () {
3-
return {};
8+
return this.streamInfo ? this.streamInfo : {};
49
};
510

611
this.getFragmentController = function () {
@@ -10,4 +15,4 @@ function StreamMock () {
1015
};
1116
}
1217

13-
export default StreamMock;
18+
export default StreamMock;

test/unit/streaming.controllers.PlaybackControllers.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import VideoModelMock from './mocks/VideoModelMock';
77
import MediaPlayerModelMock from './mocks/MediaPlayerModelMock';
88
import DashMetricsMock from './mocks/DashMetricsMock';
99
import StreamControllerMock from './mocks/StreamControllerMock';
10+
import StreamMock from './mocks/StreamMock';
1011
import URIFragmentModelMock from './mocks/URIFragmentModelMock';
1112
import AdapterMock from './mocks/AdapterMock';
1213

@@ -21,6 +22,7 @@ describe('PlaybackController', function () {
2122
videoModelMock,
2223
dashMetricsMock,
2324
mediaPlayerModelMock,
25+
streamMock,
2426
streamControllerMock,
2527
uriFragmentModelMock,
2628
adapterMock,
@@ -30,6 +32,7 @@ describe('PlaybackController', function () {
3032
videoModelMock = new VideoModelMock();
3133
dashMetricsMock = new DashMetricsMock();
3234
mediaPlayerModelMock = new MediaPlayerModelMock();
35+
streamMock = new StreamMock();
3336
streamControllerMock = new StreamControllerMock();
3437
uriFragmentModelMock = new URIFragmentModelMock();
3538
adapterMock = new AdapterMock();
@@ -45,6 +48,8 @@ describe('PlaybackController', function () {
4548
adapter: adapterMock,
4649
settings: settings
4750
});
51+
52+
streamControllerMock.initialize([streamMock]);
4853
});
4954

5055
afterEach(function () {
@@ -72,6 +77,7 @@ describe('PlaybackController', function () {
7277
};
7378

7479
playbackController.initialize(streamInfo);
80+
streamMock.initialize(streamInfo);
7581

7682
expect(playbackController.getIsDynamic()).to.equal(true);
7783
});
@@ -90,6 +96,7 @@ describe('PlaybackController', function () {
9096
};
9197

9298
playbackController.initialize(streamInfo);
99+
streamMock.initialize(streamInfo);
93100
});
94101

95102
it('should return NaN when getLiveDelay is called after a call to computeLiveDelay with no parameter', function () {
@@ -326,7 +333,7 @@ describe('PlaybackController', function () {
326333
let doneFn;
327334

328335
let staticStreamInfo = { manifestInfo: { isDynamic: false }, start: 10, duration: 600 };
329-
let dynamicStreamInfo = { manifestInfo: { isDynamic: true }, start: 50, duration: Infinity };
336+
let dynamicStreamInfo = { manifestInfo: { isDynamic: true }, start: 10, duration: Infinity };
330337
let dvrWindowRange = { start: 70, end: 100 };
331338
let liveStartTime = 85;
332339

@@ -348,6 +355,7 @@ describe('PlaybackController', function () {
348355
expectedSeekTime = staticStreamInfo.start;
349356

350357
playbackController.initialize(staticStreamInfo);
358+
streamMock.initialize(staticStreamInfo);
351359
eventBus.trigger(Events.STREAM_INITIALIZED, {});
352360
});
353361

@@ -360,18 +368,20 @@ describe('PlaybackController', function () {
360368
expectedSeekTime = staticStreamInfo.start + uriStartTime;
361369

362370
playbackController.initialize(staticStreamInfo);
371+
streamMock.initialize(staticStreamInfo);
363372
eventBus.trigger(Events.STREAM_INITIALIZED, {});
364373
});
365374

366375
it('should start static stream at period start if #t is before period start', function (done) {
367376
doneFn = done;
368377

369-
let uriStartTime = -10;
378+
let uriStartTime = -20;
370379
uriFragmentModelMock.setURIFragmentData({t: uriStartTime.toString()});
371380

372381
expectedSeekTime = staticStreamInfo.start;
373382

374383
playbackController.initialize(staticStreamInfo);
384+
streamMock.initialize(staticStreamInfo);
375385
eventBus.trigger(Events.STREAM_INITIALIZED, {});
376386
});
377387

@@ -384,6 +394,7 @@ describe('PlaybackController', function () {
384394
expectedSeekTime = staticStreamInfo.start;
385395

386396
playbackController.initialize(staticStreamInfo);
397+
streamMock.initialize(staticStreamInfo);
387398
eventBus.trigger(Events.STREAM_INITIALIZED, {});
388399
});
389400

@@ -396,6 +407,7 @@ describe('PlaybackController', function () {
396407
expectedSeekTime = staticStreamInfo.start;
397408

398409
playbackController.initialize(staticStreamInfo);
410+
streamMock.initialize(staticStreamInfo);
399411
eventBus.trigger(Events.STREAM_INITIALIZED, {});
400412
});
401413

@@ -407,6 +419,7 @@ describe('PlaybackController', function () {
407419
expectedSeekTime = staticStreamInfo.start;
408420

409421
playbackController.initialize(staticStreamInfo);
422+
streamMock.initialize(staticStreamInfo);
410423
eventBus.trigger(Events.STREAM_INITIALIZED, {});
411424
});
412425

@@ -416,18 +429,20 @@ describe('PlaybackController', function () {
416429
expectedSeekTime = liveStartTime;
417430

418431
playbackController.initialize(dynamicStreamInfo);
432+
streamMock.initialize(dynamicStreamInfo);
419433
eventBus.trigger(Events.STREAM_INITIALIZED, {liveStartTime: liveStartTime});
420434
});
421435

422436
it('should start dynamic stream at #t', function (done) {
423437
doneFn = done;
424438

425-
let uriStartTime = (dvrWindowRange.start - dynamicStreamInfo.start) + 10;
439+
let uriStartTime = 70;
426440
uriFragmentModelMock.setURIFragmentData({t: uriStartTime.toString()});
427441

428442
expectedSeekTime = dynamicStreamInfo.start + uriStartTime;
429443

430444
playbackController.initialize(dynamicStreamInfo);
445+
streamMock.initialize(dynamicStreamInfo);
431446
eventBus.trigger(Events.STREAM_INITIALIZED, {liveStartTime: liveStartTime});
432447
});
433448

@@ -440,6 +455,7 @@ describe('PlaybackController', function () {
440455
expectedSeekTime = dvrWindowRange.start;
441456

442457
playbackController.initialize(dynamicStreamInfo);
458+
streamMock.initialize(dynamicStreamInfo);
443459
eventBus.trigger(Events.STREAM_INITIALIZED, {liveStartTime: liveStartTime});
444460
});
445461

@@ -451,6 +467,7 @@ describe('PlaybackController', function () {
451467
expectedSeekTime = liveStartTime;
452468

453469
playbackController.initialize(dynamicStreamInfo);
470+
streamMock.initialize(dynamicStreamInfo);
454471
eventBus.trigger(Events.STREAM_INITIALIZED, {liveStartTime: liveStartTime});
455472
});
456473

@@ -463,6 +480,7 @@ describe('PlaybackController', function () {
463480
expectedSeekTime = uriStartTime;
464481

465482
playbackController.initialize(dynamicStreamInfo);
483+
streamMock.initialize(dynamicStreamInfo);
466484
eventBus.trigger(Events.STREAM_INITIALIZED, {liveStartTime: liveStartTime});
467485
});
468486

@@ -475,6 +493,7 @@ describe('PlaybackController', function () {
475493
expectedSeekTime = dvrWindowRange.start;
476494

477495
playbackController.initialize(dynamicStreamInfo);
496+
streamMock.initialize(dynamicStreamInfo);
478497
eventBus.trigger(Events.STREAM_INITIALIZED, {liveStartTime: liveStartTime});
479498
});
480499

@@ -487,6 +506,7 @@ describe('PlaybackController', function () {
487506
expectedSeekTime = liveStartTime;
488507

489508
playbackController.initialize(dynamicStreamInfo);
509+
streamMock.initialize(dynamicStreamInfo);
490510
eventBus.trigger(Events.STREAM_INITIALIZED, {liveStartTime: liveStartTime});
491511
});
492512

@@ -498,6 +518,7 @@ describe('PlaybackController', function () {
498518
expectedSeekTime = liveStartTime;
499519

500520
playbackController.initialize(dynamicStreamInfo);
521+
streamMock.initialize(dynamicStreamInfo);
501522
eventBus.trigger(Events.STREAM_INITIALIZED, {liveStartTime: liveStartTime});
502523
});
503524
});

0 commit comments

Comments
 (0)