update zap; add ice restart
All checks were successful
OTA TV / deploy (push) Successful in 2s

This commit is contained in:
David Westgate 2025-04-25 16:52:28 -07:00
parent f491b21636
commit 5ea740ea24
4 changed files with 31 additions and 26 deletions

View File

@ -46,16 +46,4 @@ const tune = (adapter = 0) => {
}
const getSignal = (adapter = 0) => {
const signalElement = document.getElementById(`signal-${adapter}`);
if (!signalElement) {
return;
}
fetch(`/api/signal?adapter=${adapter}`).then(res =>
res.json()
).then((strength: any) => {
signalElement.innerHTML = `Signal: ${strength.signal} C/N: ${strength.cn}`
})
}
populateChannels(PLAYERS);

View File

@ -7,7 +7,7 @@ const ws1 = new WebSocket(ws1builder);
const config = {
iceServers: [
{
urls: ['stun:dwestgate.us:3478','turn:dwestgate.us:3478?transport=udp'],
urls: ['stun:dwestgate.us:3478', 'turn:dwestgate.us:3478?transport=udp'],
username: 'webrtcuser',
credential: 'webrtccred'
}
@ -21,8 +21,8 @@ interface IData {
cn: number
}
const pc0 = new RTCPeerConnection(config);
const pc1 = new RTCPeerConnection(config);
const pc0 = new RTCPeerConnection(isSecure ? config : {});
const pc1 = new RTCPeerConnection(isSecure ? config : {});
const video0 = document.getElementById('video-0') as HTMLVideoElement;
const video1 = document.getElementById('video-1') as HTMLVideoElement;
const station0 = document.getElementById('station-0') as HTMLHeadElement;
@ -60,12 +60,23 @@ pc0.onicecandidate = ({ candidate }) => {
}
};
const restartIce = (pc, ws) => {
setInterval(async () => {
const offer = await pc.createOffer({ iceRestart: true });
await pc.setLocalDescription(offer);
ws.send(JSON.stringify({ type: 'offer', data: offer }));
}, 50000)
}
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 }));
if (isSecure) {
restartIce(pc0,ws0);
}
}
ws0.onmessage = async (message) => {
@ -114,6 +125,9 @@ ws1.onopen = async () => {
const offer = await pc1.createOffer();
await pc1.setLocalDescription(offer);
ws1.send(JSON.stringify({ type: 'offer', data: offer }));
if (isSecure) {
restartIce(pc1,ws1);
}
}
ws1.onmessage = async (message) => {

View File

@ -4,7 +4,7 @@ import * as ws from 'ws';
// Constants
const WIDTH = 640; // Video width
const HEIGHT = 480; // Video height
const HEIGHT = 360; // Video height
const FRAME_SIZE = WIDTH * HEIGHT * 1.5; // YUV420p frame size (460800 bytes)
export default class TVWebSocket {
@ -88,23 +88,26 @@ export default class TVWebSocket {
// Function to start FFmpeg and capture raw video
startFFmpeg = (): ChildProcessWithoutNullStreams => {
const p = spawn('ffmpeg', [
'-loglevel', 'debug',
// '-loglevel', 'debug',
'-i', this.videoDevice,
'-framerate' ,'59.94',
// Video
'-map', '0:v:0',
'-framerate', '24',
'-r', '30',
'-vf', `scale=${WIDTH}:${HEIGHT}:flags=fast_bilinear`,
'-vcodec', 'rawvideo',
'-preset', 'ultrafast',
'-b:v' ,'1M',
'-pix_fmt', 'yuv420p',
'-f', 'rawvideo',
'-threads', '1',
// '-threads', '1',
//quality
'-fflags', '+discardcorrupt',
'-err_detect', 'ignore_err',
'-analyzeduration', '100M',
'-probesize', '100M',
'-analyzeduration', '500k',
'-probesize', '500k',
'pipe:3',

View File

@ -125,14 +125,14 @@ export default class Zap {
zap.process.stderr.on("data", (data) => {
const output = data.toString();
const output: string = data.toString();
if (/Lock/.test(output)) {
clearTimeout(lockTimer);
const match = output.match(this.regex);
zap.channel = verifiedChannel;
zap.signal = match[1],
zap.cn = match[3]
zap.signal = match?.[1],
zap.cn = match?.[3]
resolve(zap);
}