Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

audio_levels.js 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /**
  2. * The audio Levels plugin.
  3. */
  4. var AudioLevels = (function(my) {
  5. var audioLevelCanvasCache = {};
  6. my.LOCAL_LEVEL = 'local';
  7. /**
  8. * Updates the audio level canvas for the given peerJid. If the canvas
  9. * didn't exist we create it.
  10. */
  11. my.updateAudioLevelCanvas = function (peerJid) {
  12. var resourceJid = null;
  13. var videoSpanId = null;
  14. if (!peerJid)
  15. videoSpanId = 'localVideoContainer';
  16. else {
  17. resourceJid = Strophe.getResourceFromJid(peerJid);
  18. videoSpanId = 'participant_' + resourceJid;
  19. }
  20. videoSpan = document.getElementById(videoSpanId);
  21. if (!videoSpan) {
  22. if (resourceJid)
  23. console.error("No video element for jid", resourceJid);
  24. else
  25. console.error("No video element for local video.");
  26. return;
  27. }
  28. var audioLevelCanvas = $('#' + videoSpanId + '>canvas');
  29. var videoSpaceWidth = $('#remoteVideos').width();
  30. var thumbnailSize
  31. = VideoLayout.calculateThumbnailSize(videoSpaceWidth);
  32. var thumbnailWidth = thumbnailSize[0];
  33. var thumbnailHeight = thumbnailSize[1];
  34. if (!audioLevelCanvas || audioLevelCanvas.length === 0) {
  35. audioLevelCanvas = document.createElement('canvas');
  36. audioLevelCanvas.className = "audiolevel";
  37. audioLevelCanvas.style.bottom = "-" + interfaceConfig.CANVAS_EXTRA/2 + "px";
  38. audioLevelCanvas.style.left = "-" + interfaceConfig.CANVAS_EXTRA/2 + "px";
  39. resizeAudioLevelCanvas( audioLevelCanvas,
  40. thumbnailWidth,
  41. thumbnailHeight);
  42. videoSpan.appendChild(audioLevelCanvas);
  43. } else {
  44. audioLevelCanvas = audioLevelCanvas.get(0);
  45. resizeAudioLevelCanvas( audioLevelCanvas,
  46. thumbnailWidth,
  47. thumbnailHeight);
  48. }
  49. };
  50. /**
  51. * Updates the audio level UI for the given resourceJid.
  52. *
  53. * @param resourceJid the resource jid indicating the video element for
  54. * which we draw the audio level
  55. * @param audioLevel the newAudio level to render
  56. */
  57. my.updateAudioLevel = function (resourceJid, audioLevel) {
  58. drawAudioLevelCanvas(resourceJid, audioLevel);
  59. var videoSpanId = getVideoSpanId(resourceJid);
  60. var audioLevelCanvas = $('#' + videoSpanId + '>canvas').get(0);
  61. if (!audioLevelCanvas)
  62. return;
  63. var drawContext = audioLevelCanvas.getContext('2d');
  64. var canvasCache = audioLevelCanvasCache[resourceJid];
  65. drawContext.clearRect (0, 0,
  66. audioLevelCanvas.width, audioLevelCanvas.height);
  67. drawContext.drawImage(canvasCache, 0, 0);
  68. };
  69. /**
  70. * Resizes the given audio level canvas to match the given thumbnail size.
  71. */
  72. function resizeAudioLevelCanvas(audioLevelCanvas,
  73. thumbnailWidth,
  74. thumbnailHeight) {
  75. audioLevelCanvas.width = thumbnailWidth + interfaceConfig.CANVAS_EXTRA;
  76. audioLevelCanvas.height = thumbnailHeight + interfaceConfig.CANVAS_EXTRA;
  77. };
  78. /**
  79. * Draws the audio level canvas into the cached canvas object.
  80. *
  81. * @param resourceJid the resource jid indicating the video element for
  82. * which we draw the audio level
  83. * @param audioLevel the newAudio level to render
  84. */
  85. function drawAudioLevelCanvas(resourceJid, audioLevel) {
  86. if (!audioLevelCanvasCache[resourceJid]) {
  87. var videoSpanId = getVideoSpanId(resourceJid);
  88. var audioLevelCanvasOrig = $('#' + videoSpanId + '>canvas').get(0);
  89. /*
  90. * FIXME Testing has shown that audioLevelCanvasOrig may not exist.
  91. * In such a case, the method CanvasUtil.cloneCanvas may throw an
  92. * error. Since audio levels are frequently updated, the errors have
  93. * been observed to pile into the console, strain the CPU.
  94. */
  95. if (audioLevelCanvasOrig)
  96. {
  97. audioLevelCanvasCache[resourceJid]
  98. = CanvasUtil.cloneCanvas(audioLevelCanvasOrig);
  99. }
  100. }
  101. var canvas = audioLevelCanvasCache[resourceJid];
  102. if (!canvas)
  103. return;
  104. var drawContext = canvas.getContext('2d');
  105. drawContext.clearRect(0, 0, canvas.width, canvas.height);
  106. var shadowLevel = getShadowLevel(audioLevel);
  107. if (shadowLevel > 0)
  108. // drawContext, x, y, w, h, r, shadowColor, shadowLevel
  109. CanvasUtil.drawRoundRectGlow( drawContext,
  110. interfaceConfig.CANVAS_EXTRA/2, interfaceConfig.CANVAS_EXTRA/2,
  111. canvas.width - interfaceConfig.CANVAS_EXTRA,
  112. canvas.height - interfaceConfig.CANVAS_EXTRA,
  113. interfaceConfig.CANVAS_RADIUS,
  114. interfaceConfig.SHADOW_COLOR,
  115. shadowLevel);
  116. };
  117. /**
  118. * Returns the shadow/glow level for the given audio level.
  119. *
  120. * @param audioLevel the audio level from which we determine the shadow
  121. * level
  122. */
  123. function getShadowLevel (audioLevel) {
  124. var shadowLevel = 0;
  125. if (audioLevel <= 0.3) {
  126. shadowLevel = Math.round(interfaceConfig.CANVAS_EXTRA/2*(audioLevel/0.3));
  127. }
  128. else if (audioLevel <= 0.6) {
  129. shadowLevel = Math.round(interfaceConfig.CANVAS_EXTRA/2*((audioLevel - 0.3) / 0.3));
  130. }
  131. else {
  132. shadowLevel = Math.round(interfaceConfig.CANVAS_EXTRA/2*((audioLevel - 0.6) / 0.4));
  133. }
  134. return shadowLevel;
  135. };
  136. /**
  137. * Returns the video span id corresponding to the given resourceJid or local
  138. * user.
  139. */
  140. function getVideoSpanId(resourceJid) {
  141. var videoSpanId = null;
  142. if (resourceJid === AudioLevels.LOCAL_LEVEL
  143. || (connection.emuc.myroomjid && resourceJid
  144. === Strophe.getResourceFromJid(connection.emuc.myroomjid)))
  145. videoSpanId = 'localVideoContainer';
  146. else
  147. videoSpanId = 'participant_' + resourceJid;
  148. return videoSpanId;
  149. };
  150. /**
  151. * Indicates that the remote video has been resized.
  152. */
  153. $(document).bind('remotevideo.resized', function (event, width, height) {
  154. var resized = false;
  155. $('#remoteVideos>span>canvas').each(function() {
  156. var canvas = $(this).get(0);
  157. if (canvas.width !== width + interfaceConfig.CANVAS_EXTRA) {
  158. canvas.width = width + interfaceConfig.CANVAS_EXTRA;
  159. resized = true;
  160. }
  161. if (canvas.heigh !== height + interfaceConfig.CANVAS_EXTRA) {
  162. canvas.height = height + interfaceConfig.CANVAS_EXTRA;
  163. resized = true;
  164. }
  165. });
  166. if (resized)
  167. Object.keys(audioLevelCanvasCache).forEach(function (resourceJid) {
  168. audioLevelCanvasCache[resourceJid].width
  169. = width + interfaceConfig.CANVAS_EXTRA;
  170. audioLevelCanvasCache[resourceJid].height
  171. = height + interfaceConfig.CANVAS_EXTRA;
  172. });
  173. });
  174. return my;
  175. })(AudioLevels || {});