Хорошо, поэтому я делаю учебники по webRTC, и я использовал следующие два учебника, чтобы помочь мне.
Учебное пособие Sitepoint и Учебное пособие по скотчу
Первое, на что нужно обратить внимание, для первого урока, даже с исходным кодом, клонированным из github здесь:
https://github.com/sitepoint-editors/simplewebrtc-messenger.git
при развертывании приложения на Now.sh оно работает, но я не могу присоединиться к другим пользователям.
TLDR;
Вот Мое развернутое приложение .Когда я пытаюсь подключиться к удаленному соединению, я получаю эту ошибку
Uncaught DOMException: не удалось создать «RTCPeerConnection»: «stun.l.google.com» не является одной из поддерживаемых схем URL «stun',' turn 'или' turns.
Вот [исходный код
// 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>
Есть идеи о том, что я делаю неправильно?