Reputation: 173
Ok so I am doing tutorials on webRTC and I've been using the following two tutorials to help me.
Sitepoint tutorial and Scotch tutorial
First thing to note, for the first tutorial even with the source code cloned from github here:
https://github.com/sitepoint-editors/simplewebrtc-messenger.git
when I deploy the app on Now.sh it works but I am unable to join different users.
TLDR;
Here is My Deployed App. When I try to join a remote connection I get this error
Uncaught DOMException: Failed to construct 'RTCPeerConnection': 'stun.l.google.com' is not one of the supported URL schemes 'stun', 'turn' or 'turns'.
Here is the [source code
// Code goes here
let username, roomname;
// Determine whether or not we have a querystring.
function hasQueryString() {
console.log(location.href.indexOf("?"))
return location.href.indexOf("?") !== -1;
}
const formEl = $('.form');
// Enable video on the page.
function enableVideo() {
document.getElementById("url").style.display = "block";
document.getElementById("remotes").style.visibility = "visible";
loadSimpleWebRTC();
}
if (hasQueryString()) {
console.log("Query string!");
enableVideo();
if (formEl) {
formEl.hide();
}
} else if (formEl) {
formEl.show();
}
// Handle form submission
console.log("Form loaded!")
$("#join-btn").click(function (event) {
const formEl = $('.form');
var usernameInput = formEl.find('#inputUsername');
var roomnameInput = formEl.find('#inputRoomname');
if (usernameInput.length > 0 && !usernameInput[0].value) {
alert("Invalid username!")
} else if (roomnameInput.length > 0 && !roomnameInput[0].value) {
alert("Please enter a roomname");
} else if (roomnameInput.length > 0 && roomnameInput[0].value.length < 6) {
alert("Roomname must be longer than 5 characters!");
} else {
username = usernameInput[0].value;
roomname = roomnameInput[0].value.toLowerCase();
window.location = getRoomURL();
enableVideo();
}
return false;
})
// Determine the room name and public URL for this chat session.
function getRoom() {
if (roomname) {
return roomname;
} else {
var query = location.search && location.search.split("?")[1];
console.log(query);
if (query) {
console.log("roomname is:");
console.log((location.search && decodeURIComponent(query.split("=")[1]).toLowerCase()));
roomname = location.search && decodeURIComponent(query.split("=")[1]).toLowerCase();
return roomname;
}
}
roomname = "room" + Math.floor(Math.random() * 0xFFFFFF).toString(16);
return roomname;
}
function getUser() {
if (username) {
return username;
} else return "User" + Math.floor(Math.random() * 0xFFFFFF).toString(16);
}
// Retrieve the absolute room URL.
function getRoomURL() {
return location.protocol + "//" + location.host + (location.path || "") + "?room=" + getRoom();
}
// Dynamically load the simplewebrtc script so that we can
// kickstart the video call.
function loadSimpleWebRTC() {
var script = document.createElement("script");
script.src = "https://simplewebrtc.com/latest-v3.js";
document.head.appendChild(script);
script.onload = function () {
var webrtc = new SimpleWebRTC({
localVideoEl: "selfVideo",
// the id/element dom element that will hold remote videos
remoteVideosEl: "",
autoRequestMedia: true,
debug: false,
detectSpeakingEvents: true,
autoAdjustMic: false
});
// Set the publicly available room URL.
document.getElementById("roomUrl").innerText = getRoomURL();
// Immediately join room when loaded.
webrtc.on("readyToCall", function () {
webrtc.joinRoom(getRoom());
});
function showVolume(el, volume) {
if (!el) return;
if (volume < -45) volume = -45; // -45 to -20 is
if (volume > -20) volume = -20; // a good range
el.value = volume;
}
// Display the volume meter.
webrtc.on("localStream", function (stream) {
var button = document.querySelector("form>button");
if (button) button.removeAttribute("disabled");
document.getElementById("localVolume").style.display = "block";
});
// If we didn't get access to the camera, raise an error.
webrtc.on("localMediaError", function (err) {
alert("This service only works if you allow camera access.Please grant access and refresh the page.");
});
// When another person joins the chat room, we'll display their video.
webrtc.on("videoAdded", function (video, peer) {
console.log("user added to chat", peer);
var remotes = document.getElementById("remotes");
if (remotes) {
var outerContainer = document.createElement("div");
outerContainer.className = "col-md-6";
var container = document.createElement("div");
container.className = "videoContainer";
container.id = "container_" + webrtc.getDomId(peer);
container.appendChild(video);
// Suppress right-clicks on the video.
video.oncontextmenu = function () { return false; };
// Show the volume meter.
var vol = document.createElement("meter");
vol.id = "volume_" + peer.id;
vol.className = "volume";
vol.min = -45;
vol.max = -20;
vol.low = -40;
vol.high = -25;
container.appendChild(vol);
// Show the connection state.
if (peer && peer.pc) {
var connstate = document.createElement("div");
connstate.className = "connectionstate";
container.appendChild(connstate);
peer.pc.on("iceConnectionStateChange", function (event) {
switch (peer.pc.iceConnectionState) {
case "checking":
connstate.innerText = "connecting to peer...";
break;
case "connected":
case "completed": // on caller side
vol.style.display = "block";
connstate.innerText = "connection established";
break;
case "disconnected":
connstate.innerText = "disconnected";
break;
case "failed":
connstate.innerText = "connection failed";
break;
case "closed":
connstate.innerText = "connection closed";
break;
}
});
}
outerContainer.appendChild(container);
remotes.appendChild(outerContainer);
// If we're adding a new video we need to modify bootstrap so we
// only get two videos per row.
var remoteVideos = document.getElementById("remotes").getElementsByTagName("video").length;
if (!(remoteVideos % 2)) {
var spacer = document.createElement("div");
spacer.className = "w-100";
remotes.appendChild(spacer);
}
}
});
// If a user disconnects from chat, we need to remove their video feed.
webrtc.on("videoRemoved", function (video, peer) {
console.log("user removed from chat", peer);
var remotes = document.getElementById("remotes");
var el = document.getElementById("container_" + webrtc.getDomId(peer));
if (remotes && el) {
remotes.removeChild(el.parentElement);
}
});
// If our volume has changed, update the meter.
webrtc.on("volumeChange", function (volume, treshold) {
showVolume(document.getElementById("localVolume"), volume);
});
// If a remote user's volume has changed, update the meter.
webrtc.on("remoteVolumeChange", function (peer, volume) {
showVolume(document.getElementById("volume_" + peer.id), volume);
});
// If there is a P2P failure, we need to error out.
webrtc.on("iceFailed", function (peer) {
var connstate = document.querySelector("#container_" + webrtc.getDomId(peer) + " .connectionstate");
console.log("local fail", connstate);
if (connstate) {
connstate.innerText = "connection failed";
fileinput.disabled = "disabled";
}
});
// remote p2p/ice failure
webrtc.on("connectivityError", function (peer) {
var connstate = document.querySelector("#container_" + webrtc.getDomId(peer) + " .connectionstate");
console.log("remote fail", connstate);
if (connstate) {
connstate.innerText = "connection failed";
fileinput.disabled = "disabled";
}
});
}
}
body {
font-family: 'Raleway', sans-serif;
}
footer {
text-align: center;
margin-top: 2em;
}
h2 {
font-style: italic;
}
header {
text-align: center;
margin: 4em;
}
header h1, header h2 {
display: inline;
}
header h1 a, header h2 a, header h1 a:hover, header h2 a:hover {
color: inherit;
text-decoration: none;
}
header h2 {
font-size: 24px;
padding-left: .5em;
}
#remotes {
visibility: hidden;
}
#url {
text-align: center;
display: none;
}
#login {
display: none;
}
#roomIntro {
font-weight: bold;
}
.videoContainer {
object-fit: cover;
margin: 0 auto;
padding: 0;
}
.videoContainer video {
width: 100%;
height: 100%;
border-radius: 10px;
border: 5px double #f2f2f2;
}
.volume {
position: absolute;
left: 15%;
width: 70%;
bottom: 20px;
height: 10px;
display: none;
}
.connectionstate {
position: absolute;
top: 10px;
width: 100%;
text-align: center;
color: #fff
}
.col-md-6 {
margin-bottom: 1em;
}
<!DOCTYPE html>
<html>
<head>
<title>vchat - a simple video chat app</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB"
crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://webrtc.github.io/adapter/adapter-4.2.2.js"></script>
<link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
<div id="enter-form-container" class="jumbotron col-md-6 banner">
<h1 class="display-4">Web Chat</h1>
<p class="lead">This is a simple free webRTC video chat.</p>
<hr class="my-4">
<!-- <a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a>-->
<div id="enter-form" class="form">
<p>Enter a username followed by a room name to join a preexisting room or create a new one.</p>
<div class="form-group">
<label for="exampleInputUsername1">Username</label>
<input type="text" class="form-control" id="inputUsername" name="username" aria-describedby="usernameHelp" placeholder="Enter Username">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Room Name</label>
<input type="text" class="form-control" id="inputRoomname" name="roomname" placeholder="Room Name">
</div>
<button id="join-btn" class="btn btn-primary submit">Enter Room</button>
</div>
<div id="url" class="alert alert-dark" role="alert">
<span id="roomIntro">ROOM URL</span>:
<span id="roomUrl"></span>
</div>
<div id="chat"></div>
</div>
</div>
<div id="remotes" class="row">
<div class="col-md-6">
<div class="videoContainer">
<video id="selfVideo" oncontextmenu="return false;"></video>
<meter id="localVolume" class="volume" min="-45" max="-20" high="-25" low="-40"></meter>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T"
crossorigin="anonymous"></script>
<script src="script.js"></script>
</body>
</html>
Any ideas as to what I'm doing wrong??
Upvotes: 0
Views: 2822
Reputation: 173
OK so apparently there has been some issues with simpleWebRTC's Sandbox signalling server all week and they also advise that you use your own signaling server.
So I found XirSys xsdk platform and followed their simpleWebRtc example and BOOM! It works.
Upvotes: 0
Reputation: 12174
Use:
stun:stun.l.google.com:19302
There should be stun
in the Server URL and indicate the Port Number.
Upvotes: 5