Canvas: WebRTC canvas to video

WebRTC from canvas to video over two tabs

HTML

<button id="button" onclick="connect()">Connect</button>
<div id="div"></div>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="https://rawgit.com/jan-ivar/localSocket/master/localSocket.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script>
<h1>Canvas (WebGL)</h1>
<h4>WebGL canvas sends stream to video</h4>
<canvas id='viz'></canvas>

JavaScript

const canvas = document.getElementById('viz')

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, 1, 0.1, 1000 );

var renderer = new THREE.WebGLRenderer({ canvas: canvas });
renderer.setSize( 400, 400 );

const geometry = new THREE.BoxGeometry( 3,3,3 );
const material = new THREE.MeshNormalMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );

camera.position.z = 5;

function animate() {
	requestAnimationFrame( animate );
	renderer.render( scene, camera );
  
  cube.rotation.x += 0.01
  cube.rotation.z += 0.01
}
animate();

var stream = canvas.captureStream();

var pc = new RTCPeerConnection(), dc, enterPressed = e => e.keyCode == 13;

var connect = () => init(dc = pc.createDataChannel("chat"));
pc.ondatachannel = e => init(dc = e.channel);

var init = dc => {
  dc.onopen = e => (dc.send("Hi!"), chat.select());
  dc.onclose = e => log("Bye!");
  dc.onmessage = e => log(e.data);
};

pc.oniceconnectionstatechange = e => log(pc.iceConnectionState);
pc.onicecandidate = e => send({ candidate: e.candidate });
pc.onnegotiationneeded = e => pc.createOffer()
  .then(offer => pc.setLocalDescription(offer))
  .then(() => send({ sdp: pc.localDescription }))
  .catch(log);

var sc = new localSocket(), send = obj => sc.send(JSON.stringify(obj));
var incoming = msg => msg.sdp &&
  pc.setRemoteDescription(new RTCSessionDescription(msg.sdp))
  .then(() => pc.signalingState == "stable" || pc.createAnswer()
    .then(answer => pc.setLocalDescription(answer))
    .then(() => send({ sdp: pc.localDescription })))
  .catch(log) || msg.candidate &&
  pc.addIceCandidate(new RTCIceCandidate(msg.candidate)).catch(log);
sc.onmessage = e => incoming(JSON.parse(e.data));

var log = msg => div.innerHTML += "<br>" + msg;

stream.getTracks().forEach(
    function(track) {
      pc.addTrack(
        track,
        stream
      );
    }
  );