modified lib-jitsi-meet dev repo
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.

LocalStatsCollector.js 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /**
  2. * Provides statistics for the local stream.
  3. */
  4. var RTCBrowserType = require('../RTC/RTCBrowserType');
  5. /**
  6. * Size of the webaudio analyzer buffer.
  7. * @type {number}
  8. */
  9. var WEBAUDIO_ANALYZER_FFT_SIZE = 2048;
  10. /**
  11. * Value of the webaudio analyzer smoothing time parameter.
  12. * @type {number}
  13. */
  14. var WEBAUDIO_ANALYZER_SMOOTING_TIME = 0.8;
  15. window.AudioContext = window.AudioContext || window.webkitAudioContext;
  16. var context = null;
  17. if(window.AudioContext) {
  18. context = new AudioContext();
  19. }
  20. /**
  21. * Converts time domain data array to audio level.
  22. * @param samples the time domain data array.
  23. * @returns {number} the audio level
  24. */
  25. function timeDomainDataToAudioLevel(samples) {
  26. var maxVolume = 0;
  27. var length = samples.length;
  28. for (var i = 0; i < length; i++) {
  29. if (maxVolume < samples[i])
  30. maxVolume = samples[i];
  31. }
  32. return parseFloat(((maxVolume - 127) / 128).toFixed(3));
  33. }
  34. /**
  35. * Animates audio level change
  36. * @param newLevel the new audio level
  37. * @param lastLevel the last audio level
  38. * @returns {Number} the audio level to be set
  39. */
  40. function animateLevel(newLevel, lastLevel) {
  41. var value = 0;
  42. var diff = lastLevel - newLevel;
  43. if(diff > 0.2) {
  44. value = lastLevel - 0.2;
  45. }
  46. else if(diff < -0.4) {
  47. value = lastLevel + 0.4;
  48. }
  49. else {
  50. value = newLevel;
  51. }
  52. return parseFloat(value.toFixed(3));
  53. }
  54. /**
  55. * <tt>LocalStatsCollector</tt> calculates statistics for the local stream.
  56. *
  57. * @param stream the local stream
  58. * @param interval stats refresh interval given in ms.
  59. * @param callback function that receives the audio levels.
  60. * @constructor
  61. */
  62. function LocalStatsCollector(stream, interval, callback) {
  63. this.stream = stream;
  64. this.intervalId = null;
  65. this.intervalMilis = interval;
  66. this.audioLevel = 0;
  67. this.callback = callback;
  68. }
  69. /**
  70. * Starts the collecting the statistics.
  71. */
  72. LocalStatsCollector.prototype.start = function () {
  73. if (!context ||
  74. RTCBrowserType.isTemasysPluginUsed())
  75. return;
  76. var analyser = context.createAnalyser();
  77. analyser.smoothingTimeConstant = WEBAUDIO_ANALYZER_SMOOTING_TIME;
  78. analyser.fftSize = WEBAUDIO_ANALYZER_FFT_SIZE;
  79. var source = context.createMediaStreamSource(this.stream);
  80. source.connect(analyser);
  81. var self = this;
  82. this.intervalId = setInterval(
  83. function () {
  84. var array = new Uint8Array(analyser.frequencyBinCount);
  85. analyser.getByteTimeDomainData(array);
  86. var audioLevel = timeDomainDataToAudioLevel(array);
  87. if (audioLevel != self.audioLevel) {
  88. self.audioLevel = animateLevel(audioLevel, self.audioLevel);
  89. self.callback(self.audioLevel);
  90. }
  91. },
  92. this.intervalMilis
  93. );
  94. };
  95. /**
  96. * Stops collecting the statistics.
  97. */
  98. LocalStatsCollector.prototype.stop = function () {
  99. if (this.intervalId) {
  100. clearInterval(this.intervalId);
  101. this.intervalId = null;
  102. }
  103. };
  104. module.exports = LocalStatsCollector;