95 lines
3.0 KiB
JavaScript
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")),
|
||
|
parseInt(args.get("height"))
|
||
|
)
|