loled/static/js/display.js

95 lines
3.0 KiB
JavaScript

async function init(
name="loled-display",
width = window.innerWidth,
height = window.innerHeight,
){
const display = document.getElementById("display")
const video = document.getElementById("display-video")
const nameEl = document.getElementById("display-name")
let peerConnection = null
async function setNewConnection(offer, iceCandidates){
const connection = new RTCPeerConnection({
iceServers: [
{urls: ["stun:stun.nextcloud.com:443"]}
]
})
connection.addEventListener("track", (e) => {
if(e.streams.length > 0){
video.srcObject = e.streams[0]
video.play()
}
})
connection.addEventListener("connectionstatechange", () => {
if(connection.connectionState == "connected"){
nameEl.hidden = true
} else if(["closed", "failed", "disconnected"].indexOf(connection.connectionState)) {
nameEl.hidden = false
}
})
connection.setRemoteDescription(new RTCSessionDescription(offer))
for(const it of iceCandidates){
connection.addIceCandidate(it ? new RTCIceCandidate(it) : undefined)
}
const answr = await connection.createAnswer()
connection.setLocalDescription(answr)
await fetch("/_loled/display/put-answer", {
method: "POST",
body: JSON.stringify(answr),
headers: {"content-type": "application/json"}
})
console.log("New offer received")
if(peerConnection){
peerConnection.close()
}
peerConnection = connection
nameEl.hidden = true
}
display.style.width = width+"px"
display.style.height = height+"px"
display.style.setProperty("--display-width", width+"px")
display.style.setProperty("--display-height", height+"px")
const [registration, registerdName] = await getRegistration(name)
name = registerdName;
nameEl.hidden = false
registration.addEventListener("message", e => {
const message = JSON.parse(e.data)
if(message.type == "offer"){
setNewConnection(message.offer, message.iceCandidates)
}
})
}
async function getRegistration(name){
console.info("Waiting welcome message")
const reg = new EventSource("/_loled/display/register?name="+name)
const registeredName = await new Promise((res, rej) => {
reg.addEventListener("message", e => {
const message = JSON.parse(e.data)
if(message.type != 'welcome'){
rej(new Error("Invalid message received"))
}
res(message.name)
}, {once: true})
})
console.info(`display registerd with name ${registeredName}`)
return [reg, registeredName]
}
const args = new URLSearchParams(location.search);
init(
args.get("name"),
parseInt(args.get("width") || window.innerWidth),
parseInt(args.get("height") || window.innerHeight)
)