Last active
August 9, 2020 10:33
-
-
Save birkholz/0b0fa8d7b1c0c1a379520d6c1dd12639 to your computer and use it in GitHub Desktop.
Sending an audiostream to multiple outputs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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