Advertisement
fodalfadel

webrtc.js

May 12th, 2018
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     // signaling code
  2.     io = io.connect();
  3.    
  4.     var myName = '';
  5.     var theirName = '';
  6.     var myUserType = '';
  7.     var rtcPeerConn;
  8.     var dataChannel;
  9.     var mainVideoArea = document.querySelector('#mainVideoTag');
  10.     var smallVideoArea = document.querySelector('#smallVideoTag');
  11.     var configuration = {
  12.         'iceServers': [{
  13.             'urls': 'stun:stun.l.google.com:19302'
  14.         }]
  15.     };
  16.     var dataChannelOptions = {
  17.         ordered: false, // no guaranteed delivery, unreliable but faster
  18.         maxPacketLifeTime: 1000
  19.     }
  20.    
  21.     // signal handler for socket.io
  22.     io.on('signal', function (data) {
  23.         if (data.user_type == "doctor" && data.command == "joinroom") {
  24.             console.log("The doctor is here!");
  25.    
  26.             if (myUserType == 'patient') {
  27.                 theirName = data.user_name;
  28.                 document.querySelector('#messageOutName').textContent = theirName;
  29.                 document.querySelector('#messageInName').textContent = myName;
  30.             }
  31.    
  32.             // Switch to the doctor listing
  33.             document.querySelector('#requestDoctorForm').style.display = 'none';
  34.             document.querySelector('#waitingForDoctor').style.display = 'none';
  35.             document.querySelector('#doctorListing').style.display = 'block';
  36.         } else if (data.user_type == "patient" && data.command == "calldoctor") {
  37.             console.log('Patient is calling');
  38.    
  39.             if (!rtcPeerConn) {
  40.                 startSignaling();
  41.             }
  42.    
  43.             if (myUserType == 'doctor') {
  44.                 theirName = data.user_name;
  45.                 document.querySelector('#messageOutName').textContent = theirName;
  46.                 document.querySelector('#messageInName').textContent = myName;
  47.             }
  48.    
  49.             document.querySelector('#doctorSignup').style.display = 'none';
  50.             document.querySelector('#videoPage').style.display = 'block';
  51.         } else if (data.user_type == 'signaling') {
  52.             if (!rtcPeerConn) {
  53.                 startSignaling();
  54.             }
  55.    
  56.             var message = JSON.parse(data.user_data);
  57.    
  58.             if (message.sdp) {
  59.                 rtcPeerConn.setRemoteDescription(new RTCSessionDescription(message.sdp), function () {
  60.                     // if we received an offer, we need to answer
  61.                     if (rtcPeerConn.remoteDescription.type == 'offer') {
  62.                         rtcPeerConn.createAnswer(sendLocalDesc, logError);
  63.                     }
  64.                 }, logError);
  65.             } else {
  66.                 rtcPeerConn.addIceCandidate(new RTCIceCandidate(message.candidate));
  67.             }
  68.         }
  69.     });
  70.    
  71.     function startSignaling() {
  72.         console.log('starting signaling...');
  73.    
  74.         rtcPeerConn = new RTCPeerConnection(configuration);
  75.         dataChannel = rtcPeerConn.createDataChannel('textMessages', dataChannelOptions);
  76.    
  77.         dataChannel.onopen = dataChannelStateChanged;
  78.         rtcPeerConn.ondatachannel = receiveDataChannel;
  79.    
  80.         // send any ice candidates to the other peer
  81.         rtcPeerConn.onicecandidate = function (evt) {
  82.             if (evt.candidate) {
  83.                 io.emit('signal', {
  84.                     'user_type': 'signaling',
  85.                     'command': 'icecandidate',
  86.                     'user_data': JSON.stringify({
  87.                         'candidate': evt.candidate
  88.                     })
  89.                 });
  90.             }
  91.    
  92.             console.log('completed sending an ice candidate...');
  93.         }
  94.    
  95.         // let the 'negotiationneeded' event trigger offer generation
  96.         rtcPeerConn.onnegotiationneeded = function () {
  97.             console.log('on negotiation called');
  98.    
  99.             rtcPeerConn.createOffer(sendLocalDesc, logError);
  100.         };
  101.    
  102.         // once remote stream arrives, show it in main video element
  103.         rtcPeerConn.ontrack = function (evt) {
  104.             console.log('going to add their stream...');
  105.    
  106.             mainVideoArea.srcObject = evt.stream;
  107.         }
  108.    
  109.         // get a local stream, show it in our video tag and add it to be sent
  110.         navigator.mediaDevices.getUserMedia({
  111.             'audio': true,
  112.             'video': true
  113.         }, function (stream) {
  114.             console.log('going to display my stream...');
  115.    
  116.             smallVideoArea.srcObject = stream;
  117.    
  118.             rtcPeerConn.addStream(stream);
  119.         }, logError);
  120.     }
  121.    
  122.     function sendLocalDesc(desc) {
  123.         rtcPeerConn.setLocalDescription(desc, function () {
  124.             console.log('sending local description');
  125.    
  126.             io.emit('signal', {
  127.                 'user_type': 'signaling',
  128.                 'command': 'SDP',
  129.                 'user_data': JSON.stringify({
  130.                     'sdp': rtcPeerConn.localDescription
  131.                 })
  132.             });
  133.         }, logError);
  134.     }
  135.    
  136.     function logError(error) {
  137.    
  138.     }
  139.    
  140.     // mute/pause streams video
  141.     var muteMySelf = document.querySelector('#muteMySelf');
  142.     var pauseMyVideo = document.querySelector('#pauseMyVideo');
  143.    
  144.     muteMySelf.addEventListener('click', function (ev) {
  145.         console.log('muting/unmuting myself');
  146.    
  147.         var streams = rtcPeerConn.getLocalStreams();
  148.    
  149.         for (var stream of streams) {
  150.             for (var audioTrack of stream.getAudioTracks()) {
  151.                 if (audioTrack.enabled) {
  152.                     muteMySelf.innerHTML = "Unmute"
  153.                 } else {
  154.                     muteMySelf.innerHTML = "Mute Myself"
  155.                 }
  156.    
  157.                 audioTrack.enabled = !audioTrack.enabled;
  158.             }
  159.    
  160.             console.log('Local stream: ' + stream.id);
  161.         }
  162.    
  163.         ev.preventDefault();
  164.     }, false);
  165.    
  166.     pauseMyVideo.addEventListener('click', function (ev) {
  167.         console.log('pausing/unpausing my video');
  168.    
  169.         var streams = rtcPeerConn.getLocalStreams();
  170.    
  171.         for (var stream of streams) {
  172.             for (var videoTrack of stream.getVideoTracks()) {
  173.                 if (videoTrack.enabled) {
  174.                     pauseMyVideo.innerHTML = 'Start Video';
  175.                 } else {
  176.                     pauseMyVideo.innerHTML = 'Pause Video';
  177.                 }
  178.    
  179.                 videoTrack.enabled = !videoTrack.enabled;
  180.             }
  181.    
  182.             console.log('Local stream: ' + stream.id);
  183.         }
  184.    
  185.         ev.preventDefault();
  186.     }, false);
  187.    
  188.     // Data channel code
  189.     var messageHolder = document.querySelector('#messageHolder');
  190.     var myMessage = document.querySelector('#myMessage');
  191.     var sendMessage = document.querySelector('#sendMessage');
  192.     var receivedFileName;
  193.     var receivedFileSize;
  194.     var fileBuffer = [];
  195.     var fileSize = 0;
  196.     var fileTransferring = false;
  197.    
  198.     function dataChannelStateChanged() {
  199.         if (dataChannel.readyState === 'open') {
  200.             console.log('Data channel open');
  201.    
  202.             dataChannel.onmessage = receiveDataChannelMessage;
  203.         }
  204.     }
  205.    
  206.     function receiveDataChannel(event) {
  207.         console.log('Receiving a data channel');
  208.    
  209.         dataChannel = event.channel;
  210.         dataChannel.onmessage = receiveDataChannelMessage;
  211.     }
  212.    
  213.     function receiveDataChannelMessage(event) {
  214.         console.log('From DataChannel: ' + event.data);
  215.    
  216.         if (fileTransferring) {
  217.             // Here is the file handling code:
  218.             fileBuffer.push(event.data);
  219.             fileSize += event.data.byteLength;
  220.             fileProgress.value = fileSize;
  221.    
  222.             // Provide link to downloadable file when complete
  223.             if (fileSize === receivedFileSize) {
  224.                 var received = new window.Blob(fileBuffer);
  225.                 fileBuffer = [];
  226.    
  227.                 downloadLink.href = URL.createObjectURL(received);
  228.                 downloadLink.download = receivedFileName;
  229.                 downloadLink.appendChild(document.createTextNode(receivedFileName + '(' + fileSize + ') bytes'));
  230.                 fileTransferring = false;
  231.    
  232.                 // Also put the file in the text chat area
  233.                 var linkTag = document.createElement('a');
  234.                 var div = document.createElement('div');
  235.    
  236.                 linkTag.href = URL.createObjectURL(received);
  237.                 linkTag.download = receivedFileName;
  238.                 linkTag.appendChild(document.createTextNode(receivedFileName));
  239.    
  240.                 div.className = 'message-out';
  241.                 div.appendChild(linkTag);
  242.                 messageHolder.appendChild(div);
  243.             }
  244.         } else {
  245.             appendChatMessage(event.data, 'message-out');
  246.         }
  247.     }
  248.    
  249.     sendMessage.addEventListener('click', function (ev) {
  250.         dataChannel.send(myMessage.value);
  251.         appendChatMessage(myMessage.value, 'message-in');
  252.         myMessage.value = '';
  253.    
  254.         ev.preventDefault();
  255.     }, false);
  256.    
  257.     function appendChatMessage(msg, className) {
  258.         var div = document.createElement('div');
  259.         div.className = className;
  260.         div.innerHTML = '<span>' + msg + '</span>';
  261.         messageHolder.appendChild(div);
  262.     }
  263.    
  264.     // File transfer
  265.     var sendFile = document.querySelector('input#sendFile');
  266.     var fileProgress = document.querySelector('progress#fileProgress');
  267.     var downloadLink = document.querySelector('a#receivedFileLink');
  268.    
  269.     io.on('files', function (data) {
  270.         receivedFileName = data.filenime;
  271.         receivedFileSize = data.filesize;
  272.    
  273.         console.log("File on it's way is " + receivedFileName + " (" + receivedFileSize + ")");
  274.    
  275.         fileTransferring = true;
  276.     });
  277.    
  278.     sendFile.addEventListener('change', function (ev) {
  279.         var file = sendFile.files[0];
  280.    
  281.         console.log('sending file ' + file.name + ' (' + file.size + ')...');
  282.    
  283.         io.emit('files', {
  284.             'filename': file.name,
  285.             'filesize': file.size
  286.         });
  287.    
  288.         appendChatMessage('sending ' + file.name, 'message-in');
  289.    
  290.         fileTransferring = true;
  291.    
  292.         fileProgress.max = file.size;
  293.    
  294.         var chunkSize = 16384;
  295.         var sliceFile = function (offset) {
  296.             var reader = new window.FileReader();
  297.             reader.onload = (function () {
  298.                 return function (e) {
  299.                     dataChannel.send(e.target.result);
  300.    
  301.                     if (file.size > offset + e.target.result.byteLength) {
  302.                         window.setTimeout(sliceFile, 0, offset + chunkSize);
  303.                     }
  304.    
  305.                     fileProgress.value = offset + e.target.result.byteLength;
  306.                 };
  307.             })(file);
  308.    
  309.             var slice = file.slice(offset, offset + chunkSize);
  310.    
  311.             reader.readAsArrayBuffer(slice);
  312.         };
  313.    
  314.         sliceFile(0);
  315.         fileTransferring = false;
  316.     }, false);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement