Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

AudioMixer.js 2.6KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /* global
  2. __filename
  3. */
  4. import { getLogger } from 'jitsi-meet-logger';
  5. import { createAudioContext } from './WebAudioUtils';
  6. const logger = getLogger(__filename);
  7. /**
  8. * The AudioMixer, as the name implies, mixes a number of MediaStreams containing audio tracks into a single
  9. * MediaStream.
  10. */
  11. export default class AudioMixer {
  12. /**
  13. * Create AudioMixer instance.
  14. */
  15. constructor() {
  16. this._started = false;
  17. this._streamsToMix = [];
  18. this._streamMSSArray = [];
  19. }
  20. /**
  21. * Add audio MediaStream to be mixed, if the stream doesn't contain any audio tracks it will be ignored.
  22. *
  23. * @param {MediaStream} stream - MediaStream to be mixed.
  24. */
  25. addMediaStream(stream) {
  26. if (!stream.getAudioTracks()) {
  27. logger.warn('Added MediaStream doesn\'t contain audio tracks.');
  28. }
  29. this._streamsToMix.push(stream);
  30. }
  31. /**
  32. * At this point a WebAudio ChannelMergerNode is created and and the two associated MediaStreams are connected to
  33. * it; the resulting mixed MediaStream is returned.
  34. *
  35. * @returns {MediaStream} - MediaStream containing added streams mixed together, or null if no MediaStream
  36. * is added.
  37. */
  38. start() {
  39. // If the mixer was already started just return the existing mixed stream.
  40. if (this._started) {
  41. return this._mixedMSD.stream;
  42. }
  43. this._audioContext = createAudioContext();
  44. if (!this._streamsToMix.length) {
  45. logger.warn('No MediaStream\'s added to AudioMixer, nothing will happen.');
  46. return null;
  47. }
  48. this._started = true;
  49. this._mixedMSD = this._audioContext.createMediaStreamDestination();
  50. for (const stream of this._streamsToMix) {
  51. const streamMSS = this._audioContext.createMediaStreamSource(stream);
  52. streamMSS.connect(this._mixedMSD);
  53. // Maintain a list of MediaStreamAudioSourceNode so we can disconnect them on reset.
  54. this._streamMSSArray.push(streamMSS);
  55. }
  56. return this._mixedMSD.stream;
  57. }
  58. /**
  59. * Disconnect MediaStreamAudioSourceNode and clear references.
  60. *
  61. * @returns {void}
  62. */
  63. reset() {
  64. this._started = false;
  65. this._streamsToMix = [];
  66. // Clean up created MediaStreamAudioSourceNode.
  67. for (const streamMSS of this._streamMSSArray) {
  68. streamMSS.disconnect();
  69. }
  70. this._streamMSSArray = [];
  71. if (this._audioContext) {
  72. this._audioContext = undefined;
  73. }
  74. }
  75. }