104 lines
2.7 KiB
JavaScript
104 lines
2.7 KiB
JavaScript
const socket = io();
|
|
const peerConnections = {};
|
|
const startBtn = document.getElementById('startBtn');
|
|
const localVideo = document.getElementById('localVideo');
|
|
const statusDot = document.getElementById('statusDot');
|
|
const statusText = document.getElementById('statusText');
|
|
|
|
let activeStream;
|
|
|
|
const config = {
|
|
iceServers: [
|
|
{ urls: "stun:localhost:3478" },
|
|
{
|
|
urls: "turn:localhost:3478",
|
|
username: "myuser",
|
|
credential: "mypassword"
|
|
}
|
|
]
|
|
};
|
|
|
|
socket.on('viewer', id => {
|
|
if (!activeStream) return;
|
|
|
|
const peerConnection = new RTCPeerConnection(config);
|
|
peerConnections[id] = peerConnection;
|
|
|
|
activeStream.getTracks().forEach(track => {
|
|
peerConnection.addTrack(track, activeStream);
|
|
});
|
|
|
|
peerConnection.onicecandidate = event => {
|
|
if (event.candidate) {
|
|
socket.emit('candidate', id, event.candidate);
|
|
}
|
|
};
|
|
|
|
peerConnection
|
|
.createOffer()
|
|
.then(sdp => peerConnection.setLocalDescription(sdp))
|
|
.then(() => {
|
|
socket.emit('offer', id, peerConnection.localDescription);
|
|
});
|
|
});
|
|
|
|
socket.on('answer', (id, description) => {
|
|
if (peerConnections[id]) {
|
|
peerConnections[id].setRemoteDescription(description);
|
|
}
|
|
});
|
|
|
|
socket.on('candidate', (id, candidate) => {
|
|
if (peerConnections[id]) {
|
|
peerConnections[id].addIceCandidate(new RTCIceCandidate(candidate));
|
|
}
|
|
});
|
|
|
|
socket.on('disconnectPeer', id => {
|
|
if (peerConnections[id]) {
|
|
peerConnections[id].close();
|
|
delete peerConnections[id];
|
|
}
|
|
});
|
|
|
|
startBtn.addEventListener('click', async () => {
|
|
try {
|
|
const stream = await navigator.mediaDevices.getDisplayMedia({
|
|
video: {
|
|
width: { ideal: 1920 },
|
|
height: { ideal: 1080 },
|
|
frameRate: { ideal: 60 }
|
|
},
|
|
audio: false
|
|
});
|
|
|
|
activeStream = stream;
|
|
localVideo.srcObject = stream;
|
|
localVideo.classList.add('active');
|
|
|
|
startBtn.style.display = 'none';
|
|
statusDot.classList.add('active');
|
|
statusText.innerText = 'Sharing Screen (1080p60)';
|
|
|
|
socket.emit('broadcaster');
|
|
|
|
stream.getVideoTracks()[0].onended = () => {
|
|
stopSharing();
|
|
};
|
|
|
|
} catch (err) {
|
|
console.error("Error accessing display media.", err);
|
|
statusText.innerText = 'Failed to access screen';
|
|
statusDot.style.backgroundColor = 'var(--error-color)';
|
|
}
|
|
});
|
|
|
|
function stopSharing() {
|
|
startBtn.style.display = 'inline-block';
|
|
localVideo.classList.remove('active');
|
|
statusDot.classList.remove('active');
|
|
statusText.innerText = 'Not Sharing';
|
|
activeStream = null;
|
|
socket.emit('disconnect');
|
|
}
|