Skip to content

Instantly share code, notes, and snippets.

@birkholz
Last active August 9, 2020 10:33
Show Gist options
  • Save birkholz/0b0fa8d7b1c0c1a379520d6c1dd12639 to your computer and use it in GitHub Desktop.
Save birkholz/0b0fa8d7b1c0c1a379520d6c1dd12639 to your computer and use it in GitHub Desktop.
Sending an audiostream to multiple outputs
var ac = new AudioContext();
var dest = ac.createMediaStreamDestination();
// Get permission to use non-default audio devices
// This requests microphone permission also. Perhaps there's a better way to just get output permission.
navigator.mediaDevices.getUserMedia({audio: true});
// Gets a list of output devices
const devices = await navigator.mediaDevices.enumerateDevices();
const audioDevices = devices.filter(device => device.kind === 'audiooutput');
// We create 2 audio nodes which will have distinct output devices
var audio = new Audio();
var audio2 = new Audio();
// Set the sinkId of each audio to our different output devices (0 was my default, and 2 was my virtual cable input)
await audio.setSinkId(audioDevices[0].deviceId);
await audio2.setSinkId(audioDevices[2].deviceId);
// Set the srcObject of both to use the same stream destination
audio.srcObject = dest.stream;
audio2.srcObject = dest.stream;
var outputs = [audio, audio2];
// Load an AudioBuffer for use as a source
// This is probably overcomplicated
source = ac.createBufferSource();
var request = new XMLHttpRequest();
request.open("GET", 'drums.wav', true);
request.responseType = "arraybuffer";
var loader = this;
request.onload = function() {
// Asynchronously decode the audio file data in request.response
loader.context.decodeAudioData(
request.response,
function(buffer) {
if (!buffer) {
alert('error decoding file data: ' + url);
return;
}
source.buffer = buffer;
},
function(error) {
console.error('decodeAudioData error', error);
}
);
}
request.onerror = function() {
alert('BufferLoader: XHR error');
}
request.send();
source.connect(dest);
// Some helper methods to control playback of our outputs
function play() {
outputs.forEach(function(o){o.play();});
}
function pause() {
outputs.forEach(function(o){o.pause();});
}
// Start the source first
source.start();
// Finally play the outputs
play();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment