WebAudio -> PC -> <audio>

by juberti

HTML

<button id="start">▶</button>
<button id="pause">X</button>
<button id="play">Y</button>
<audio id="foo" autoplay/>

JavaScript

var AudioContext = window.AudioContext || window.webkitAudioContext;

var audioElem = document.getElementById("foo");
var bstart = document.querySelector('#start');
bstart.addEventListener('click', start);
var bpause = document.getElementById("pause");
bpause.addEventListener('click', pause);
var bplay = document.getElementById("play");
bplay.addEventListener('click', play);

function start() {
  var audioContext = new AudioContext();
  var oscillator = audioContext.createOscillator();
  oscillator.type = 'sine';
  oscillator.frequency.value = 440; // value in hertz
  
  var dest = audioContext.createMediaStreamDestination();
  oscillator.connect(dest);
  oscillator.start(0);
  
  audioContext.resume().then(() => {
    createConnection(dest.stream, audioElem);
  });
  audioElem.play();
}

function createConnection(stream, elem) {
  var config = { iceServers: [ { urls: ["stun:stun.l.google.com:19302"]}]};
  var pc1 = new RTCPeerConnection(config);
  pc1.addTrack(stream.getTracks()[0], stream);
  pc1.onicecandidate = (e) => { if (e.candidate) pc2.addIceCandidate(e.candidate); }
  var pc2 = new RTCPeerConnection(config);
  pc2.onicecandidate = (e) => { if (e.candidate) pc1.addIceCandidate(e.candidate); }
  pc2.ontrack = (e) => {
    elem.srcObject = e.streams[0];
  }
  pc1.createOffer()
  .then((o) => pc1.setLocalDescription(o))
  .then(() => pc2.setRemoteDescription(pc1.localDescription))
  .then(() => pc2.createAnswer())
  .then((a) => pc2.setLocalDescription(a))
  .then(() => pc1.setRemoteDescription(pc2.localDescription));
}

function pause() {
  audioElem.pause();
}

function play() {
  audioElem.play();
}