Public
Watch
1
Fork
You've already forked afogados
0
0

Latest commit

maotovisk
feat(shortcuts): a global shortcut to show or hide the desktop overlay
All checks were successful
frontend / test (push) Successful in 59s
5ef3193 2026-10-31 22:35:03 -03:00 133 commits
2026-09-27 23:30:51 -03:00
2026-10-25 21:09:43 -03:00
2026-10-25 21:09:43 -03:00

afogados.com

Private, group-based live streaming with sub-second latency (WebRTC via Broadcast Box) and Twitch-style chat. Pick a group, go live with OBS, gpu-screen-recorder or VDO.Ninja over WHIP, and watch your friends in a Discord-style multi-view.

  • Specs: docs/spec/. Start with the overview, which has the roadmap.
  • Backend: .NET 10 ASP.NET Core, EF Core + PostgreSQL, Redis. See Backend layout.
  • Frontend: React 19, Vite, TanStack Router + Query, Tailwind v4, i18next (pt-BR / en). See frontend/.

Status

Phase State
0 · Specs done
1 · Foundation: auth (password, Discord, osu!), sessions, identity linking, islands shell, settings done
2 · Groups, invites, roles, bans, /ws realtime + presence done
3 · Streaming: WHIP publish (OBS / gpu-screen-recorder / VDO.Ninja / browser), WHEP player, Go Live panel, liveness reaper done
4 · Chat: markdown, server emojis, GIFs, attachments, one live chat per server, text channels, unread markers, link previews, reactions done
5 · Public share links, group watch page (multiview, theater, unified PIP, per-stream audio, members island, pop-out chat and OBS link) done
6 · Direct messages (1:1, with streaming) · moderation, replies, webhooks DMs done, the rest pending
7 see overview
Mobile · Android V0 steps 1–6 built and running on the emulator, release work in progress (mobile.md)

Development

cp .env.example .env              # fill Discord/osu! app credentials if you have them
(cd frontend && pnpm install)
make deps migrate                 # Postgres + Redis, then the schema (once, and after new migrations)
make dev                          # API :8080, worker :8081 and Vite :5173 together

make dev opens mprocs through bunx (nothing to install beyond bun): a TUI with one pane per process (api, worker, web, and db-logs on demand), where each can be restarted, stopped or zoomed on its own, and q stops everything. Without bun the same three run in parallel in one terminal with [serve]/[worker]/[web] prefixes, and Ctrl+C stops them all. The make targets load .env themselves, from any shell. Individual pieces: make serve, make worker, make web, make import-sqlite DB=data/afogados.db.

Open http://localhost:5173. APP_URL must be the URL the browser uses (the Vite origin in dev), otherwise OAuth redirects and the CSRF Origin check won't match.

The dev-only component gallery lives at http://localhost:5173/_ui.

To test publishing without OBS, use FFmpeg's WHIP muxer (FFmpeg ≥ 8) with the key from the Go Live panel:

ffmpeg -re -f lavfi -i testsrc2=size=1280x720:rate=30 -f lavfi -i sine \
  -c:v libx264 -profile:v baseline -tune zerolatency -g 30 -bf 0 -pix_fmt yuv420p \
  -c:a libopus -ar 48000 -ac 2 -f whip -authorization 'sk_live_…' http://localhost:8080/api/whip

Checks

make check        # .NET tests and pnpm typecheck + tests, in parallel
make build        # .NET publish into bin/afogados and the frontend build, in parallel
make image        # both container images, in parallel

To exercise the PostgreSQL migration and SQLite import test against a local database, set TEST_DATABASE_URL to a PostgreSQL connection string before running dotnet test backend/Afogados.Api.Tests. The test creates and removes its own database.

Backend layout

One project, backend/Afogados.Api, organized by feature:

Folder Holds
Routing/RouteMapper.cs Every route, mapped explicitly to a handler method
Features/{Auth,Groups,Streams,Chat,Realtime,Maintenance} Handlers (HTTP only: binding, rate limits, headers, status codes), services (business rules, EF queries, realtime events) and request/response contracts
Data AppDbContext, entities, IEntityTypeConfigurations, EF migrations, the SQLite importer
Infrastructure Adapters: Broadcast Box and KLIPY typed HttpClients, blob storage, Redis rate limiter and lock, health checks
Common Error envelope, JSON conventions, crypto primitives
Hosting Options bound from the environment, service registration, middleware pipeline, serve/worker/migrate/import-sqlite

After changing an entity, add a migration (the EF tool is pinned in backend/dotnet-tools.json):

make migration name=AddSomething

Container images

Two images, each built from its own folder and published by its own Forgejo workflow (.forgejo/workflows/) when that folder changes. The frontend (Caddy, static files) and the API run on separate origins, afogados.com and api.afogados.com.

make image
docker compose -f deploy/compose.yaml --env-file .env --profile app run --rm backend migrate
docker compose -f deploy/compose.yaml --env-file .env --profile app up -d

The frontend is served at http://localhost:8080 and the API at http://localhost:8081. See deploy.md for the topology, CI, the production compose stack, the environment reference, PostgreSQL backups, and the import-sqlite command for existing data.