Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix live segment list #3369

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions src/dash/DashHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
import FragmentRequest from '../streaming/vo/FragmentRequest';
import { HTTPRequest } from '../streaming/vo/metrics/HTTPRequest';
import {HTTPRequest} from '../streaming/vo/metrics/HTTPRequest';
import FactoryMaker from '../core/FactoryMaker';
import {
replaceIDForTemplate,
Expand Down Expand Up @@ -93,11 +93,11 @@ function DashHandler(config) {
return streamInfo;
}

function setCurrentIndex (value) {
function setCurrentIndex(value) {
segmentIndex = value;
}

function getCurrentIndex () {
function getCurrentIndex() {
return segmentIndex;
}

Expand Down Expand Up @@ -196,7 +196,10 @@ function DashHandler(config) {
//if representation has initialization and segments information, REPRESENTATION_UPDATE_COMPLETED can be triggered immediately
//otherwise, it means that a request has to be made to get initialization and/or segments informations
if (hasInitialization && hasSegments) {
eventBus.trigger(events.REPRESENTATION_UPDATE_COMPLETED, {sender: instance, representation: voRepresentation});
eventBus.trigger(events.REPRESENTATION_UPDATE_COMPLETED, {
sender: instance,
representation: voRepresentation
});
} else {
segmentsController.update(voRepresentation, getType(), selectedMimeType, hasInitialization, hasSegments);
}
Expand All @@ -209,8 +212,7 @@ function DashHandler(config) {

const request = new FragmentRequest();
const representation = segment.representation;
const bandwidth = representation.adaptation.period.mpd.manifest.Period_asArray[representation.adaptation.period.index].
AdaptationSet_asArray[representation.adaptation.index].Representation_asArray[representation.index].bandwidth;
const bandwidth = representation.adaptation.period.mpd.manifest.Period_asArray[representation.adaptation.period.index].AdaptationSet_asArray[representation.adaptation.index].Representation_asArray[representation.index].bandwidth;
let url = segment.media;

url = replaceTokenForTemplate(url, 'Number', segment.replacementNumber);
Expand Down Expand Up @@ -312,9 +314,9 @@ function DashHandler(config) {

requestedTime = null;

const indexToRequest = segmentIndex + 1;
logger.debug('Getting the next request at index: ' + indexToRequest);
let indexToRequest = segmentIndex + 1;

logger.debug('Getting the next request at index: ' + indexToRequest);
// check that there is a segment in this index
const segment = segmentsController.getSegmentByIndex(representation, indexToRequest, lastSegment ? lastSegment.mediaStartTime : -1);
if (!segment && isEndlessMedia(representation) && !dynamicStreamCompleted) {
Expand Down Expand Up @@ -396,7 +398,10 @@ function DashHandler(config) {
}

if (segments.length > 0) {
representation.segmentAvailabilityRange = {start: segments[0].presentationStartTime, end: segments[segments.length - 1].presentationStartTime};
representation.segmentAvailabilityRange = {
start: segments[0].presentationStartTime,
end: segments[segments.length - 1].presentationStartTime
};
representation.availableSegmentsNumber = segments.length;
representation.segments = segments;

Expand Down
13 changes: 8 additions & 5 deletions src/dash/utils/ListSegmentsGetter.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import FactoryMaker from '../../core/FactoryMaker';
import Constants from '../../streaming/constants/Constants';

import { getIndexBasedSegment } from './SegmentsUtils';
import {getIndexBasedSegment} from './SegmentsUtils';

function ListSegmentsGetter(config, isDynamic) {

Expand All @@ -54,14 +54,16 @@ function ListSegmentsGetter(config, isDynamic) {
return null;
}

const list = representation.adaptation.period.mpd.manifest.Period_asArray[representation.adaptation.period.index].
AdaptationSet_asArray[representation.adaptation.index].Representation_asArray[representation.index].SegmentList;
const list = representation.adaptation.period.mpd.manifest.Period_asArray[representation.adaptation.period.index].AdaptationSet_asArray[representation.adaptation.index].Representation_asArray[representation.index].SegmentList;
const len = list.SegmentURL_asArray.length;

const startNumber = representation && !isNaN(representation.startNumber) ? representation.startNumber : 1;
const offsetToSubtract = Math.max(startNumber - 1, 0);

const start = representation.startNumber;
let segment = null;
if (index < len) {
const s = list.SegmentURL_asArray[index];
if ((index - offsetToSubtract) < len) {
const s = list.SegmentURL_asArray[index - offsetToSubtract];

segment = getIndexBasedSegment(timelineConverter, isDynamic, representation, index);
if (segment) {
Expand Down Expand Up @@ -91,6 +93,7 @@ function ListSegmentsGetter(config, isDynamic) {
return null;
}


const periodTime = timelineConverter.calcPeriodRelativeTimeFromMpdRelativeTime(representation, requestedTime);
const index = Math.floor(periodTime / duration);

Expand Down
20 changes: 11 additions & 9 deletions src/dash/utils/SegmentsUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ export function unescapeDollarsInTemplate(url) {
}

export function replaceIDForTemplate(url, value) {
if (!value || !url || url.indexOf('$RepresentationID$') === -1) { return url; }
if (!value || !url || url.indexOf('$RepresentationID$') === -1) {
return url;
}
let v = value.toString();
return url.split('$RepresentationID$').join(v);
}
Expand Down Expand Up @@ -127,7 +129,7 @@ export function replaceTokenForTemplate(url, token, value) {
}

function getSegment(representation, duration, presentationStartTime, mediaStartTime, availabilityStartTime,
timelineConverter, presentationEndTime, isDynamic, index) {
timelineConverter, presentationEndTime, isDynamic, index) {
let seg = new Segment();

seg.representation = representation;
Expand All @@ -152,7 +154,7 @@ function isSegmentAvailable(timelineConverter, representation, segment, isDynami
if (isDynamic) {
// segment is not available in current period, but it may be segment available in another period that current one (in DVR window)
// if not (time > segmentAvailabilityRange.end), then return false
if ( representation.segmentAvailabilityRange && segment.presentationStartTime >= representation.segmentAvailabilityRange.end) {
if (representation.segmentAvailabilityRange && segment.presentationStartTime >= representation.segmentAvailabilityRange.end) {
return false;
}
} else {
Expand Down Expand Up @@ -183,9 +185,9 @@ export function getIndexBasedSegment(timelineConverter, isDynamic, representatio
presentationEndTime = parseFloat((presentationStartTime + duration).toFixed(5));

const segment = getSegment(representation, duration, presentationStartTime,
timelineConverter.calcMediaTimeFromPresentationTime(presentationStartTime, representation),
timelineConverter.calcAvailabilityStartTimeFromPresentationTime(presentationStartTime, representation.adaptation.period.mpd, isDynamic),
timelineConverter, presentationEndTime, isDynamic, index);
timelineConverter.calcMediaTimeFromPresentationTime(presentationStartTime, representation),
timelineConverter.calcAvailabilityStartTimeFromPresentationTime(presentationStartTime, representation.adaptation.period.mpd, isDynamic),
timelineConverter, presentationEndTime, isDynamic, index);

if (!isSegmentAvailable(timelineConverter, representation, segment, isDynamic)) {
return null;
Expand All @@ -206,9 +208,9 @@ export function getTimeBasedSegment(timelineConverter, isDynamic, representation
presentationEndTime = presentationStartTime + scaledDuration;

seg = getSegment(representation, scaledDuration, presentationStartTime,
scaledTime,
representation.adaptation.period.mpd.manifest.loadedTime,
timelineConverter, presentationEndTime, isDynamic, index);
scaledTime,
representation.adaptation.period.mpd.manifest.loadedTime,
timelineConverter, presentationEndTime, isDynamic, index);

if (!isSegmentAvailable(timelineConverter, representation, seg, isDynamic)) {
return null;
Expand Down
15 changes: 7 additions & 8 deletions src/dash/utils/TimelineConverter.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ function TimelineConverter() {
function calcSegmentAvailabilityRange(voRepresentation, isDynamic) {
// Static Range Finder
const voPeriod = voRepresentation.adaptation.period;
const range = { start: voPeriod.start, end: voPeriod.start + voPeriod.duration };
const range = {start: voPeriod.start, end: voPeriod.start + voPeriod.duration};
if (!isDynamic) return range;

if (!isClientServerTimeSyncCompleted && voRepresentation.segmentAvailabilityRange) {
Expand All @@ -157,7 +157,7 @@ function TimelineConverter() {
const d = voRepresentation.segmentDuration || (voRepresentation.segments && voRepresentation.segments.length ? voRepresentation.segments[voRepresentation.segments.length - 1].duration : 0);

// Specific use case of SegmentTimeline without timeShiftBufferDepth
if (voRepresentation.segmentInfoType === DashConstants.SEGMENT_TIMELINE && voPeriod.mpd.timeShiftBufferDepth === Number.POSITIVE_INFINITY) {
if (voRepresentation.segmentInfoType === DashConstants.SEGMENT_TIMELINE) {
return calcSegmentAvailabilityRangeFromTimeline(voRepresentation);
}

Expand All @@ -166,7 +166,7 @@ function TimelineConverter() {
range.start = Math.max((now - voPeriod.mpd.timeShiftBufferDepth), voPeriod.start);

const endOffset = voRepresentation.availabilityTimeOffset !== undefined &&
voRepresentation.availabilityTimeOffset < d ? d - voRepresentation.availabilityTimeOffset : d;
voRepresentation.availabilityTimeOffset < d ? d - voRepresentation.availabilityTimeOffset : d;

range.end = now >= periodEnd && now - endOffset < periodEnd ? periodEnd : now - endOffset;

Expand All @@ -176,26 +176,25 @@ function TimelineConverter() {
function calcSegmentAvailabilityRangeFromTimeline(voRepresentation) {
const adaptation = voRepresentation.adaptation.period.mpd.manifest.Period_asArray[voRepresentation.adaptation.period.index].AdaptationSet_asArray[voRepresentation.adaptation.index];
const representation = dashManifestModel.getRepresentationFor(voRepresentation.index, adaptation);

const timeline = representation.SegmentTemplate.SegmentTimeline;
const timescale = representation.SegmentTemplate.timescale;
const segments = timeline.S_asArray;
const range = { start: 0, end: 0 };
const range = {start: 0, end: 0};
let d = 0;
let segment,
repeat,
i,
len;

range.start = segments[0].t / timescale;
range.start = calcPresentationTimeFromMediaTime(segments[0].t / timescale, voRepresentation);

for (i = 0, len = segments.length; i < len; i++) {
segment = segments[i];
repeat = 0;
if (segment.hasOwnProperty('r')) {
repeat = segment.r;
}
d += (segment.d / timescale) * (1 + repeat);
d += (segment.d / timescale) * (1 + repeat);
}

range.end = range.start + d;
Expand All @@ -220,7 +219,7 @@ function TimelineConverter() {
const periodEnd = voPeriod.start + voPeriod.duration;

const endOffset = voRepresentation.availabilityTimeOffset !== undefined &&
voRepresentation.availabilityTimeOffset < d ? d - voRepresentation.availabilityTimeOffset : d;
voRepresentation.availabilityTimeOffset < d ? d - voRepresentation.availabilityTimeOffset : d;

return Math.min(now - endOffset, periodEnd);
}
Expand Down
4 changes: 4 additions & 0 deletions src/streaming/controllers/PlaybackController.js
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,10 @@ function PlaybackController() {
if (!DVRWindow) {
return NaN;
}

if (Math.abs(DVRWindow.end - DVRWindow.start) < 4) {
return currentTime;
}
if (currentTime > DVRWindow.end) {
actualTime = Math.max(DVRWindow.end - liveDelay, DVRWindow.start);

Expand Down