Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

audio_levels.js 6.9KB

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