I work with MFF and GH. Whether other browsers are friends with WebRTC , you can find out by going to sipjs.com - there without registration you can admire yourself in duplicate (if you have a webcam), send yourself a message or file. And all this on one page. Not interested. I wonder when I'm on one page, and my counterpart on another. The demo example needs a little tweak ...
How it all works (in my understanding):
WebRTC is the connection of two UserAgents (i.e., two browsers, then UA) point-to-point, at which the signal from a webcam captured by one browser is transmitted to another browser by a rapid flow.
To establish a connection and break through the fence, NAT'ov needs a SIP and STUN server. Both UAs must be registered on the SIP server. Something like "1234@myfreefreefreeswitch.ru".
UA with the name "1234 @ ..." and the password "111" logs in to the SIP server "myfreefreefreeswitch.ru" and says: I want to contact UA "5678 @ ..." for voice transmission. If both are online, the server connects them.
The browser asks the user: "The microphone is asked. Let us give?". We give, and get voice-ip.
You can check video chat from two different computers on the basis of a demo example from sipjs.com , using sipjs.onsip.com as a SIP / STUN server.
Sipjs.onsip.com does not require prior registration. It serves UA pairs with names
"alice. random string@sipjs.onsip.com" and
"bob.the same random string@sipjs.onsip.com . "
Actually "bob." or "alice." not required. You can connect with any unique name. But it is indecent.
Random lines in their demo example are generated by JS when opening the page and for some reason are transmitted to the server in document.cookie. The relationship to the SIP protocol is apparently not necessary for something else (for example, to register a new, curious user).
To check the video chat from 2 computers, the http server is not required, 2 html pages are enough (on one: "I am Bob, I want to contact Alice," on the other: "I am Alice, I want to contact Bob") and single script.
The pages are almost the same (made one by one). !!! Before opening them it is necessary to fix 1 line in both pages in the same way !!!
IT IS IMPORTANT!!! var token = '42c3';
42c3 must be corrected for any long line (English letters and numbers), otherwise your Bob and Alice will come into conflict with those who have not corrected.
In addition, it is possible that at some point your string will become obsolete and everything will stop working. Replace it in both pages with the same new line.
Remember: this demo from sipjs.com and onsip.com is not exactly used as planned. I hope they will not be offended - we are popularizing them.
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="utf-8"> <title>Alice-tv</title> <script> var domain = 'sipjs.onsip.com'; var token = '42c3'; var d123 = new Date(); d123.setTime(d123.getTime() + 1000*60*60); // expires in 1 hour document.cookie = ('onsipToken=' + token + ';' + 'expires=' + d123.toUTCString() + ';'); var fromName = 'Alice'; var toName = 'Bob'; var fromURI = fromName.toLowerCase() + '.' + token + '@' + domain; var toURI = toName.toLowerCase() + '.' + token + '@' + domain; </script> <script src="https://rawgit.com/onsip/SIP.js/0.7.5/dist/sip-0.7.5.js"></script> <script src="demo.js"></script> </head> <body> <div class="content"> <div class="demo-window"> <div class="left"> <h4> </h4> <h5> </h5> </div> <div class="demo-view"> <video id="video" muted="muted"></video> </div> <button id="video-button" class="right" type="button">video</button> <div class="clearfix"></div> <div id="content-message"> <div id="message-display"> <p class="message"><span class="message-from"></span> <span class="message-body placeholder">No messages yet</span></p> </div> <textarea id="message-input" class="message-input" placeholder="Enter your message here!"></textarea> <br> <button id="message-button" class="right" type="button">send message</button> </div> </div> </div> </body> </html>
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="utf-8"> <title>Bob-tv</title> <script> var domain = 'sipjs.onsip.com'; var token = '42c3'; var d123 = new Date(); d123.setTime(d123.getTime() + 1000*60*60); // expires in 1 hour document.cookie = ('onsipToken=' + token + ';' + 'expires=' + d123.toUTCString() + ';'); var fromName = 'Bob'; var toName = 'Alice'; var fromURI = fromName.toLowerCase() + '.' + token + '@' + domain; var toURI = toName.toLowerCase() + '.' + token + '@' + domain; </script> <script src="https://rawgit.com/onsip/SIP.js/0.7.5/dist/sip-0.7.5.js"></script> <script src="demo.js"></script> </head> <body> <div class="content"> <div class="demo-window"> <div class="left"> <h4> </h4> <h5> </h5> </div> <div class="demo-view"> <video id="video" muted="muted"></video> </div> <button id="video-button" class="right" type="button">video</button> <div class="clearfix"></div> <div id="content-message"> <div id="message-display"> <p class="message"><span class="message-from"></span> <span class="message-body placeholder">No messages yet</span></p> </div> <textarea id="message-input" class="message-input" placeholder="Enter your message here!"></textarea> <br> <button id="message-button" class="right" type="button">send message</button> </div> </div> </div> </body> </html>
The script does not transmit sound (the computer will not start yelling like a TV). To allow audio, you need to fix false to true in 2 places:
line 96: var options = mediaOptions ( false , true, remoteRender, null);
line 116-117: session = makeCall (userAgent, target,
false true
function createUA(callerURI, displayName) { var configuration = { traceSip: true, uri: callerURI, displayName: displayName }; var userAgent = new SIP.UA(configuration); return userAgent; } function setUpMessageInterface(userAgent, target, messageRenderId, messageInputId, buttonId) { var messageRender = document.getElementById(messageRenderId); var messageInput = document.getElementById(messageInputId); var button = document.getElementById(buttonId); function sendMessage() { var msg = messageInput.value; if (msg !== '') { messageInput.value = ''; userAgent.message(target, msg); } } var noMessages = true; userAgent.on('message', function (msg) { if (noMessages) { noMessages = false; if (messageRender.childElementCount > 0) messageRender.removeChild(messageRender.children[0]); } var msgTag = createMsgTag(msg.remoteIdentity.displayName, msg.body); messageRender.appendChild(msgTag); }); button.addEventListener('click', function () { sendMessage(); }); messageInput.onkeydown = (function(e) { if(e.keyCode == 13 && !e.shiftKey) { e.preventDefault(); sendMessage(); } }); } function createMsgTag(from, msgBody) { var msgTag = document.createElement('p'); msgTag.className = 'message'; var fromTag = document.createElement('span'); fromTag.appendChild(document.createTextNode(from + ':')); var msgBodyTag = document.createElement('span'); msgBodyTag.appendChild(document.createTextNode(' ' + msgBody)); msgTag.appendChild(fromTag); msgTag.appendChild(msgBodyTag); return msgTag; } function mediaOptions(audio, video, remoteRender, localRender) { return { media: { constraints: { audio: audio, video: video }, render: { remote: remoteRender, local: localRender } } }; } function makeCall(userAgent, target, audio, video, remoteRender, localRender) { var options = mediaOptions(audio, video, remoteRender, localRender); var session = userAgent.invite('sip:' + target, options); return session; } function setUpVideoInterface(userAgent, target, remoteRenderId, buttonId) { var onCall = false; var session; var remoteRender = document.getElementById(remoteRenderId); var button = document.getElementById(buttonId); userAgent.on('invite', function (incomingSession) { onCall = true; session = incomingSession; var options = mediaOptions(false, true, remoteRender, null); button.firstChild.nodeValue = 'hang up'; session.accept(options); session.on('bye', function () { onCall = false; button.firstChild.nodeValue = 'video'; session = null; }); }); button.addEventListener('click', function () { if (onCall) { onCall = false; button.firstChild.nodeValue = 'video'; session.bye(); session = null; } else { onCall = true; button.firstChild.nodeValue = 'hang up'; session = makeCall(userAgent, target, false, true, remoteRender, null); session.on('bye', function () { onCall = false; button.firstChild.nodeValue = 'video'; session = null; }); } }); } //**************************** (function () { if (SIP.WebRTC.isSupported()) { window.fromUA = createUA(fromURI, fromName); var registrationFailed = false; var failRegistration = function () { registrationFailed = true; failInterfaceSetup(); }; fromUA.on('registered', setupInterfaces); fromUA.on('registrationFailed', failRegistration); window.onunload = function () { fromUA.stop(); }; function setupInterfaces() { setUpVideoInterface(fromUA, toURI, 'video', 'video-button'); setUpMessageInterface(fromUA, toURI, 'message-display', 'message-input', 'message-button'); } function failInterfaceSetup() { alert('Max registration limit hit. The app is disabled.'); } } })();
For those who will install it on the server and are familiar with jinja2
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="utf-8"> <title>{{fromName}}-tv</title> <script> var domain = 'sipjs.onsip.com'; var token = '{{token}}'; var d123 = new Date(); d123.setTime(d123.getTime() + 1000*60*60); // expires in 1 hour document.cookie = ('onsipToken=' + token + ';' + 'expires=' + d123.toUTCString() + ';'); var fromName = '{{fromName}}'; var toName = '{{toName}}'; var fromURI = fromName.toLowerCase() + '.' + token + '@' + domain; var toURI = toName.toLowerCase() + '.' + token + '@' + domain; </script> <script src="https://rawgit.com/onsip/SIP.js/0.7.5/dist/sip-0.7.5.js"></script> <script src="{{request.static_url('mydoctor:static/demo.js')}}"></script> </head> <body> <div class="content"> <div class="demo-window"> <div class="left"> <h4>{{title}}</h4> <h5>{{comment}}</h5> </div> <div class="demo-view"> <video id="video" muted="muted"></video> </div> <button id="video-button" class="right" type="button">video</button> <div class="clearfix"></div> <div id="content-message"> <div id="message-display"> <p class="message"><span class="message-from"></span> <span class="message-body placeholder">No messages yet</span></p> </div> <textarea id="message-input" class="message-input" placeholder="Enter your message here!"></textarea> <br> <button id="message-button" class="right" type="button">send message</button> </div> </div> </div> </body> </html>
_token = uuid.uuid4().hex ... { 'title': ' ', 'comment': ' ', 'fromName':'Alice', 'toName':'Bob', 'token': _token } ... { 'title': ' ', 'comment': ' ', 'fromName':'Bob', 'toName':'Alice', 'token': _token }
Unique name extensions for Alice and Bob will make the server on boot.
I tried to set up my SIP server. I chose FreeSWITCH , I understood the settings a day, but I could not adjust it: the voice came with a delay of 5 (five) seconds, the video hung with a strange recording in the FS log that the video format was not supported.
Text and files were sent normally. It seems that FS tried to skip everything through itself (video conferencing or for other purposes).
I hope that some SIP / STUN specialist will smile, drive me a minus for ineptitude and explain which SIP / STUN to choose and how to configure it.
Source: https://habr.com/ru/post/312868/
All Articles