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.3KB

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