All,
Я пытаюсь научить webrtc создать дружественный для мобильных устройств веб-интерфейс, аналогичный настройке apprtc, которую Google сделал для чатов P2P. Я хотел редактировать googles apprtc, но я не могу понять все, что в нем есть. Я создал это из учебника и не могу заставить мой браузер отображать мои медиафайлы. В настоящее время работает Nodejs и тестирование на внешних устройствах с ngrok для использования https. Любой совет с благодарностью !!
index.html
<!DOCTYPE html>
<head>
<title>SeeIT WebRTC Test</title>
</head>
<body>
<h1>SeeIT WebRTC Test</h1>
<!--This is the Room Selection Screen-->
<div id="selectRoom">
<label>Type a room number</label>
<input id="roomNumber" type="text" />
<button id="goRoom">GO!</button>
</div>
<!--This is the div that contains video streams-->
<div id="consultingRoom" style="display:none">
<video id="localVideo" autoplay></video>
<video id="remoteVideo" autoplay></video>
</div>
<!--These are the required javascripts libraries-->
<script src="/socket.io/socket.io.js"></script>
<script src="client.js"></script>
<script src='../node_modules/webrtc-adapter/out/adapter.js'></script>
</body>
client.js
// here we get a reference to the webpage elements
var divSelectRoom = document.getElementById("selectRoom");
var divConsultingRoom = document.getElementById("consultingRoom");
var inputRoomNumber = document.getElementById("roomNumber");
var btnGoRoom = document.getElementById("goRoom");
var localVideo = document.getElementById("localVideo");
var remoteVideo = document.getElementById("remoteVideo");
// these are the global variables
var roomNumber;
var localStream;
var remoteStream;
var rtcPeerConnection;
// these are the STUN servers
var iceServers = {
'iceServers': [
{'urls':'stun:stun.services.mozilla.com'},
{'urls':'stun1.I.google.com:19302'}
]
}
var streamConstraints = { audio: true, video: true };
var isCaller;
// here we connect to the socket.io server. We will create it later.
var socket = io();
// here we add a click event to the button
btnGoRoom.onclick = function () {
if (inputRoomNumber.value === ''){
alert("Please type a room number")
} else {
roomNumber = inputRoomNumber.value; //we take the value from the element
socket.emit('create or join', roomNumber); //we send a message to the server
divSelectRoom.style = "display: none;"; //hide selectRoom div
divConsultingRoom.style = "display: block;"; //show consultingRoom div
}
};
// when server emits created
socket.on('created', function (room) {
//caller gets user media devices with defined constraints
navigator.mediaDevices.getUserMedia(streamConstraints).then(function (stream){
localStream = stream; //sets local stream to a variable
adapter.attachMediaStream(localVideo, stream); //shows stream to user
isCaller = true; //sets current user as caller
}).catch(function (err) {
console.log('An error ocurred when accessing media devices');
});
});
// when server emits joined
socket.on('joined', function (room) {
//callee gets user media devices
navigator.mediaDevices.getUserMedia(streamConstraints).then(function (stream){
localStream = stream; //sets local stream to a variable
adapter.attachMediaStream(localVideo, stream); //shows stream to user
socket.emit('ready',roomNumber); //sends message to server
}).catch(function (err) {
console.log('An error ocurred when accessing media devices');
});
});
// when server emits ready
socket.on('ready', function () {
if(isCaller){
// Creates an RTCPeerConnection Object
rtcPeerConnection = new RTCPeerConnection(iceServers);
// Adds event listeners to the newly created oject
rtcPeerConnection.onicecandidate = onIceCandidate;
rtcPeerConnection.onaddStream = onAddStream;
// Adds the current local stream to the object
rtcPeerConnection.addStream(localStream);
// Prepares an Offer
rtcPeerConnection.createOffer(setLocalAndOffer,function(e){console.log(e)});
}
});
// When servers emits offer
socket.on('offer', function (event){
if(!isCaller){
// Creates an RTCPeerConnection object
rtcPeerConnection = new RTCPeerConnection(iceServers);
// Adds event listeners to the newly created object
rtcPeerConnection.onicecandidate = onIceCandidate;
rtcPeerConnection.onaddstream = onAddStream;
// Adds the current local stream to the object
rtcPeerConnection.addStream(localStream);
// Stores the offer as remote description
rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(event));
// Prepares an Answer
rtcPeerConnection.createAnswer(setLocalAndAnswer, function(e){console.log(e)});
}
});
// When server emits answer
socket.on('answer', function (event){
// Stores it as a remote description
rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(event));
});
// When server emits candidate
socket.on('candidate', function (event) {
// Creates a candidate object
var candidate = new RTCIceCandidate({
sdpMLineIndex: event.label,
candidate: event.candidate
});
// Stores candidate
rtcPeerConneciton.addIceCandidate(candidate);
});
// When a user receives the other user's video and audio stream
function onAddStream(event) {
video.srcObject = stream;
remoteStream = event.stream;
}
// These are the functions referenced before as listeners for the peer connection
// Sends a candidate message to server
function onIceCandidate(event) {
if (event.candidate) {
console.log('sending ice candidate');
socket.emit('candidate',{
type: 'candidate',
lable: event.candidate.sdpMLineIndex,
id: event.candidate.sdpMid,
candidate: event.candidate.candidate,
room: roomNumber
})
}
}
// Stores offer and sends message to server
function setLocalAndOffer(sessionDescription) {
rtcPeerConnection.setLocalDescription(sessionDescription);
socket.emit('offer',{
type: 'offer',
sdp: sessionDescription,
room: roomNumber
});
}
// Stores answer and sends message to server
function setLocalAndAnswer(sessionDescription){
rtcPeerConnection.setLocalDescription(sessionDescription);
socket.emit('answer',{
type: 'answer',
sdp: sessionDescription,
room: roomNumber
});
}
server.js
// Requiring libraries
const express = require('express');
const app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
// Static hosting using express
app.use(express.static('public'));
// Signaling handlers
io.on('connection', function (socket) {
console.log('a user connected');
// When clinet emits create or join
socket.on('create or join', function (room) {
console.log('create or join to room',room);
// Count number of users on room
var myRoom = io.sockets.adapter.rooms[room]||{length:0};
var numClients = myRoom.length;
console.log(room,'has',numClients,'clients');
if(numClients == 0) { // No users on the room
socket.join(room);
socket.emit('created',room);
} else if(numClients == 1) { // One user on the room
socket.join(room);
socket.emit('joined',room);
} else { // Room is full
socket.emit('full',room);
}
});
// Relay only handlers
socket.on('ready',function(room){
socket.broadcast.to(room).emit('ready');
});
socket.on('candidate',function(event){
socket.broadcast.to(event.room).emit('candidate',event);
});
socket.on('offer',function(event){
socket.broadcast.to(event.room).emit('offer',event.sdp);
});
socket.on('answer',function(event){
socket.broadcast.to(event.room).emit('answer',event.sdp);
});
});
// Listener
http.listen(3000,function(){
console.log('listening on *:3000');
});