Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

LocalStatsCollector.js 3.3KB

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