frontend add 2nd player, style touch ups

This commit is contained in:
david 2025-04-01 17:48:29 -07:00
parent 6f1faf2753
commit b98717201e
4 changed files with 74 additions and 40 deletions

View File

@ -33,6 +33,20 @@ body {
width: 20em; width: 20em;
border-radius: 50%; border-radius: 50%;
} }
.content{
display: flex;
flex-direction: column;
gap: 1em;
.player{
.channel-group{
display: flex;
align-self: center;
justify-self: center;
}
}
}
} }

View File

@ -9,12 +9,23 @@
</head> </head>
<body> <body>
<h1>Video streams</h1> <header></header>
<h2>WebRTC</h2> <main>
<div class="player"> <h1>Video streams</h1>
<video id="video" autoplay playsinline controls></video> <h2>WebRTC</h2>
<div id="channel-group" class="channel-group" ></div> <div class="content">
<button onClick="tune()">Tune</button> <div class="player">
<video id="video0" autoplay playsinline controls></video>
<div id="channel-container-0" class="channel-group"></div>
<button onClick="tune(0)">Tune</button>
</div>
<div class="player">
<video id="video1" autoplay playsinline controls></video>
<div id="channel-container-1" class="channel-group"></div>
<button onClick="tune(1)">Tune</button>
</div>
</main>
</div> </div>
<script src="js/video.js"></script> <script src="js/video.js"></script>

View File

@ -1,46 +1,53 @@
const getChannels = () => { const PLAYERS = 2;
const populateChannels = (players:number) => {
fetch('/api/list').then(async (res) => { fetch('/api/list').then(async (res) => {
const channelNames: string[] = await res.json() const channelNames: string[] = await res.json()
const radioGroup = document.getElementById('channel-group');
if (!radioGroup) {
throw new Error("Radio group not found") for(let i = 0; i < players; ++i){
const radioGroup = document.getElementById(`channel-container-${i}`);
if (!radioGroup) {
throw new Error("Radio group not found")
}
radioGroup.innerHTML = ''
channelNames.forEach((channelName,_) => {
const id = `radio-${channelName}`;
const input = document.createElement('input');
input.type = "radio"
input.name = `channel-radio-${i}`;
input.value = channelName;
input.id = id
const lbl = document.createElement("label");
lbl.htmlFor = id;
lbl.textContent = channelName;
// Wrap in a div or line
const wrapper = document.createElement("div");
wrapper.appendChild(input);
wrapper.appendChild(lbl);
radioGroup.appendChild(wrapper)
})
} }
radioGroup.innerHTML = ''
channelNames.forEach((channelName,index) => {
const id = `radio-${index}`;
const input = document.createElement('input');
input.type = "radio"
input.name = 'grp';
input.value = channelName;
input.id = id
const lbl = document.createElement("label");
lbl.htmlFor = id;
lbl.textContent = channelName;
// Wrap in a div or line
const wrapper = document.createElement("div");
wrapper.appendChild(input);
wrapper.appendChild(lbl);
radioGroup.appendChild(wrapper)
})
}).catch(err => { }).catch(err => {
console.log("nope ",err) console.log("nope ",err)
}) })
} }
const tune = () =>{ const tune = (adapter=0) =>{
const choice = document.querySelector<HTMLInputElement>('input[name="grp"]:checked') const choice = document.querySelector<HTMLInputElement>(`input[name="channel-radio-${adapter}"]:checked`)
const channel = choice?.value; const channel = choice?.value;
if(channel){ if(channel){
fetch(`/api/tune/${channel}`, {method:'PUT'}) fetch(`/api/tune/${channel}?adapter=${adapter}`, {method:'PUT'})
} }
} }
getChannels(); populateChannels(PLAYERS);

View File

@ -1,7 +1,8 @@
const host = window.location.hostname const host = window.location.hostname
const ws = new WebSocket(`ws://${host}:3001`); const ws = new WebSocket(`ws://${host}:3001`);
const pc = new RTCPeerConnection({ iceServers: [] }); const pc = new RTCPeerConnection({ iceServers: [] });
const video = document.getElementById('video') as HTMLVideoElement; const video0 = document.getElementById('video0') as HTMLVideoElement;
const video1 = document.getElementById('video1') as HTMLVideoElement;
pc.onconnectionstatechange = (event) => { pc.onconnectionstatechange = (event) => {
console.log("onconnectionstatechange ", event) console.log("onconnectionstatechange ", event)
@ -13,7 +14,8 @@ pc.ondatachannel = (event) => {
pc.ontrack = (event) => { pc.ontrack = (event) => {
console.log("Received track event", event.streams); console.log("Received track event", event.streams);
video.srcObject = event.streams[0]; video0.srcObject = event.streams[0];
video1.srcObject = event.streams[0];
}; };
pc.onicecandidate = ({ candidate }) => { pc.onicecandidate = ({ candidate }) => {