JSFiddle - React, Tailwind, and code Playground

by Hakan Bilgin

HTML

<h1 id="status">
  Status: Waiting for input
</h1>

<div style="padding-bottom: 2rem">
  This page demonstrates how to broadcast to https://twitch.tv directly from your browser. It requires no libraries, extensions or additional software. This is all done in uder 50 lines of Javascript.
</div>

<div style="padding-bottom: 2rem">
  Input your 'Stream Key' in the input field and hit 'Start Streaming'. When the status changes to 'connected' you will be live on your channel.
</div>

<div>
  <b> Stream Key </b> <input id="streamKey" type="text" />
  <button onclick="startStream()"> Start Streaming </button>
</div>

<video id="selfView" autoplay muted style="height: 500px"> </video>

JavaScript

const statusEl = document.getElementById('status')
const updateStatus = (msg, color) => {
  statusEl.innerText = msg
  statusEl.style.background = color
}

window.startStream = () => {
  let peerConnection = new RTCPeerConnection()
  peerConnection.oniceconnectionstatechange = () => {
    switch (peerConnection.iceConnectionState) {
      case 'connecting':
        return updateStatus(peerConnection.iceConnectionState, 'yellow')
      case 'connected':
        return updateStatus(peerConnection.iceConnectionState, 'green')
      case 'disconnected':
      case 'failed':
        return updateStatus(peerConnection.iceConnectionState, 'red')
    }
  }

  navigator.mediaDevices.getUserMedia({
    audio: true,
    video: true
  }).
  then(stream => {
    stream.getTracks().forEach(t => peerConnection.addTrack(t))
    document.getElementById('selfView').srcObject = stream

    peerConnection.createOffer().then(offer => {
      peerConnection.setLocalDescription(offer)
      fetch('https://g.webrtc.live-video.net:4443/v2/offer', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/sdp',
            Authorization: `Bearer ${document.getElementById('streamKey').value}`
          },
          body: offer.sdp,
        }).catch(() => {
          updateStatus('Failed to authenticate', 'red')
        }).then(r => r.text())
        .then(sdp => peerConnection.setRemoteDescription({
          type: 'answer',
          sdp
        }))
    })
  }).catch(() => {
    updateStatus('Failed to capture webcam', 'red')
  })
}