WebRTC Renego

Mnimalistic conference built on top of Bistri WebRTC API

by bistri

HTML

<script src="https://cdn.jsdelivr.net/gh/bistri/bistri-conference-js/dist/bistri.conference-3.5.1.js"></script>
<div id="remoteUsers"></div>
<div id="user">
  <div id="localStream"></div>
  <button id="start">Start</button>
  <button id="toggle">Mute Video</button>
  <button id="stop">End</button>
  <button id="share">Screen Sharing</button>
  <button id="remove">Stop Screen</button>
  <button id="force">Force</button>
</div>

CSS

#user {
  position: absolute;
  left: 0;
  bottom: 0;
}

#user video {
  width: 25%;
  height: auto;
}

.wrapper {
  display: inline-block;
  position: relative;
  width: 320px;
}

.wrapper video {
  width: 320px;
  height: auto;
  z-index: 1;
}

.wrapper .data {
  padding: 5px;
  position: absolute;
  right: 0;
  top: 0;
  font-size: .8em;
  font-family: monospace;
  color: #fff;
  background-color: rgba(0,0,0,.3);
  z-index: 2;
}

JavaScript

let localStream,
		screenStream,
    targetStream,
    participants = 0,
    room = "v3-4-0";

function getVideoConsts ( nb )
{
  if ( nb > 1 )
  {
    return {
      "aspectRatio": 16/9,
      "width": { ideal: 320 },
      "height": { ideal: 180 },
      "frameRate": { min: 1, max: 15 }
    }
  }
  else
  {
    return {
      "aspectRatio": 16/9,
      "width": { ideal: 640 },
      "height": { ideal: 360 }
    }
  }
}

function getCallConsts ( nb )
{
  if ( nb > 1 )
  {
    return {
      "stream": targetStream,
      "audio-bitrate": 80,
      "video-bitrate": 233
    };
  }
  else
  {
    return {
      "stream": targetStream,
         "audio-bitrate": 80,
         "video-bitrate": 233
    };
  }
}

function renegociateCalls ()
{
  bc.updateStream ( localStream, {
    video: getVideoConsts ( participants )
  }, () =>
                   {
    bc.reattachStream ( localStream, { "mirror": true } );
    bc.getRoomMembers ( room ).forEach ( member =>
                                        {
      bc.updateCall ( member.id, room, {
        "stream":{ copy: [ localStream, targetStream ] },
        "audio-bitrate": 80,
        "video-bitrate": 233
      } /*getCallConsts ( participants )*/ );
    } );
  } );
}

function createWrapper ( id )
{
  const container = document.querySelector ( "#remoteUsers" ),
        data =  document.createElement ( "div" ),
        wrapper = document.createElement ( "div" );

  data.id = "data_" + id;
  data.className = "data";
  wrapper.id = "wrapper_" + id;
  wrapper.className = "wrapper";
  wrapper.appendChild ( data );
  container.appendChild ( wrapper );

  return wrapper
}

function destroyWrapper ( id )
{
  const wrapper = document.querySelector ( "#wrapper_" + id );

  wrapper.parentNode.removeChild ( wrapper );	
}

function toKbps ( bitrate )
{
  return Math.round ( bitrate / 1000 ) + " kbps";
}

bc.init( {
  appId: "38077edb",
  appKey: "4f304359baa6d0fd1f9106aaeb116f33",
  debug: true,
  autoAcceptCall: false
}...