| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 | 
							- /* global APP, interfaceConfig, $ */
 - /* jshint -W101 */
 - 
 - import CanvasUtil from './CanvasUtils';
 - import FilmStrip from '../videolayout/FilmStrip';
 - 
 - const LOCAL_LEVEL = 'local';
 - 
 - let ASDrawContext = null;
 - let audioLevelCanvasCache = {};
 - let dominantSpeakerAudioElement = null;
 - 
 - function _initDominantSpeakerAudioLevels(dominantSpeakerAvatarSize) {
 -     let ASRadius = dominantSpeakerAvatarSize / 2;
 -     let ASCenter = (dominantSpeakerAvatarSize + ASRadius) / 2;
 - 
 -     // Draw a circle.
 -     ASDrawContext.beginPath();
 -     ASDrawContext.arc(ASCenter, ASCenter, ASRadius, 0, 2 * Math.PI);
 -     ASDrawContext.closePath();
 - 
 -     // Add a shadow around the circle
 -     ASDrawContext.shadowColor = interfaceConfig.SHADOW_COLOR;
 -     ASDrawContext.shadowOffsetX = 0;
 -     ASDrawContext.shadowOffsetY = 0;
 - }
 - 
 - /**
 -  * Resizes the given audio level canvas to match the given thumbnail size.
 -  */
 - function _resizeAudioLevelCanvas(   audioLevelCanvas,
 -                                     thumbnailWidth,
 -                                     thumbnailHeight) {
 -     audioLevelCanvas.width = thumbnailWidth + interfaceConfig.CANVAS_EXTRA;
 -     audioLevelCanvas.height = thumbnailHeight + interfaceConfig.CANVAS_EXTRA;
 - }
 - 
 - /**
 -  * Draws the audio level canvas into the cached canvas object.
 -  *
 -  * @param id of the user for whom we draw the audio level
 -  * @param audioLevel the newAudio level to render
 -  */
 - function drawAudioLevelCanvas(id, audioLevel) {
 -     if (!audioLevelCanvasCache[id]) {
 - 
 -         let videoSpanId = getVideoSpanId(id);
 - 
 -         let audioLevelCanvasOrig = $(`#${videoSpanId}>canvas`).get(0);
 - 
 -         /*
 -          * FIXME Testing has shown that audioLevelCanvasOrig may not exist.
 -          * In such a case, the method CanvasUtil.cloneCanvas may throw an
 -          * error. Since audio levels are frequently updated, the errors have
 -          * been observed to pile into the console, strain the CPU.
 -          */
 -         if (audioLevelCanvasOrig) {
 -             audioLevelCanvasCache[id]
 -                 = CanvasUtil.cloneCanvas(audioLevelCanvasOrig);
 -         }
 -     }
 - 
 -     let canvas = audioLevelCanvasCache[id];
 - 
 -     if (!canvas) {
 -         return;
 -     }
 - 
 -     let drawContext = canvas.getContext('2d');
 - 
 -     drawContext.clearRect(0, 0, canvas.width, canvas.height);
 - 
 -     let shadowLevel = getShadowLevel(audioLevel);
 - 
 -     if (shadowLevel > 0) {
 -         // drawContext, x, y, w, h, r, shadowColor, shadowLevel
 -         CanvasUtil.drawRoundRectGlow(
 -             drawContext,
 -             interfaceConfig.CANVAS_EXTRA / 2, interfaceConfig.CANVAS_EXTRA / 2,
 -             canvas.width - interfaceConfig.CANVAS_EXTRA,
 -             canvas.height - interfaceConfig.CANVAS_EXTRA,
 -             interfaceConfig.CANVAS_RADIUS,
 -             interfaceConfig.SHADOW_COLOR,
 -             shadowLevel);
 -     }
 - }
 - 
 - /**
 -  * Returns the shadow/glow level for the given audio level.
 -  *
 -  * @param audioLevel the audio level from which we determine the shadow
 -  * level
 -  */
 - function getShadowLevel (audioLevel) {
 -     let shadowLevel = 0;
 - 
 -     if (audioLevel <= 0.3) {
 -         shadowLevel = Math.round(
 -             interfaceConfig.CANVAS_EXTRA/2*(audioLevel/0.3));
 -     } else if (audioLevel <= 0.6) {
 -         shadowLevel = Math.round(
 -             interfaceConfig.CANVAS_EXTRA/2*((audioLevel - 0.3) / 0.3));
 -     } else {
 -         shadowLevel = Math.round(
 -             interfaceConfig.CANVAS_EXTRA/2*((audioLevel - 0.6) / 0.4));
 -     }
 - 
 -     return shadowLevel;
 - }
 - 
 - /**
 -  * Returns the video span id corresponding to the given user id
 -  */
 - function getVideoSpanId(id) {
 -     let videoSpanId = null;
 - 
 -     if (id === LOCAL_LEVEL || APP.conference.isLocalId(id)) {
 -         videoSpanId = 'localVideoContainer';
 -     } else {
 -         videoSpanId = `participant_${id}`;
 -     }
 - 
 -     return videoSpanId;
 - }
 - 
 - /**
 -  * The audio Levels plugin.
 -  */
 - const AudioLevels = {
 - 
 -     init () {
 -         dominantSpeakerAudioElement =  $('#dominantSpeakerAudioLevel')[0];
 -         ASDrawContext = dominantSpeakerAudioElement.getContext('2d');
 - 
 -         let parentContainer = $("#dominantSpeaker");
 -         let dominantSpeakerWidth = parentContainer.width();
 -         let dominantSpeakerHeight = parentContainer.height();
 - 
 -         dominantSpeakerAudioElement.width = dominantSpeakerWidth;
 -         dominantSpeakerAudioElement.height = dominantSpeakerHeight;
 - 
 -         let dominantSpeakerAvatar = $("#dominantSpeakerAvatar");
 -         _initDominantSpeakerAudioLevels(dominantSpeakerAvatar.width());
 -     },
 - 
 -     /**
 -      * Updates the audio level canvas for the given id. If the canvas
 -      * didn't exist we create it.
 -      */
 -     createAudioLevelCanvas (id, thumbWidth, thumbHeight) {
 - 
 -         let videoSpanId = (id === "local")
 -                         ? "localVideoContainer"
 -                         : `participant_${id}`;
 - 
 -         let videoSpan = document.getElementById(videoSpanId);
 - 
 -         if (!videoSpan) {
 -             if (id) {
 -                 console.error("No video element for id", id);
 -             } else {
 -                 console.error("No video element for local video.");
 -             }
 -             return;
 -         }
 - 
 -         let audioLevelCanvas = $(`#${videoSpanId}>canvas`);
 - 
 -         if (!audioLevelCanvas || audioLevelCanvas.length === 0) {
 - 
 -             audioLevelCanvas = document.createElement('canvas');
 -             audioLevelCanvas.className = "audiolevel";
 -             audioLevelCanvas.style.bottom
 -                 = `-${interfaceConfig.CANVAS_EXTRA/2}px`;
 -             audioLevelCanvas.style.left
 -                 = `-${interfaceConfig.CANVAS_EXTRA/2}px`;
 -             _resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
 - 
 -             videoSpan.appendChild(audioLevelCanvas);
 -         } else {
 -             audioLevelCanvas = audioLevelCanvas.get(0);
 - 
 -             _resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
 -         }
 -     },
 - 
 -     /**
 -      * Updates the audio level UI for the given id.
 -      *
 -      * @param id id of the user for whom we draw the audio level
 -      * @param audioLevel the newAudio level to render
 -      */
 -     updateAudioLevel (id, audioLevel, largeVideoId) {
 -         drawAudioLevelCanvas(id, audioLevel);
 - 
 -         let videoSpanId = getVideoSpanId(id);
 - 
 -         let audioLevelCanvas = $(`#${videoSpanId}>canvas`).get(0);
 - 
 -         if (!audioLevelCanvas) {
 -             return;
 -         }
 - 
 -         let drawContext = audioLevelCanvas.getContext('2d');
 - 
 -         let canvasCache = audioLevelCanvasCache[id];
 - 
 -         drawContext.clearRect(
 -             0, 0, audioLevelCanvas.width, audioLevelCanvas.height
 -         );
 -         drawContext.drawImage(canvasCache, 0, 0);
 - 
 -         if (id === LOCAL_LEVEL) {
 -             id = APP.conference.getMyUserId();
 -             if (!id) {
 -                 return;
 -             }
 -         }
 - 
 -         if(id === largeVideoId) {
 -             window.requestAnimationFrame(function () {
 -                 AudioLevels.updateDominantSpeakerAudioLevel(audioLevel);
 -             });
 -         }
 -     },
 - 
 -     updateDominantSpeakerAudioLevel (audioLevel) {
 -         if($("#dominantSpeaker").css("visibility") == "hidden"
 -             || ASDrawContext === null) {
 -             return;
 -         }
 - 
 -         ASDrawContext.clearRect(0, 0,
 -             dominantSpeakerAudioElement.width,
 -             dominantSpeakerAudioElement.height);
 - 
 -         if (!audioLevel) {
 -             return;
 -         }
 - 
 -         ASDrawContext.shadowBlur = getShadowLevel(audioLevel);
 - 
 -         // Fill the shape.
 -         ASDrawContext.fill();
 -     },
 - 
 -     updateCanvasSize (localVideo, remoteVideo) {
 -         let localCanvasWidth
 -             = localVideo.thumbWidth + interfaceConfig.CANVAS_EXTRA;
 -         let localCanvasHeight
 -             = localVideo.thumbHeight + interfaceConfig.CANVAS_EXTRA;
 -         let remoteCanvasWidth
 -             = remoteVideo.thumbWidth + interfaceConfig.CANVAS_EXTRA;
 -         let remoteCanvasHeight
 -             = remoteVideo.thumbHeight + interfaceConfig.CANVAS_EXTRA;
 - 
 -         let { remoteThumbs, localThumb } = FilmStrip.getThumbs();
 - 
 -         remoteThumbs.children('canvas').each(function () {
 -             $(this).attr('width', remoteCanvasWidth);
 -             $(this).attr('height', remoteCanvasHeight);
 -         });
 - 
 -         if(localThumb) {
 -             localThumb.children('canvas').each(function () {
 -                 $(this).attr('width', localCanvasWidth);
 -                 $(this).attr('height', localCanvasHeight);
 -             });
 -         }
 -     }
 - };
 - 
 - export default AudioLevels;
 
 
  |