Skip to content
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
1 change: 0 additions & 1 deletion samples/alternative/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
video = document.getElementById('video-element');
alternativeVideo = document.getElementById('alternative-video-element');
player = dashjs.MediaPlayer().create();
alternativeVideo = document.querySelector('#alternativeVideo');
player.initialize(video, url, false);
player.setAlternativeVideoElement(alternativeVideo);
}
Expand Down
29 changes: 11 additions & 18 deletions src/streaming/MediaManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ function MediaManager() {
isSwitching = false,
hideAlternativePlayerControls = false,
altPlayer,
fullscreenDiv,
playbackController,
altVideoElement,
alternativeContext,
Expand Down Expand Up @@ -84,17 +83,6 @@ function MediaManager() {

logger = debug.getLogger(instance);

if (!fullscreenDiv) {
fullscreenDiv = document.createElement('div');
fullscreenDiv.id = 'fullscreenDiv';
const videoElement = videoModel.getElement();
const parentNode = videoElement && videoElement.parentNode;
if (parentNode) {
parentNode.insertBefore(fullscreenDiv, videoElement);
fullscreenDiv.appendChild(videoElement);
}
}

document.addEventListener('fullscreenchange', () => {
if (document.fullscreenElement === videoModel.getElement()) {
// TODO: Implement fullscreen
Expand All @@ -117,7 +105,9 @@ function MediaManager() {
const prebufferedPlayer = MediaPlayer().create();
prebufferedPlayer.initialize(null, alternativeMpdUrl, false, NaN);
prebufferedPlayer.updateSettings({
streaming: {cacheInitSegments: true}
streaming: {
cacheInitSegments: true
}
});
prebufferedPlayer.preload();
prebufferedPlayer.setAutoPlay(false);
Expand Down Expand Up @@ -162,7 +152,6 @@ function MediaManager() {
if (altPlayer) {
altPlayer.off(Events.ERROR, onAlternativePlayerError, this);
}

altPlayer = MediaPlayer().create();
altPlayer.updateSettings({
streaming: {
Expand Down Expand Up @@ -201,14 +190,13 @@ function MediaManager() {
}

if (altPlayer && altVideoElement) {
altVideoElement.style.display = 'block';
altPlayer.attachView(altVideoElement);
}

videoModel.pause();
logger.debug('Main video paused');

videoModel.getElement().style.display = 'none';
altVideoElement.style.display = 'block';
logger.debug('Main video paused');

if (time) {
logger.debug(`Seeking alternative content to time: ${time}`);
Expand Down Expand Up @@ -242,7 +230,12 @@ function MediaManager() {

if (playbackController.getIsDynamic()) {
logger.debug('Seeking to original live point for dynamic manifest');
playbackController.seekToOriginalLive(true, false, false);
if (seekTime > playbackController.getDvrWindowStart()) {
playbackController.seek(seekTime, false, false);
} else {
logger.warn('Seek time is before DVR window start, seeking to start of DVR window');
playbackController.seekToDvrWindowStart();
}
} else {
logger.debug(`Seeking main content to time: ${seekTime}`);
playbackController.seek(seekTime, false, false);
Expand Down
38 changes: 19 additions & 19 deletions src/streaming/controllers/AlternativeMediaController.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,25 +41,6 @@ function AlternativeMediaController() {
const context = this.context;
const eventBus = EventBus(context).getInstance();

function _calculateSeekTime(currentEvent, altPlayer) {
let seekTime;
if (currentEvent.mode === Constants.ALTERNATIVE_MPD.MODES.REPLACE) {
if (currentEvent.returnOffset || currentEvent.returnOffset === 0) {
seekTime = currentEvent.presentationTime + currentEvent.returnOffset;
logger.debug(`Using return offset - seeking to: ${seekTime}`);
} else {
const alternativeDuration = altPlayer.duration()
const alternativeEffectiveDuration = !isNaN(currentEvent.maxDuration) ? Math.min(currentEvent.maxDuration, alternativeDuration) : alternativeDuration
seekTime = currentEvent.presentationTime + alternativeEffectiveDuration;
logger.debug(`Using alternative duration - seeking to: ${seekTime}`);
}
} else if (currentEvent.mode === Constants.ALTERNATIVE_MPD.MODES.INSERT) {
seekTime = currentEvent.presentationTime;
logger.debug(`Insert mode - seeking to original presentation time: ${seekTime}`);
}
return seekTime;
}

let instance,
debug,
logger,
Expand Down Expand Up @@ -314,6 +295,25 @@ function AlternativeMediaController() {
}
}

function _calculateSeekTime(currentEvent, altPlayer) {
let seekTime;
if (currentEvent.mode === Constants.ALTERNATIVE_MPD.MODES.REPLACE) {
if (currentEvent.returnOffset || currentEvent.returnOffset === 0) {
seekTime = currentEvent.presentationTime + currentEvent.returnOffset;
logger.debug(`Using return offset - seeking to: ${seekTime}`);
} else {
const alternativeDuration = altPlayer.duration()
const alternativeEffectiveDuration = !isNaN(currentEvent.maxDuration) ? Math.min(currentEvent.maxDuration, alternativeDuration) : alternativeDuration
seekTime = currentEvent.presentationTime + alternativeEffectiveDuration;
logger.debug(`Using alternative duration - seeking to: ${seekTime}`);
}
} else if (currentEvent.mode === Constants.ALTERNATIVE_MPD.MODES.INSERT) {
seekTime = currentEvent.presentationTime;
logger.debug(`Insert mode - seeking to original presentation time: ${seekTime}`);
}
return seekTime;
}

function _resetAlternativeSwitchStates() {
currentEvent = null;
actualEventPresentationTime = 0;
Expand Down
29 changes: 27 additions & 2 deletions src/streaming/controllers/EventController.js
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,29 @@ function EventController() {
}
}

/**
* Auxiliary method to check for earliest resolution time events and return alternative MPD
* @param {object} event
* @return {object|null} - Returns the alternative MPD if it exists and has earliestResolutionTimeOffset, null otherwise
* @private
*/
function _checkForEarliestResolutionTimeEvents(event) {
try {
if (!event || !event.alternativeMpd) {
return null;
}

if (event.alternativeMpd.earliestResolutionTimeOffset !== undefined) {
return event.alternativeMpd;
}

return null;
} catch (e) {
logger.error(e);
return null;
}
}

/**
* Checks if the event has an earliestResolutionTimeOffset and if it's ready to resolve
* @param {object} event
Expand All @@ -511,11 +534,13 @@ function EventController() {
*/
function _checkEventReadyToResolve(event, currentVideoTime) {
try {
if (!event.alternativeMpd.earliestResolutionTimeOffset || event.triggeredReadyToResolve) {
const earlyToResolveEvent = _checkForEarliestResolutionTimeEvents(event);

if (!earlyToResolveEvent || event.triggeredReadyToResolve) {
return false;
}

const resolutionTime = event.calculatedPresentationTime - event.alternativeMpd .earliestResolutionTimeOffset;
const resolutionTime = event.calculatedPresentationTime - earlyToResolveEvent.earliestResolutionTimeOffset;
return currentVideoTime >= resolutionTime;
} catch (e) {
logger.error(e);
Expand Down
21 changes: 21 additions & 0 deletions src/streaming/controllers/PlaybackController.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,25 @@ function PlaybackController() {
seek(seektime, stickToBuffered, internal, adjustLiveDelay);
}

function seekToStartDvrWindow(stickToBuffered = false, internal = false, adjustLiveDelay = false) {
const dvrWindowStart = getDvrWindowStart();

if (dvrWindowStart === 0) {
return;
}

seek(dvrWindowStart, stickToBuffered, internal, adjustLiveDelay);
}

function getDvrWindowStart() {
if (!streamInfo || !videoModel || !isDynamic) {
return;
}
const type = streamController && streamController.hasVideoTrack() ? Constants.VIDEO : Constants.AUDIO;
const dvrInfo = dashMetrics.getCurrentDVRInfo(type);
return dvrInfo && dvrInfo.range ? dvrInfo.range.start : 0;
}

function _getDvrWindowEnd() {
if (!streamInfo || !videoModel || !isDynamic) {
return;
Expand Down Expand Up @@ -922,6 +941,7 @@ function PlaybackController() {
getAvailabilityStartTime,
getBufferLevel,
getCurrentLiveLatency,
getDvrWindowStart,
getEnded,
getInitialCatchupModeActivated,
getIsDynamic,
Expand All @@ -947,6 +967,7 @@ function PlaybackController() {
seek,
seekToCurrentLive,
seekToOriginalLive,
seekToStartDvrWindow,
setConfig,
updateCurrentTime,
};
Expand Down