您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

AudioMixer.js 2.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. }
  19. /**
  20. * Add audio MediaStream to be mixed, if the stream doesn't contain any audio tracks it will be ignored.
  21. *
  22. * @param {MediaStream} stream - MediaStream to be mixed.
  23. */
  24. addMediaStream(stream) {
  25. if (!stream.getAudioTracks()) {
  26. logger.warn('Added MediaStream doesn\'t contain audio tracks.');
  27. }
  28. this._streamsToMix.push(stream);
  29. }
  30. /**
  31. * At this point a WebAudio ChannelMergerNode is created and and the two associated MediaStreams are connected to
  32. * it; the resulting mixed MediaStream is returned.
  33. *
  34. * @returns {MediaStream} - MediaStream containing added streams mixed together, or null if no MediaStream
  35. * is added.
  36. */
  37. start() {
  38. // If the mixer was already started just return the existing mixed stream.
  39. if (this._started) {
  40. return this._mixedMSD.stream;
  41. }
  42. this._audioContext = createAudioContext();
  43. if (!this._streamsToMix.length) {
  44. logger.warn('No MediaStream\'s added to AudioMixer, nothing will happen.');
  45. return null;
  46. }
  47. this._started = true;
  48. // Create ChannelMergerNode and connect all MediaStreams to it.
  49. this._channelMerger = this._audioContext.createChannelMerger(this._streamsToMix.length);
  50. for (const stream of this._streamsToMix) {
  51. const streamMSS = this._audioContext.createMediaStreamSource(stream);
  52. streamMSS.connect(this._channelMerger);
  53. }
  54. this._mixedMSD = this._audioContext.createMediaStreamDestination();
  55. this._channelMerger.connect(this._mixedMSD);
  56. return this._mixedMSD.stream;
  57. }
  58. /**
  59. * Disconnect the ChannelMergerNode stopping the audio mix process.References to MediaStreams are also cleared.
  60. *
  61. * @returns {void}
  62. */
  63. reset() {
  64. this._started = false;
  65. this._streamsToMix = [];
  66. if (this._channelMerger) {
  67. this._channelMerger.disconnect();
  68. }
  69. if (this._audioContext) {
  70. this._audioContext = undefined;
  71. }
  72. }
  73. }