ota-tv-web/src/static/js/video.ts
2025-04-04 14:28:13 -07:00

97 lines
2.7 KiB
TypeScript

const isSecure = window.location.protocol === 'https:';
const host = window.location.hostname;
const ws0builder = isSecure ? `wss://${host}/ws0` : `ws://${host}:3001`;
const ws1builder = isSecure ? `wss://${host}/ws1` : `ws://${host}:3002`;
const ws0 = new WebSocket(ws0builder);
const ws1 = new WebSocket(ws1builder);
const config = {
iceServers: [
{
urls: ['stun:dwestgate.us:3478','turn:dwestgate.us:3478?transport=udp'],
username: 'webrtcuser',
credential: 'webrtccred'
}
]
};
const pc0 = new RTCPeerConnection(config);
const pc1 = new RTCPeerConnection(config);
const video0 = document.getElementById('video0') as HTMLVideoElement;
const video1 = document.getElementById('video1') as HTMLVideoElement;
// 0
pc0.ontrack = (event) => {
console.log("Received track event", event.streams);
video0.srcObject = event.streams[0];
};
pc0.onicecandidate = ({ candidate }) => {
if (candidate) {
ws0.send(JSON.stringify({ type: 'ice-candidate', data: candidate }));
}
};
ws0.onopen = async () => {
pc0.addTransceiver('video', { direction: 'recvonly' });
pc0.addTransceiver('audio', { direction: 'recvonly' })
const offer = await pc0.createOffer();
await pc0.setLocalDescription(offer);
ws0.send(JSON.stringify({ type: 'offer', data: offer }));
}
ws0.onmessage = async (message) => {
const msg = JSON.parse(message.data);
if (msg.type === 'answer') {
await pc0.setRemoteDescription(msg.data);
}
else if (msg.type === 'ice-candidate') {
await pc0.addIceCandidate(msg.data);
}
};
// 1
pc1.ontrack = (event) => {
console.log("Received track event", event.streams);
video1.srcObject = event.streams[0];
};
pc1.onicecandidate = ({ candidate }) => {
if (candidate) {
ws1.send(JSON.stringify({ type: 'ice-candidate', data: candidate }));
}
};
ws1.onopen = async () => {
pc1.addTransceiver('video', { direction: 'recvonly' });
pc1.addTransceiver('audio', { direction: 'recvonly' })
const offer = await pc1.createOffer();
await pc1.setLocalDescription(offer);
ws1.send(JSON.stringify({ type: 'offer', data: offer }));
}
ws1.onmessage = async (message) => {
const msg = JSON.parse(message.data);
if (msg.type === 'answer') {
await pc1.setRemoteDescription(msg.data);
}
else if (msg.type === 'ice-candidate') {
await pc1.addIceCandidate(msg.data);
}
};
// TODO: Not yet working
// const dc0 = pc0.createDataChannel("keepalive");
// dc0.onopen = () =>{
// console.log("Data channel 0 open");
// setInterval(()=>{
// dc0.send("ping");
// },10000)
// }
// const dc1 = pc1.createDataChannel("keepalive");
// dc1.onopen = () =>{
// console.log("Data channel 1 open");
// setInterval(()=>{
// dc1.send("ping");
// },10000)
// }