Skip to content

Commit

Permalink
Add support for transition phase between live and on-demand streams (#…
Browse files Browse the repository at this point in the history
…3280)

* Add support for transition phase between live and on-demand streams (see IOP section 4.6.4)

* Add support for transition phase between live and on-demand streams (see IOP section 4.6.4)
  • Loading branch information
Bertrand Berthelot committed Jun 9, 2020
1 parent d968368 commit c4b6f11
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/core/events/CoreEvents.js
Expand Up @@ -84,6 +84,7 @@ class CoreEvents extends EventsBase {
this.SEGMENTBASE_INIT_REQUEST_NEEDED = 'segmentBaseInitRequestNeeded';
this.SEGMENTBASE_SEGMENTSLIST_REQUEST_NEEDED = 'segmentBaseSegmentsListRequestNeeded';
this.SEEK_TARGET = 'seekTarget';
this.DYNAMIC_STREAM_COMPLETED = 'dynamicStreamCompleted';
}
}

Expand Down
15 changes: 13 additions & 2 deletions src/dash/DashHandler.js
Expand Up @@ -64,6 +64,7 @@ function DashHandler(config) {
requestedTime,
currentTime,
isDynamicManifest,
dynamicStreamCompleted,
selectedMimeType,
segmentsController;

Expand All @@ -76,10 +77,12 @@ function DashHandler(config) {
eventBus.on(events.INITIALIZATION_LOADED, onInitializationLoaded, instance);
eventBus.on(events.SEGMENTS_LOADED, onSegmentsLoaded, instance);
eventBus.on(events.REPRESENTATION_UPDATE_STARTED, onRepresentationUpdateStarted, instance);
eventBus.on(events.DYNAMIC_STREAM_COMPLETED, onDynamicStreamCompleted, instance);
}

function initialize(isDynamic) {
isDynamicManifest = isDynamic;
dynamicStreamCompleted = false;
segmentsController.initialize(isDynamic);
}

Expand Down Expand Up @@ -126,6 +129,7 @@ function DashHandler(config) {
eventBus.off(events.INITIALIZATION_LOADED, onInitializationLoaded, instance);
eventBus.off(events.SEGMENTS_LOADED, onSegmentsLoaded, instance);
eventBus.off(events.REPRESENTATION_UPDATE_STARTED, onRepresentationUpdateStarted, instance);
eventBus.off(events.DYNAMIC_STREAM_COMPLETED, onDynamicStreamCompleted, instance);
}

function setRequestUrl(request, destination, representation) {
Expand Down Expand Up @@ -255,7 +259,9 @@ function DashHandler(config) {
isFinished = true;
}
} else {
if (lastSegment) {
if (dynamicStreamCompleted) {
isFinished = true;
} else if (lastSegment) {
const time = parseFloat((lastSegment.presentationStartTime - representation.adaptation.period.start).toFixed(5));
const endTime = lastSegment.duration > 0 ? time + 1.5 * lastSegment.duration : time;
const duration = representation.adaptation.period.duration;
Expand Down Expand Up @@ -322,7 +328,7 @@ function DashHandler(config) {

// check that there is a segment in this index
const segment = segmentsController.getSegmentByIndex(representation, indexToRequest, lastSegment ? lastSegment.mediaStartTime : -1);
if (!segment && isEndlessMedia(representation)) {
if (!segment && isEndlessMedia(representation) && !dynamicStreamCompleted) {
logger.debug('No segment found at index: ' + indexToRequest + '. Wait for next loop');
return null;
} else {
Expand Down Expand Up @@ -420,6 +426,11 @@ function DashHandler(config) {
eventBus.trigger(events.REPRESENTATION_UPDATE_COMPLETED, {sender: this, representation: representation});
}

function onDynamicStreamCompleted() {
logger.debug('Dynamic stream complete');
dynamicStreamCompleted = true;
}

instance = {
initialize: initialize,
getType: getType, //need to be public in order to be used by logger
Expand Down
1 change: 1 addition & 0 deletions src/dash/constants/DashConstants.js
Expand Up @@ -103,6 +103,7 @@ class DashConstants {
this.CONTENTPROTECTION_ASARRAY = 'ContentProtection_asArray';
this.MAIN = 'main';
this.DYNAMIC = 'dynamic';
this.STATIC = 'static';
this.MEDIA_PRESENTATION_DURATION = 'mediaPresentationDuration';
this.MINIMUM_UPDATE_PERIOD = 'minimumUpdatePeriod';
this.CODEC_PRIVATE_DATA = 'codecPrivateData';
Expand Down
8 changes: 8 additions & 0 deletions src/streaming/ManifestUpdater.js
Expand Up @@ -33,6 +33,7 @@ import Events from '../core/events/Events';
import FactoryMaker from '../core/FactoryMaker';
import Debug from '../core/Debug';
import Errors from '../core/errors/Errors';
import DashConstants from '../dash/constants/DashConstants';

function ManifestUpdater() {

Expand Down Expand Up @@ -138,6 +139,13 @@ function ManifestUpdater() {

function update(manifest) {

// See DASH-IF IOP v4.3 section 4.6.4 "Transition Phase between Live and On-Demand"
// Stop manifest update, ignore static manifest and signal end of dynamic stream to detect end of stream
if (manifestModel.getValue() && manifestModel.getValue().type === DashConstants.DYNAMIC && manifest.type === DashConstants.STATIC) {
eventBus.trigger(Events.DYNAMIC_STREAM_COMPLETED);
return;
}

manifestModel.setValue(manifest);

const date = new Date();
Expand Down

0 comments on commit c4b6f11

Please sign in to comment.