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

Added live indicator to controlbar. #2960

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
158 changes: 92 additions & 66 deletions contrib/akamai/controlbar/ControlBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
thumbnailElem,
thumbnailTimeLabel,
idSuffix,
liveThresholdSecs = 12,

//************************************************************************************
// THUMBNAIL CONSTANTS
//************************************************************************************
//************************************************************************************
// THUMBNAIL CONSTANTS
//************************************************************************************
// Maximum percentage of player height that the thumbnail will fill
maxPercentageThumbnailScreen = 0.15,
// Separation between the control bar and the thumbnail (in px)
Expand Down Expand Up @@ -92,9 +93,9 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
return id + (idSuffix ? idSuffix : '');
},

//************************************************************************************
// PLAYBACK
//************************************************************************************
//************************************************************************************
// PLAYBACK
//************************************************************************************

togglePlayPauseBtnState = function () {
if (player.isPaused()) {
Expand Down Expand Up @@ -139,11 +140,13 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
updateDuration();
if (!seeking) {
setTime(displayUTCTimeCodes ? player.timeAsUTC() : player.time());

if (seekbarPlay) {
seekbarPlay.style.width = (player.time() / player.duration() * 100) + '%';
if (player.duration() - player.time() < liveThresholdSecs) {
seekbarPlay.style.width = '100%'
} else {
seekbarPlay.style.width = (player.time() / player.duration() * 100) + '%';
}
}

if (seekbarBuffer) {
seekbarBuffer.style.width = ((player.time() + getBufferLevel()) / player.duration() * 100) + '%';
}
Expand All @@ -158,7 +161,6 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
getBufferLevel = function () {
var dashMetrics = player.getDashMetrics();
var bufferLevel = 0;

if (dashMetrics) {
bufferLevel = dashMetrics.getCurrentBufferLevel('video', true);
if (!bufferLevel) {
Expand All @@ -168,9 +170,9 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
return bufferLevel;
},

//************************************************************************************
// VOLUME
//************************************************************************************
//************************************************************************************
// VOLUME
//************************************************************************************

toggleMuteBtnState = function () {
var span = document.getElementById(getControlId('iconMute'));
Expand Down Expand Up @@ -206,9 +208,9 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
toggleMuteBtnState();
},

//************************************************************************************
// SEEKING
// ************************************************************************************
//************************************************************************************
// SEEKING
// ************************************************************************************

calculateTimeByEvent = function (event) {
var seekbarRect = seekbar.getBoundingClientRect();
Expand Down Expand Up @@ -268,7 +270,7 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
}

// Get thumbnail information
player.getThumbnail(mouseTime, function(thumbnail) {
player.getThumbnail(mouseTime, function (thumbnail) {
if (!thumbnail) return;

// Adjust left variable for positioning thumbnail with regards to its viewport
Expand All @@ -279,19 +281,19 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
left -= ctrlWidth / 2;
}

var scale = (videoContainerRect.height * maxPercentageThumbnailScreen)/thumbnail.height;
var scale = (videoContainerRect.height * maxPercentageThumbnailScreen) / thumbnail.height;
if (scale > maximumScale) {
scale = maximumScale;
}

// Set thumbnail control position
thumbnailContainer.style.left = left + 'px';
thumbnailContainer.style.display = '';
thumbnailContainer.style.bottom += Math.round(videoControllerRect.height + bottomMarginThumbnail ) + 'px';
thumbnailContainer.style.bottom += Math.round(videoControllerRect.height + bottomMarginThumbnail) + 'px';
thumbnailContainer.style.height = Math.round(thumbnail.height) + 'px';

var backgroundStyle = 'url("' + thumbnail.url + '") ' + (thumbnail.x > 0 ? '-' + thumbnail.x : '0') +
'px ' + (thumbnail.y > 0 ? '-' + thumbnail.y : '0') + 'px';
'px ' + (thumbnail.y > 0 ? '-' + thumbnail.y : '0') + 'px';
thumbnailElem.style.background = backgroundStyle;
thumbnailElem.style.width = thumbnail.width + 'px';
thumbnailElem.style.height = thumbnail.height + 'px';
Expand All @@ -308,46 +310,70 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
thumbnailContainer.style.display = 'none';
},

getScrollOffset = function() {
getScrollOffset = function () {
if (window.pageXOffset) {
return {
x: window.pageXOffset,
y: window.pageYOffset
};
}
return {
x: document.documentElement.scrollLeft,
y: document.documentElement.scrollTop
x: document.documentElement.scrollLeft,
y: document.documentElement.scrollTop
};
},
seekLive = function () {
player.seek(player.duration());
},

//************************************************************************************
// TIME/DURATION
//************************************************************************************

//************************************************************************************
// TIME/DURATION
//************************************************************************************
setDuration = function (value) {
if (!isNaN(value)) {
if (player.isDynamic()) {
durationDisplay.textContent = '● LIVE';
if (!durationDisplay.onclick) {
durationDisplay.onclick = seekLive;
durationDisplay.classList.add('live-icon')
}
} else if (!isNaN(value)) {
durationDisplay.textContent = displayUTCTimeCodes ? player.formatUTC(value) : player.convertToTimeCode(value);
}
},

setTime = function (value) {
if (!isNaN(value)) {
setTime = async function (value) {
if (value < 0) {
return;
}
if (player.isDynamic() && player.duration()) {
var liveDelay = player.duration() - value;
if (liveDelay < liveThresholdSecs) {
durationDisplay.classList.add('live');
timeDisplay.textContent = "";
} else {
durationDisplay.classList.remove('live');
timeDisplay.textContent = '- ' + player.convertToTimeCode(liveDelay);
}
} else if (!isNaN(value)) {
timeDisplay.textContent = displayUTCTimeCodes ? player.formatUTC(value) : player.convertToTimeCode(value);
}
},

updateDuration = function () {
var duration = player.duration();
if (duration !== parseFloat(seekbar.max)) { //check if duration changes for live streams..
if (!startedPlaying && duration && player.isDynamic()) {
seekLive();
startedPlaying = true;
}
setDuration(displayUTCTimeCodes ? player.durationAsUTC() : duration);
seekbar.max = duration;
}
},

//************************************************************************************
// FULLSCREEN
//************************************************************************************
//************************************************************************************
// FULLSCREEN
//************************************************************************************

onFullScreenChange = function (e) {
if (isFullscreen()) {
Expand Down Expand Up @@ -429,26 +455,26 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
}
},

//************************************************************************************
// Audio Video MENU
//************************************************************************************
//************************************************************************************
// Audio Video MENU
//************************************************************************************

onTracksAdded = function (e) {
// Subtitles/Captions Menu //XXX we need to add two layers for captions & subtitles if present.
if (!captionMenu) {
var contentFunc = function (element, index) {
if (isNaN(index)) {
return "OFF";
return "OFF";
}

var label = getLabelForLocale(element.labels);
if (label) {
return label + " : " + element.kind;
return label + " : " + element.kind;
}

return element.lang + " : " + element.kind;
}
captionMenu = createMenu({menuType: 'caption', arr: e.tracks}, contentFunc);
captionMenu = createMenu({ menuType: 'caption', arr: e.tracks }, contentFunc);

var func = function () {
onMenuClick(captionMenu, captionBtn);
Expand All @@ -460,14 +486,14 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
},

onStreamInitialized = function (e) {
startedPlaying = false;
updateDuration();

var contentFunc;
//Bitrate Menu
if (bitrateListBtn) {
destroyBitrateMenu();

var availableBitrates = {menuType: 'bitrate'};
var availableBitrates = { menuType: 'bitrate' };
availableBitrates.audio = player.getBitrateInfoListFor("audio") || [];
availableBitrates.video = player.getBitrateInfoListFor("video") || [];
if (availableBitrates.audio.length > 1 || availableBitrates.video.length > 1) {
Expand All @@ -492,7 +518,7 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {

//Track Switch Menu
if (!trackSwitchMenu && trackSwitchBtn) {
var availableTracks = {menuType: "track"};
var availableTracks = { menuType: "track" };
availableTracks.audio = player.getTracksFor("audio");
availableTracks.video = player.getTracksFor("video"); // these return empty arrays so no need to check for null

Expand Down Expand Up @@ -528,13 +554,13 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
videoController.appendChild(el);

switch (menuType) {
case 'caption' :
case 'caption':
el.appendChild(document.createElement("ul"));
el = createMenuContent(el, getMenuContent(menuType, info.arr, contentFunc), 'caption', menuType + '-list');
setMenuItemsState(getMenuInitialIndex(info, menuType), menuType + '-list');
break;
case 'track' :
case 'bitrate' :
case 'track':
case 'bitrate':
if (info.video.length > 1) {
el.appendChild(createMediaTypeMenu("video"));
el = createMenuContent(el, getMenuContent(menuType, info.video, contentFunc), 'video', 'video-' + menuType + '-list');
Expand All @@ -552,12 +578,12 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
return el;
},

getMenuInitialIndex = function(info, menuType, mediaType) {
getMenuInitialIndex = function (info, menuType, mediaType) {
if (menuType === 'track') {

var mediaInfo = player.getCurrentTrackFor(mediaType);
var idx = 0
info.some(function(element, index){
info.some(function (element, index) {
if (isTracksEqual(element, mediaInfo)) {
idx = index;
return true;
Expand Down Expand Up @@ -596,22 +622,22 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
return content;
},

getBrowserLocale = function() {
return (navigator.languages && navigator.languages.length) ? navigator.languages : [navigator.language];
getBrowserLocale = function () {
return (navigator.languages && navigator.languages.length) ? navigator.languages : [navigator.language];
},

getLabelForLocale = function (labels) {
var locales = getBrowserLocale();
var locales = getBrowserLocale();

for (var i = 0; i < labels.length; i++) {
for (var j = 0; j < locales.length; j++) {
if (labels[i].lang && locales[j] && locales[j].indexOf(labels[i].lang) > -1) {
return labels[i].text;
for (var i = 0; i < labels.length; i++) {
for (var j = 0; j < locales.length; j++) {
if (labels[i].lang && locales[j] && locales[j].indexOf(labels[i].lang) > -1) {
return labels[i].text;
}
}
}
}

return labels.length === 1 ? labels[0].text : null;
return labels.length === 1 ? labels[0].text : null;
},

createMediaTypeMenu = function (type) {
Expand Down Expand Up @@ -706,11 +732,11 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
player.setAutoSwitchQualityFor(self.mediaType, true);
}
break;
case 'caption-list' :
case 'caption-list':
player.setTextTrack(self.index - 1);
break
case 'video-track-list' :
case 'audio-track-list' :
case 'video-track-list':
case 'audio-track-list':
player.setCurrentTrack(player.getTracksFor(self.mediaType)[self.index]);
break;
}
Expand Down Expand Up @@ -750,9 +776,9 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
}
},

//************************************************************************************
//IE FIX
//************************************************************************************
//************************************************************************************
//IE FIX
//************************************************************************************

coerceIEInputAndChangeEvents = function (slider, addChange) {
var fireChange = function (e) {
Expand Down Expand Up @@ -783,9 +809,9 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
};


//************************************************************************************
// PUBLIC API
//************************************************************************************
//************************************************************************************
// PUBLIC API
//************************************************************************************

return {
setVolume: setVolume,
Expand Down Expand Up @@ -825,7 +851,7 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
seekbar.addEventListener("mousedown", onSeeking, true);
seekbar.addEventListener("mousemove", onSeekBarMouseMove, true);
// set passive to true for scroll blocking listeners (https://www.chromestatus.com/feature/5745543795965952)
seekbar.addEventListener("touchmove", onSeekBarMouseMove, {passive: true});
seekbar.addEventListener("touchmove", onSeekBarMouseMove, { passive: true });
seekbar.addEventListener("mouseout", onSeekBarMouseMoveOut, true);
seekbar.addEventListener("touchcancel", onSeekBarMouseMoveOut, true);
seekbar.addEventListener("touchend", onSeekBarMouseMoveOut, true);
Expand Down
9 changes: 9 additions & 0 deletions contrib/akamai/controlbar/controlbar.css
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@
float: right;
}

.live-icon {
cursor: pointer;
}
.live-icon.live{
color:red !important;
pointer-events: none;
cursor: default;
}

.btn-play-pause{
float: left;
padding:9px 10px;
Expand Down
3 changes: 2 additions & 1 deletion samples/control/controlbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

<script class="code">
function startVideo() {
const url = 'https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd';
// const url = 'https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd';
const url = 'http://vm2.dashif.org/livesim/testpic_2s/Manifest.mpd'; /*Live*/
gitperonam marked this conversation as resolved.
Show resolved Hide resolved
var videoElement = document.querySelector(".videoContainer video");

var player = dashjs.MediaPlayer().create();
Expand Down