| 572 | } |
| 573 | |
| 574 | function getMixedAudioStream() { |
| 575 | // via: @pehrsons |
| 576 | if (!Storage.AudioContextConstructor) { |
| 577 | Storage.AudioContextConstructor = new Storage.AudioContext(); |
| 578 | } |
| 579 | |
| 580 | self.audioContext = Storage.AudioContextConstructor; |
| 581 | |
| 582 | self.audioSources = []; |
| 583 | |
| 584 | if (self.useGainNode === true) { |
| 585 | self.gainNode = self.audioContext.createGain(); |
| 586 | self.gainNode.connect(self.audioContext.destination); |
| 587 | self.gainNode.gain.value = 0; // don't hear self |
| 588 | } |
| 589 | |
| 590 | var audioTracksLength = 0; |
| 591 | arrayOfMediaStreams.forEach(function(stream) { |
| 592 | if (!stream.getAudioTracks().length) { |
| 593 | return; |
| 594 | } |
| 595 | |
| 596 | audioTracksLength++; |
| 597 | |
| 598 | var audioSource = self.audioContext.createMediaStreamSource(stream); |
| 599 | |
| 600 | if (self.useGainNode === true) { |
| 601 | audioSource.connect(self.gainNode); |
| 602 | } |
| 603 | |
| 604 | self.audioSources.push(audioSource); |
| 605 | }); |
| 606 | |
| 607 | if (!audioTracksLength) { |
| 608 | return; |
| 609 | } |
| 610 | |
| 611 | self.audioDestination = self.audioContext.createMediaStreamDestination(); |
| 612 | self.audioSources.forEach(function(audioSource) { |
| 613 | audioSource.connect(self.audioDestination); |
| 614 | }); |
| 615 | return self.audioDestination.stream; |
| 616 | } |
| 617 | |
| 618 | function getVideo(stream) { |
| 619 | var video = document.createElement('video'); |