#javascript #node.js #sockets #webrtc #streaming
#javascript #node.js #сокеты #webrtc #потоковая передача
Вопрос:
Я попытался подключить свое видео (без веб-камеры) для удаленной синхронизации с другим видео. Но я не знаю, где я ошибаюсь. Я сделал это с учетом того, что они собирались подключиться к одной комнате. Один выполняет поток (LocalVideo), а другой видит, что делает другой (удаленный). Что-то очень похожее на это: https://webrtc.github.io/samples/src/content/capture/video-pc /. Но я до сих пор не дал ответа на проблему, ПОЖАЛУЙСТА, если кто-то, кто знает о node.js и WebRTC может спасти меня!
main.js:
let divSelectRoom = document.getElementById("selectRoom")
let divConsultingRoom = document.getElementById("consultingRoom")
let divConsultingRoom2 = document.getElementById("consultingRoom2")
let inputRoomNumber = document.getElementById("roomNumber")
let btnGoRoom = document.getElementById("goRoom")
let localVideo = document.getElementById("localVideo")
let remoteVideo = document.getElementById("remoteVideo")
let locallabel = document.getElementById("locallabel")
let visitlabel = document.getElementById("visitlabel")
let roomNumber, localStream, remoteStream, rtcPeerConnection, isCaller
let stream;
const iceServers = {
'iceServer': [
{ 'urls': 'stun:stun.services.mozilla.com' },
{ 'urls': 'stun:stun.l.google.com:19302' }
]
}
const streamConstraints = {
audio: 1,
video: 1
}
let startTime;
const socket = io();
btnGoRoom.onclick = () => {
if (inputRoomNumber.value == '') {
alert("please type a room name")
} else {
roomNumber = inputRoomNumber.value
socket.emit('create or join', roomNumber)
divSelectRoom.style = "display: none"
}
}
function maybeCreateStream() {
if (stream) {
return;
}
if (localVideo.captureStream) {
stream = localVideo.captureStream();
console.log('Captured stream from localVideo with captureStream',
stream);
} else if (localVideo.mozCaptureStream) {
stream = localVideo.mozCaptureStream();
console.log('Captured stream from localVideo with mozCaptureStream()',
stream);
} else {
console.log('captureStream() not supported');
}
localStream = stream
}
localVideo.play();
socket.on('created', room => {
divConsultingRoom.style = "display: block"
// Video tag capture must be set up after video tracks are enumerated.
localVideo.oncanplay = maybeCreateStream;
if (localVideo.readyState >= 3) { // HAVE_FUTURE_DATA
// Video is already ready to play, call maybeCreateStream in case oncanplay
// fired before we registered the event handler.
maybeCreateStream();
}
isCaller = true
})
socket.on('joined', room => {
divConsultingRoom2.style = "display: block"
remoteVideo.srcObject = localStream;
isCaller = false
socket.emit('ready', roomNumber)
})
socket.on('ready', () => {
console.log('enter ready')
const videoTracks = stream.getVideoTracks();
const audioTracks = stream.getAudioTracks();
if (videoTracks.length > 0) {
console.log(`Using video device: ${videoTracks[0].label}`);
}
if (audioTracks.length > 0) {
console.log(`Using audio device: ${audioTracks[0].label}`);
}
if (isCaller) {
rtcPeerConnection = new RTCPeerConnection(iceServers)
rtcPeerConnection.onicecandidate = onIceCandidate
rtcPeerConnection.ontrack = onAddStream
rtcPeerConnection.addTrack(localStream.getTracks()[0], localStream)
rtcPeerConnection.addTrack(localStream.getTracks()[1], localStream)
rtcPeerConnection.createOffer()
.then(sessionDescription => {
console.log('sending offer', sessionDescription)
rtcPeerConnection.setLocalDescription(sessionDescription)
socket.emit('offer', {
type: 'offer',
sdp: sessionDescription,
room: roomNumber
})
}).catch(err => {
console.log(err)
})
}
})
socket.on('offer', (event) => {
console.log('enter offer', isCaller)
if (!isCaller) {
rtcPeerConnection = new RTCPeerConnection(iceServers)
rtcPeerConnection.onicecandidate = onIceCandidate
rtcPeerConnection.ontrack = onAddStream
//rtcPeerConnection.addTrack(localStream.getTracks()[0], localStream)
//rtcPeerConnection.addTrack(localStream.getTracks()[1], localStream)
console.log('received offer', event)
rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(event))
rtcPeerConnection.createAnswer().then(sessionDescription => {
console.log('sending answer', sessionDescription)
socket.emit('answer', {
type: 'answer',
sdp: sessionDescription,
room: roomNumber
})
}).catch(err => {
console.log(err)
})
}
})
socket.on('answer', event => {
console.log('received answer', event)
rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(event))
})
socket.on('candidate', event => {
const candidate = new RTCIceCandidate({
sdpMLineIndex: event.label,
candidate: event.candidate
})
console.log('received candidate', candidate)
rtcPeerConnection.addIceCandidate(candidate)
})
function onAddStream(event) {
console.log('Stream It')
remoteVideo.srcObject = event.streams[0];
remoteStream = event.streams[0]
console.log('visit received remote stream', event.streams[0]);
}
function onIceCandidate(event) {
if (event.candidate) {
console.log('sending ice candidate', event.candidate)
socket.emit('candidate', {
type: 'candidate',
label: event.candidate.sdpMLineIndex,
id: event.candidate.sdpMid,
candidate: event.candidate.candidate,
room: roomNumber
})
}
}
app.js:
const { Socket } = require('dgram')
const express = require('express')
const app = express()
let http = require('http').Server(app)
const port = process.env.PORT || 3000
let io = require('socket.io')(http)
app.use(express.static('public'))
http.listen(port, () => {
console.log('listening on', port)
})
io.on('connection', socket => {
console.log('a user connected')
socket.on('create or join', room => {
console.log('create or join to room', room)
const myRoom = io.sockets.adapter.rooms[room] || {length: 0}
const numClients = myRoom.length
console.log(room, 'has',numClients,'clients')
if(numClients == 0){
socket.join(room)
socket.emit('created', room)
}else if (numClients == 1){
socket.join(room)
socket.emit('joined', room)
}else{
socket.emit('full', room)
}
})
socket.on('ready', room => {
socket.broadcast.to(room).emit('ready')
})
socket.on('candidate', event => {
socket.broadcast.to(event.room).emit('candidate', event)
})
socket.on('offer', event => {
socket.broadcast.to(event.room).emit('offer', event.sdp)
})
socket.on('answer', event => {
socket.broadcast.to(event.room).emit('answer', event.sdp)
})
})
index.html:
<!DOCTYPE html>
<head>
<title>WebRTC Training</title>
</head>
<body>
<h1>WebRTC TRAINING</h1>
<div id="selectRoom">
<label>Type room name</label>
<input id="roomNumber" type="text"/>
<button id="goRoom">Go</button>
</div>
<div id="consultingRoom" style="display: none;">
<video id="localVideo" playsinline controls loop muted>
<source src="videos/dudu.webm" type="video/webm"/>
<source src="videos/dudu.mp4" type="video/mp4"/>
<p>This browser does not support the video element.</p>
</video>
<label id="locallabel">local</label>
</div>
<div id="consultingRoom2" style="display: none;">
<video id="remoteVideo" playsinline autoplay></video>
<label id="visitlabel">visit</label>
</div>
<script src="/socket.io/socket.io.js"></script>
<script src="main.js"></script>
</body>
Это картинка, чтобы вы могли лучше ее понять.