Created
October 29, 2025 13:42
-
-
Save tiagocoutinho/e89e9d4a414abcc4451a44f9b2011a12 to your computer and use it in GitHub Desktop.
WebRTC browser, no signaling
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset='utf-8'> | |
| <title>WebRTC Demo</title> | |
| <style> | |
| textarea { width: 100%; height: 100px;} | |
| .video-player { border: 2px solid greenyellow; background-color: gray; width: 100%; } | |
| </style> | |
| </head> | |
| <body> | |
| <div> | |
| <h2>WebRTC, Passing SDP with no signaling.</h2> | |
| <p><b>Instructions: </b> | |
| Start by opening two tabs side by side and follow the steps below to pass SDP offer and answer. | |
| I will refer to each tab as <i><b>User 1</b></i> and <i><b>User 2</b></i>. | |
| </p> | |
| <ul> | |
| <li>User 1 & 2: <button onclick="init()">Initialize</button></li> | |
| <li>User 1:<button id="create-offer" onclick="createOffer()">Create offer</button></li> | |
| <li>User 2: paste offer generated by user 1 into offer field and <button id="create-answer" | |
| onclick="createAnswer()">Create answer</button></li> | |
| <li>User 1: paste offer generated by user 2 into answer field and <button id="add-answer" | |
| onclick="addAnswer()">Add answer</button></li> | |
| </ul> | |
| <div style="display: flex; column-gap: 1em;width: 100%;"> | |
| <div style="width: 100%;"> | |
| <label for="offer-sdp">SDP OFFER:</label> | |
| <textarea id="offer-sdp" placeholder='User 1 click create offer; User 2, paste offer here...'></textarea> | |
| <video class="video-player" id="user-1" autoplay playsinline></video> | |
| </div> | |
| <div style="width: 100%;"> | |
| <label for="answer-sdp">SDP Answer:</label> | |
| <textarea id="answer-sdp" placeholder="User 2: click create answer; User 1: paste answer here..."></textarea> | |
| <video class="video-player" id="user-2" autoplay playsinline></video> | |
| </div> | |
| </div> | |
| </body> | |
| <script> | |
| let peerConnection = null; | |
| const offerTextArea = document.getElementById('offer-sdp'); | |
| const answerTextArea = document.getElementById('answer-sdp'); | |
| let init = async () => { | |
| offerTextArea.value = ""; | |
| answerTextArea.value = ""; | |
| if (peerConnection != null) { | |
| peerConnection.close(); | |
| } | |
| peerConnection = new RTCPeerConnection(); | |
| const localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: false }) | |
| const remoteStream = new MediaStream(); | |
| document.getElementById('user-1').srcObject = localStream | |
| document.getElementById('user-2').srcObject = remoteStream; | |
| localStream.getTracks().forEach((track) => { | |
| peerConnection.addTrack(track, localStream); | |
| }); | |
| peerConnection.ontrack = (event) => { | |
| event.streams[0].getTracks().forEach((track) => { | |
| remoteStream.addTrack(track); | |
| }); | |
| }; | |
| } | |
| function onIceFor(textArea) { | |
| return async event => { | |
| if (event.candidate) { | |
| textArea.value = JSON.stringify(peerConnection.localDescription); | |
| navigator.clipboard.writeText(textArea.value); | |
| } | |
| } | |
| } | |
| let createOffer = async () => { | |
| peerConnection.onicecandidate = onIceFor(offerTextArea); | |
| const offer = await peerConnection.createOffer(); | |
| await peerConnection.setLocalDescription(offer); | |
| } | |
| let createAnswer = async () => { | |
| let offer = JSON.parse(offerTextArea.value) | |
| peerConnection.onicecandidate = onIceFor(answerTextArea); | |
| await peerConnection.setRemoteDescription(offer); | |
| let answer = await peerConnection.createAnswer(); | |
| await peerConnection.setLocalDescription(answer); | |
| } | |
| let addAnswer = async () => { | |
| let answer = JSON.parse(answerTextArea.value); | |
| if (!peerConnection.currentRemoteDescription) { | |
| peerConnection.setRemoteDescription(answer); | |
| } | |
| } | |
| </script> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment