Adds audio levels for the active speaker avatar.
This commit is contained in:
parent
e4154c055e
commit
b6a665e007
|
@ -21,7 +21,7 @@ var AudioLevels = (function(my) {
|
||||||
videoSpanId = 'participant_' + resourceJid;
|
videoSpanId = 'participant_' + resourceJid;
|
||||||
}
|
}
|
||||||
|
|
||||||
videoSpan = document.getElementById(videoSpanId);
|
var videoSpan = document.getElementById(videoSpanId);
|
||||||
|
|
||||||
if (!videoSpan) {
|
if (!videoSpan) {
|
||||||
if (resourceJid)
|
if (resourceJid)
|
||||||
|
@ -35,8 +35,7 @@ var AudioLevels = (function(my) {
|
||||||
var audioLevelCanvas = $('#' + videoSpanId + '>canvas');
|
var audioLevelCanvas = $('#' + videoSpanId + '>canvas');
|
||||||
|
|
||||||
var videoSpaceWidth = $('#remoteVideos').width();
|
var videoSpaceWidth = $('#remoteVideos').width();
|
||||||
var thumbnailSize
|
var thumbnailSize = VideoLayout.calculateThumbnailSize(videoSpaceWidth);
|
||||||
= VideoLayout.calculateThumbnailSize(videoSpaceWidth);
|
|
||||||
var thumbnailWidth = thumbnailSize[0];
|
var thumbnailWidth = thumbnailSize[0];
|
||||||
var thumbnailHeight = thumbnailSize[1];
|
var thumbnailHeight = thumbnailSize[1];
|
||||||
|
|
||||||
|
@ -84,6 +83,50 @@ var AudioLevels = (function(my) {
|
||||||
drawContext.clearRect (0, 0,
|
drawContext.clearRect (0, 0,
|
||||||
audioLevelCanvas.width, audioLevelCanvas.height);
|
audioLevelCanvas.width, audioLevelCanvas.height);
|
||||||
drawContext.drawImage(canvasCache, 0, 0);
|
drawContext.drawImage(canvasCache, 0, 0);
|
||||||
|
|
||||||
|
if(resourceJid === AudioLevels.LOCAL_LEVEL) {
|
||||||
|
resourceJid = Strophe.getResourceFromJid(connection.emuc.myroomjid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(resourceJid === VideoLayout.getLargeVideoState().userResourceJid) {
|
||||||
|
AudioLevels.updateActiveSpeakerAudioLevel(audioLevel);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
my.updateActiveSpeakerAudioLevel = function(audioLevel) {
|
||||||
|
var drawContext = $('#activeSpeakerAudioLevel')[0].getContext('2d');
|
||||||
|
var r = interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE / 2;
|
||||||
|
var center = (interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE + r) / 2;
|
||||||
|
|
||||||
|
// Save the previous state of the context.
|
||||||
|
drawContext.save();
|
||||||
|
|
||||||
|
drawContext.clearRect(0, 0, 300, 300);
|
||||||
|
|
||||||
|
// Draw a circle.
|
||||||
|
drawContext.arc(center, center, r, 0, 2 * Math.PI);
|
||||||
|
|
||||||
|
// Add a shadow around the circle
|
||||||
|
drawContext.shadowColor = interfaceConfig.SHADOW_COLOR;
|
||||||
|
drawContext.shadowBlur = getShadowLevel(audioLevel);
|
||||||
|
drawContext.shadowOffsetX = 0;
|
||||||
|
drawContext.shadowOffsetY = 0;
|
||||||
|
|
||||||
|
// Fill the shape.
|
||||||
|
drawContext.fill();
|
||||||
|
|
||||||
|
drawContext.save();
|
||||||
|
|
||||||
|
drawContext.restore();
|
||||||
|
|
||||||
|
|
||||||
|
drawContext.arc(center, center, r, 0, 2 * Math.PI);
|
||||||
|
|
||||||
|
drawContext.clip();
|
||||||
|
drawContext.clearRect(0, 0, 277, 200);
|
||||||
|
|
||||||
|
// Restore the previous context state.
|
||||||
|
drawContext.restore();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,7 +137,7 @@ var AudioLevels = (function(my) {
|
||||||
thumbnailHeight) {
|
thumbnailHeight) {
|
||||||
audioLevelCanvas.width = thumbnailWidth + interfaceConfig.CANVAS_EXTRA;
|
audioLevelCanvas.width = thumbnailWidth + interfaceConfig.CANVAS_EXTRA;
|
||||||
audioLevelCanvas.height = thumbnailHeight + interfaceConfig.CANVAS_EXTRA;
|
audioLevelCanvas.height = thumbnailHeight + interfaceConfig.CANVAS_EXTRA;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws the audio level canvas into the cached canvas object.
|
* Draws the audio level canvas into the cached canvas object.
|
||||||
|
@ -143,7 +186,7 @@ var AudioLevels = (function(my) {
|
||||||
interfaceConfig.CANVAS_RADIUS,
|
interfaceConfig.CANVAS_RADIUS,
|
||||||
interfaceConfig.SHADOW_COLOR,
|
interfaceConfig.SHADOW_COLOR,
|
||||||
shadowLevel);
|
shadowLevel);
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the shadow/glow level for the given audio level.
|
* Returns the shadow/glow level for the given audio level.
|
||||||
|
@ -164,7 +207,7 @@ var AudioLevels = (function(my) {
|
||||||
shadowLevel = Math.round(interfaceConfig.CANVAS_EXTRA/2*((audioLevel - 0.6) / 0.4));
|
shadowLevel = Math.round(interfaceConfig.CANVAS_EXTRA/2*((audioLevel - 0.6) / 0.4));
|
||||||
}
|
}
|
||||||
return shadowLevel;
|
return shadowLevel;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the video span id corresponding to the given resourceJid or local
|
* Returns the video span id corresponding to the given resourceJid or local
|
||||||
|
@ -180,7 +223,7 @@ var AudioLevels = (function(my) {
|
||||||
videoSpanId = 'participant_' + resourceJid;
|
videoSpanId = 'participant_' + resourceJid;
|
||||||
|
|
||||||
return videoSpanId;
|
return videoSpanId;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that the remote video has been resized.
|
* Indicates that the remote video has been resized.
|
||||||
|
|
|
@ -78,6 +78,7 @@ var Avatar = (function(my) {
|
||||||
if (activeSpeakerJid === jid && VideoLayout.isLargeVideoOnTop()) {
|
if (activeSpeakerJid === jid && VideoLayout.isLargeVideoOnTop()) {
|
||||||
setVisibility($("#largeVideo"), !show);
|
setVisibility($("#largeVideo"), !show);
|
||||||
setVisibility($('#activeSpeakerAvatar'), show);
|
setVisibility($('#activeSpeakerAvatar'), show);
|
||||||
|
setVisibility($('#activeSpeakerAudioLevel'), show);
|
||||||
setVisibility(avatar, false);
|
setVisibility(avatar, false);
|
||||||
setVisibility(video, false);
|
setVisibility(video, false);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -377,6 +377,13 @@
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#activeSpeakerAudioLevel {
|
||||||
|
visibility: hidden;
|
||||||
|
position: absolute;
|
||||||
|
top: 113px;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
#mixedstream {
|
#mixedstream {
|
||||||
display:none !important;
|
display:none !important;
|
||||||
}
|
}
|
||||||
|
@ -388,6 +395,7 @@
|
||||||
margin: auto;
|
margin: auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 50px;
|
border-radius: 50px;
|
||||||
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.userAvatar {
|
.userAvatar {
|
||||||
|
|
|
@ -49,12 +49,12 @@
|
||||||
<script src="analytics.js?v=1"></script><!-- google analytics plugin -->
|
<script src="analytics.js?v=1"></script><!-- google analytics plugin -->
|
||||||
<script src="rtp_sts.js?v=5"></script><!-- RTP stats processing -->
|
<script src="rtp_sts.js?v=5"></script><!-- RTP stats processing -->
|
||||||
<script src="local_sts.js?v=2"></script><!-- Local stats processing -->
|
<script src="local_sts.js?v=2"></script><!-- Local stats processing -->
|
||||||
<script src="videolayout.js?v=29"></script><!-- video ui -->
|
<script src="videolayout.js?v=30"></script><!-- video ui -->
|
||||||
<script src="connectionquality.js?v=1"></script>
|
<script src="connectionquality.js?v=1"></script>
|
||||||
<script src="toolbar.js?v=6"></script><!-- toolbar ui -->
|
<script src="toolbar.js?v=6"></script><!-- toolbar ui -->
|
||||||
<script src="toolbar_toggler.js?v=2"></script>
|
<script src="toolbar_toggler.js?v=2"></script>
|
||||||
<script src="canvas_util.js?v=1"></script><!-- canvas drawing utils -->
|
<script src="canvas_util.js?v=1"></script><!-- canvas drawing utils -->
|
||||||
<script src="audio_levels.js?v=2"></script><!-- audio levels plugin -->
|
<script src="audio_levels.js?v=3"></script><!-- audio levels plugin -->
|
||||||
<script src="media_stream.js?v=2"></script><!-- media stream -->
|
<script src="media_stream.js?v=2"></script><!-- media stream -->
|
||||||
<script src="bottom_toolbar.js?v=6"></script><!-- media stream -->
|
<script src="bottom_toolbar.js?v=6"></script><!-- media stream -->
|
||||||
<script src="moderator.js?v=2"></script><!-- media stream -->
|
<script src="moderator.js?v=2"></script><!-- media stream -->
|
||||||
|
@ -66,11 +66,11 @@
|
||||||
<script src="message_handler.js?v=2"></script>
|
<script src="message_handler.js?v=2"></script>
|
||||||
<script src="api_connector.js?v=2"></script>
|
<script src="api_connector.js?v=2"></script>
|
||||||
<script src="settings_menu.js?v=1"></script>
|
<script src="settings_menu.js?v=1"></script>
|
||||||
<script src="avatar.js?v=1"></script><!-- avatars -->
|
<script src="avatar.js?v=2"></script><!-- avatars -->
|
||||||
<link rel="stylesheet" href="css/font.css?v=6"/>
|
<link rel="stylesheet" href="css/font.css?v=6"/>
|
||||||
<link rel="stylesheet" href="css/toastr.css?v=1">
|
<link rel="stylesheet" href="css/toastr.css?v=1">
|
||||||
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=30"/>
|
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=30"/>
|
||||||
<link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=14" id="videolayout_default"/>
|
<link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=15" id="videolayout_default"/>
|
||||||
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
|
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
|
<link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
|
||||||
<link rel="stylesheet" href="css/modaldialog.css?v=3">
|
<link rel="stylesheet" href="css/modaldialog.css?v=3">
|
||||||
|
@ -265,6 +265,7 @@
|
||||||
<a target="_new"><div class="watermark rightwatermark"></div></a>
|
<a target="_new"><div class="watermark rightwatermark"></div></a>
|
||||||
<a class="poweredby" href="http://jitsi.org" target="_new" >powered by jitsi.org</a>
|
<a class="poweredby" href="http://jitsi.org" target="_new" >powered by jitsi.org</a>
|
||||||
<img id="activeSpeakerAvatar" src=""/>
|
<img id="activeSpeakerAvatar" src=""/>
|
||||||
|
<canvas id="activeSpeakerAudioLevel"></canvas>
|
||||||
<video id="largeVideo" autoplay oncontextmenu="return false;"></video>
|
<video id="largeVideo" autoplay oncontextmenu="return false;"></video>
|
||||||
</div>
|
</div>
|
||||||
<div id="remoteVideos">
|
<div id="remoteVideos">
|
||||||
|
|
|
@ -174,6 +174,7 @@ var VideoLayout = (function (my) {
|
||||||
if (RTC.getVideoSrc($('#largeVideo')[0]) !== newSrc) {
|
if (RTC.getVideoSrc($('#largeVideo')[0]) !== newSrc) {
|
||||||
|
|
||||||
$('#activeSpeakerAvatar').css('visibility', 'hidden');
|
$('#activeSpeakerAvatar').css('visibility', 'hidden');
|
||||||
|
$('#activeSpeakerAudioLevel').css('visibility', 'hidden');
|
||||||
// Due to the simulcast the localVideoSrc may have changed when the
|
// Due to the simulcast the localVideoSrc may have changed when the
|
||||||
// fadeOut event triggers. In that case the getJidFromVideoSrc and
|
// fadeOut event triggers. In that case the getJidFromVideoSrc and
|
||||||
// isVideoSrcDesktop methods will not function correctly.
|
// isVideoSrcDesktop methods will not function correctly.
|
||||||
|
@ -1038,9 +1039,11 @@ var VideoLayout = (function (my) {
|
||||||
$('#largeVideoContainer').width(availableWidth);
|
$('#largeVideoContainer').width(availableWidth);
|
||||||
$('#largeVideoContainer').height(availableHeight);
|
$('#largeVideoContainer').height(availableHeight);
|
||||||
|
|
||||||
|
var avatarSize = interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE;
|
||||||
$('#activeSpeakerAvatar').css('top',
|
var top = (availableHeight - avatarSize) / 2;
|
||||||
(availableHeight - interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE) / 2);
|
$('#activeSpeakerAvatar').css('top', top);
|
||||||
|
$('#activeSpeakerAudioLevel').css('top', top - avatarSize / 4);
|
||||||
|
$('#activeSpeakerAudioLevel').css('left', availableWidth / 2 - avatarSize * 3 / 4);
|
||||||
|
|
||||||
VideoLayout.resizeThumbnails();
|
VideoLayout.resizeThumbnails();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue