Camera rounds: several people's cameras at once in the voice tiles

- A viewer holds one screen and any number of cameras; cameras play in the
  tiles (own one mirrored), a click enlarges one
- "Watch all cameras" joins the round: cameras in the channel are watched as
  they come on. Turning your own camera on joins it too
- Sound, statistics and stop work per stream
- Relay quotas and port range raised: a round uses a route per pair of people

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-02 00:14:22 +02:00
co-authored by Claude Opus 5.5
parent 817f822771
commit 1e4bda4e74
13 changed files with 252 additions and 115 deletions
+3 -2
View File
@@ -6,7 +6,8 @@
// "Stats for nerds" over the stream: codecs, picture, bitrate and the network path, read
// from the WebRTC connection once a second. own: our stream (one block per viewer).
let { own, onclose }: { own: boolean; onclose: () => void } = $props();
// session: whose stream, when it is one we watch
let { own, session: watched = null, onclose }: { own: boolean; session?: number | null; onclose: () => void } = $props();
type Row = [string, string];
let blocks = $state<{ title: string; rows: Row[] }[]>([]);
@@ -83,7 +84,7 @@
}
async function read() {
const reports = await share.reports(own);
const reports = await share.reports(own, watched ?? undefined);
blocks = reports.map(r => {
const user = r.viewer != null ? session.user(r.viewer) : undefined;
return { title: r.viewer == null ? '' : `To ${user ? store.displayName(user) : `#${r.viewer}`}`, rows: describe(r.report, String(r.viewer)) };