/websocket-over-nodejs/public/one-to-one-peerconnection.html

https://github.com/BACtaki/WebRTC-Experiment · HTML · 445 lines · 365 code · 69 blank · 11 comment · 0 complexity · b61a1083f31d342e434c1908c261733b MD5 · raw file

  1. <!-- Make sure that you executed "signaler.js" or "ssl.js" instead of "simple.js"!! -->
  2. <!--
  3. > Muaz Khan - https://github.com/muaz-khan
  4. > MIT License - https://www.webrtc-experiment.com/licence/
  5. > Documentation - https://github.com/muaz-khan/WebRTC-Experiment/tree/master/websocket
  6. -->
  7. <!DOCTYPE html>
  8. <html lang="en">
  9. <head>
  10. <title>WebRTC » WebSockets ® Muaz Khan</title>
  11. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  12. <meta charset="utf-8">
  13. <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
  14. <link rel="author" type="text/html" href="https://plus.google.com/+MuazKhan">
  15. <meta name="author" content="Muaz Khan">
  16. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  17. <link rel="stylesheet" href="//www.webrtc-experiment.com/style.css">
  18. <style>
  19. audio, video {
  20. -moz-transition: all 1s ease;
  21. -ms-transition: all 1s ease;
  22. -o-transition: all 1s ease;
  23. -webkit-transition: all 1s ease;
  24. transition: all 1s ease;
  25. vertical-align: top;
  26. }
  27. input {
  28. border: 1px solid #d9d9d9;
  29. border-radius: 1px;
  30. font-size: 2em;
  31. margin: .2em;
  32. width: 30%;
  33. }
  34. .setup {
  35. border-bottom-left-radius: 0;
  36. border-top-left-radius: 0;
  37. font-size: 102%;
  38. height: 47px;
  39. margin-left: -9px;
  40. margin-top: 8px;
  41. position: absolute;
  42. }
  43. p { padding: 1em; }
  44. li {
  45. border-bottom: 1px solid rgb(189, 189, 189);
  46. border-left: 1px solid rgb(189, 189, 189);
  47. padding: .5em;
  48. }
  49. .highlight { color: rgb(0, 8, 189); }
  50. </style>
  51. <script>
  52. document.createElement('article');
  53. document.createElement('footer');
  54. </script>
  55. <!-- scripts used for peers connection -->
  56. <script src="//www.webrtc-experiment.com/websocket/PeerConnection.js"> </script>
  57. </head>
  58. <body>
  59. <article>
  60. <header style="text-align: center;">
  61. <h1>
  62. <a href="https://www.webrtc-experiment.com/">WebRTC</a>
  63. »
  64. <a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/websocket" target="_blank">WebSockets</a>
  65. ®
  66. <a href="https://github.com/muaz-khan" target="_blank">Muaz Khan</a>
  67. </h1>
  68. <p>
  69. <a href="https://www.webrtc-experiment.com/">HOME</a>
  70. <span> &copy; </span>
  71. <a href="http://www.MuazKhan.com/" target="_blank">Muaz Khan</a>
  72. .
  73. <a href="http://twitter.com/WebRTCWeb" target="_blank" title="Twitter profile for WebRTC Experiments">@WebRTCWeb</a>
  74. .
  75. <a href="https://github.com/muaz-khan?tab=repositories" target="_blank" title="Github Profile">Github</a>
  76. .
  77. <a href="https://github.com/muaz-khan/WebRTC-Experiment/issues?state=open" target="_blank">Latest issues</a>
  78. .
  79. <a href="https://github.com/muaz-khan/WebRTC-Experiment/commits/master" target="_blank">What's New?</a>
  80. </p>
  81. </header>
  82. <div class="github-stargazers"></div>
  83. <!-- just copy this <section> and next script -->
  84. <section class="experiment">
  85. <section>
  86. <span>
  87. Private ?? <a href="" target="_blank" title="Setup Private Room!"><code><strong id="unique-token">#123456789</strong></code></a>
  88. </span>
  89. <input type="text" id="your-name" placeholder="your-name">
  90. <button id="start-broadcasting" class="setup">Start Transmitting Yourself!</button>
  91. </section>
  92. <!-- list of all available conferencing rooms -->
  93. <table id="rooms-list" style="width: 100%;"></table>
  94. <!-- local/remote videos container -->
  95. <div id="videos-container"></div>
  96. </section>
  97. <script>
  98. // Muaz Khan - https://github.com/muaz-khan
  99. // MIT License - https://www.webrtc-experiment.com/licence/
  100. // Documentation - https://github.com/muaz-khan/WebRTC-Experiment/tree/master/websocket
  101. var channel = location.href.replace( /\/|:|#|%|\.|\[|\]/g , '');
  102. // var websocket = new WebSocket('ws://wsnodejs.jit.su:80');
  103. var websocket = new WebSocket('ws://' + document.domain + ':12034');
  104. websocket.onopen = function() {
  105. websocket.push(JSON.stringify({
  106. open: true,
  107. channel: channel
  108. }));
  109. };
  110. websocket.push = websocket.send;
  111. websocket.send = function(data) {
  112. websocket.push(JSON.stringify({
  113. data: data,
  114. channel: channel
  115. }));
  116. };
  117. var peer = new PeerConnection(websocket);
  118. peer.onUserFound = function(userid) {
  119. if (document.getElementById(userid)) return;
  120. var tr = document.createElement('tr');
  121. var td1 = document.createElement('td');
  122. var td2 = document.createElement('td');
  123. td1.innerHTML = userid + ' has camera. Are you interested in video chat?';
  124. var button = document.createElement('button');
  125. button.innerHTML = 'Join';
  126. button.id = userid;
  127. button.style.float = 'right';
  128. button.onclick = function() {
  129. button = this;
  130. getUserMedia(function(stream) {
  131. peer.addStream(stream);
  132. peer.sendParticipationRequest(button.id);
  133. });
  134. button.disabled = true;
  135. };
  136. td2.appendChild(button);
  137. tr.appendChild(td1);
  138. tr.appendChild(td2);
  139. roomsList.appendChild(tr);
  140. };
  141. peer.onStreamAdded = function(e) {
  142. if (e.type == 'local') document.querySelector('#start-broadcasting').disabled = false;
  143. var video = e.mediaElement;
  144. video.setAttribute('width', 600);
  145. video.setAttribute('controls', true);
  146. videosContainer.insertBefore(video, videosContainer.firstChild);
  147. video.play();
  148. rotateVideo(video);
  149. scaleVideos();
  150. };
  151. peer.onStreamEnded = function(e) {
  152. var video = e.mediaElement;
  153. if (video) {
  154. video.style.opacity = 0;
  155. rotateVideo(video);
  156. setTimeout(function() {
  157. video.parentNode.removeChild(video);
  158. scaleVideos();
  159. }, 1000);
  160. }
  161. };
  162. document.querySelector('#start-broadcasting').onclick = function() {
  163. this.disabled = true;
  164. getUserMedia(function(stream) {
  165. peer.addStream(stream);
  166. peer.startBroadcasting();
  167. });
  168. };
  169. document.querySelector('#your-name').onchange = function() {
  170. peer.userid = this.value;
  171. };
  172. var videosContainer = document.getElementById('videos-container') || document.body;
  173. var btnSetupNewRoom = document.getElementById('setup-new-room');
  174. var roomsList = document.getElementById('rooms-list');
  175. if (btnSetupNewRoom) btnSetupNewRoom.onclick = setupNewRoomButtonClickHandler;
  176. function rotateVideo(video) {
  177. video.style[navigator.mozGetUserMedia ? 'transform' : '-webkit-transform'] = 'rotate(0deg)';
  178. setTimeout(function() {
  179. video.style[navigator.mozGetUserMedia ? 'transform' : '-webkit-transform'] = 'rotate(360deg)';
  180. }, 1000);
  181. }
  182. function scaleVideos() {
  183. var videos = document.querySelectorAll('video'),
  184. length = videos.length, video;
  185. var minus = 130;
  186. var windowHeight = 700;
  187. var windowWidth = 600;
  188. var windowAspectRatio = windowWidth / windowHeight;
  189. var videoAspectRatio = 4 / 3;
  190. var blockAspectRatio;
  191. var tempVideoWidth = 0;
  192. var maxVideoWidth = 0;
  193. for (var i = length; i > 0; i--) {
  194. blockAspectRatio = i * videoAspectRatio / Math.ceil(length / i);
  195. if (blockAspectRatio <= windowAspectRatio) {
  196. tempVideoWidth = videoAspectRatio * windowHeight / Math.ceil(length / i);
  197. } else {
  198. tempVideoWidth = windowWidth / i;
  199. }
  200. if (tempVideoWidth > maxVideoWidth)
  201. maxVideoWidth = tempVideoWidth;
  202. }
  203. for (var i = 0; i < length; i++) {
  204. video = videos[i];
  205. if (video)
  206. video.width = maxVideoWidth - minus;
  207. }
  208. }
  209. window.onresize = scaleVideos;
  210. // you need to capture getUserMedia yourself!
  211. function getUserMedia(callback) {
  212. var hints = {
  213. audio: true,
  214. video: {
  215. optional: [],
  216. mandatory: {
  217. minWidth: 1280,
  218. minHeight: 720,
  219. maxWidth: 1920,
  220. maxHeight: 1080,
  221. minAspectRatio: 1.77
  222. }
  223. }
  224. };
  225. navigator.getUserMedia(hints, function(stream) {
  226. var video = document.createElement('video');
  227. video.src = URL.createObjectURL(stream);
  228. video.controls = true;
  229. video.muted = true;
  230. peer.onStreamAdded({
  231. mediaElement: video,
  232. userid: 'self',
  233. stream: stream
  234. });
  235. callback(stream);
  236. });
  237. }
  238. (function() {
  239. var uniqueToken = document.getElementById('unique-token');
  240. if (uniqueToken)
  241. if (location.hash.length > 2) uniqueToken.parentNode.parentNode.parentNode.innerHTML = '<h2 style="text-align:center;"><a href="' + location.href + '" target="_blank">Share this link</a></h2>';
  242. else uniqueToken.innerHTML = uniqueToken.parentNode.parentNode.href = '#' + (Math.random() * new Date().getTime()).toString(36).toUpperCase().replace( /\./g , '-');
  243. })();
  244. </script>
  245. <section class="experiment">
  246. <ol>
  247. <li>Using WebSockets for signaling</li>
  248. <li>It is one-to-one peers connection</li>
  249. </ol>
  250. </section>
  251. <section class="experiment own-widgets latest-commits">
  252. <h2 class="header" id="updates" style="color: red; padding-bottom: .1em;"><a href="https://github.com/muaz-khan/WebRTC-Experiment/commits/master" target="_blank">Latest Updates</a></h2>
  253. <div id="github-commits"></div>
  254. </section>
  255. <section class="experiment">
  256. <h2 class="header" id="feedback">Feedback</h2>
  257. <div>
  258. <textarea id="message" style="border: 1px solid rgb(189, 189, 189); height: 8em; margin: .2em; outline: none; resize: vertical; width: 98%;" placeholder="Have any message? Suggestions or something went wrong?"></textarea>
  259. </div>
  260. <button id="send-message" style="font-size: 1em;">Send Message</button><small style="margin-left: 1em;">Enter your email too; if you want "direct" reply!</small>
  261. </section>
  262. <section class="experiment">
  263. <h2 class="header">How to use PeerConnection.js?</h2>
  264. <pre>
  265. // http://www.webrtc-experiment.com/websocket/PeerConnection.js
  266. var peer = new <strong>PeerConnection</strong>('<strong class="highlight">ws://domain:port</strong>');
  267. peer.<strong title="local or remote stream">onStreamAdded</strong> = function(e) {
  268. document.body.appendChild(e.mediaElement);
  269. };
  270. // the easiest method of "manual" peers connection is
  271. // call "sendParticipationRequest" and pass user-id of the target user
  272. peer.<strong>sendParticipationRequest</strong>(userid);
  273. // <u>otherwise</u>, call "startBroadcasting"
  274. // (behind the scene) this function will be invoked
  275. // recursively until a participant found
  276. peer.<strong>startBroadcasting</strong>();
  277. </pre>
  278. </section>
  279. <section class="experiment">
  280. <h2 class="header">Simplest Demo</h2>
  281. <pre>
  282. var offerer = new <strong title="Constructor takes two arguments.
  283. 1) websocket url and
  284. 2) custom user-id">PeerConnection</strong>('<strong class="highlight" title="websocket url">ws://domain:port</strong>', '<strong class="highlight" title="custom user-id">offerer</strong>');
  285. offerer.<strong title="local or remote stream">onStreamAdded</strong> = function(e) {
  286. document.body.appendChild(e.mediaElement);
  287. };
  288. </pre>
  289. <pre>
  290. var answerer = new <strong title="Constructor takes two arguments.
  291. 1) websocket url and
  292. 2) custom user-id">PeerConnection</strong>('<strong class="highlight" title="websocket url">ws://domain:port</strong>', '<strong class="highlight" title="custom user-id">answerer</strong>');
  293. answerer.<strong title="local or remote stream">onStreamAdded</strong> = function(e) {
  294. document.body.appendChild(e.mediaElement);
  295. };
  296. answerer.<strong title="Ask other user to establish peer connection with you!">sendParticipationRequest</strong>(<strong class="highlight" title="user-id of the offerer">'offerer'</strong>);
  297. </pre>
  298. </section>
  299. <section class="experiment">
  300. <h2 class="header" id="signaling">getUserMedia is "in-your-own-hands"!</h2>
  301. <p>
  302. It is upto you to decide when to capture the stream; how to capture; and the quality of the stream.
  303. </p>
  304. <pre>
  305. function getUserMedia(callback) {
  306. var hints = {
  307. audio: true,
  308. video: {
  309. optional: [],
  310. // capture super-hd stream!
  311. mandatory: {
  312. minWidth: 1280,
  313. minHeight: 720,
  314. maxWidth: 1920,
  315. maxHeight: 1080,
  316. minAspectRatio: 1.77
  317. }
  318. }
  319. };
  320. navigator.getUserMedia(hints, function (stream) {
  321. // you can use "peer.addStream" to attach stream
  322. // peer.addStream(stream);
  323. // or peer.MediaStream = stream;
  324. callback(stream);
  325. // preview local video
  326. var video = document.createElement('video');
  327. video.src = URL.createObjectURL(stream);
  328. video.controls = true;
  329. video.muted = true;
  330. peer.onStreamAdded({
  331. mediaElement: video,
  332. userid: 'self',
  333. stream: stream
  334. });
  335. });
  336. }
  337. </pre>
  338. </section>
  339. <section class="experiment">
  340. <h2 class="header" id="signaling">Want to use <a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/websocket-over-nodejs" target="_blank">WebSocket over Node.js</a>?</h2>
  341. <pre>
  342. var channel = location.href.replace(/\/|:|#|%|\.|\[|\]/g, '');
  343. var websocket = new WebSocket('wss://www.webrtc-experiment.com:8563');
  344. websocket.onopen = function () {
  345. websocket.push(JSON.stringify({
  346. open: true,
  347. channel: channel
  348. }));
  349. };
  350. websocket.push = websocket.send;
  351. websocket.send = function (data) {
  352. websocket.push(JSON.stringify({
  353. data: data,
  354. channel: channel
  355. }));
  356. };
  357. // pass "websocket" object over the constructor instead of URL
  358. var peer = new PeerConnection(websocket);
  359. </pre>
  360. <p>
  361. Check <a href="https://github.com/muaz-khan/WebRTC-Experiment/issues/56#issuecomment-20090650" target="_blank">other signaling examples</a>.
  362. </p>
  363. </section>
  364. </article>
  365. <a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/websocket-over-nodejs" class="fork-right"></a>
  366. <footer>
  367. <p>
  368. <a href="https://www.webrtc-experiment.com/">WebRTC Experiments</a>
  369. © <a href="https://plus.google.com/+MuazKhan" rel="author" target="_blank">Muaz Khan</a>
  370. <a href="mailto:muazkh@gmail.com" target="_blank">muazkh@gmail.com</a>
  371. </p>
  372. </footer>
  373. <!-- commits.js is useless for you! -->
  374. <script src="//www.webrtc-experiment.com/commits.js" async> </script>
  375. </body>
  376. </html>