···11+# dlna-rs
22+33+Single-binary DLNA/UPnP media server in Rust. Auto-discovered by VLC on AppleTV. Embedded Svelte web UI for managing the advertised folders.
44+55+Built on [`librqbit-upnp-serve`](https://github.com/ikatson/rqbit) for SSDP + UPnP ContentDirectory; HTTP streaming with Range requests + DLNA headers handled directly.
66+77+## Build
88+99+Requires Rust (stable) and [bun](https://bun.sh).
1010+1111+```sh
1212+cargo build --release
1313+```
1414+1515+The web UI is built automatically via `build.rs` (runs `bun install` + `bun run build` in `web/`).
1616+1717+## Run
1818+1919+```sh
2020+./target/release/dlna-rs --folder /path/to/media
2121+```
2222+2323+Then on Apple TV: **VLC → Network → Local Network**. The server appears under its friendly name (default: `dlna-rs (hostname)`).
2424+2525+For the admin UI, open `http://localhost:9119/` in a browser.
2626+2727+## Config
2828+2929+`~/.config/dlna-rs/config.styx` (auto-created on first save):
3030+3131+```styx
3232+port 9119
3333+friendly_name "dlna-rs (hostname)"
3434+folders ({path "/Users/m/Movies", recursive true})
3535+```
3636+3737+(Format is whatever [`facet-styx`](https://crates.io/crates/facet-styx) 3.x parses — close to styx but not identical to bearcove's reference.)
3838+3939+CLI flags override:
4040+4141+```
4242+--config <PATH> path to config file
4343+--port <PORT> HTTP port (default 9119)
4444+--friendly-name <NAME> DLNA friendly name
4545+--folder <PATH> append a recursive folder (repeatable)
4646+--folder-flat <PATH> append a non-recursive folder (repeatable)
4747+```
4848+4949+## Endpoints
5050+5151+| Path | Purpose |
5252+|------|---------|
5353+| `/` | Embedded Svelte admin UI |
5454+| `/status` | Plain-text folder + count summary |
5555+| `/api/folders` | GET / POST / DELETE folders |
5656+| `/api/folders/refresh` | POST to recount a folder |
5757+| `/api/browse?path=…` | Server-side directory browser |
5858+| `/api/status` | JSON status |
5959+| `/stream/{id}` | File streaming, Range + DLNA headers |
6060+| `/description.xml` | UPnP device description |
6161+| `/scpd/*`, `/control/*` | UPnP SOAP services |
6262+6363+## VLC AppleTV verification
6464+6565+1. Start: `./target/release/dlna-rs --folder ~/Movies` (or a folder with video files).
6666+2. On macOS: System Settings → Network → Firewall → ensure incoming connections to `dlna-rs` are allowed (or temporarily disable firewall).
6767+3. Apple TV: open VLC → "Network" tab → "Local Network".
6868+4. Expect: a row labelled with the friendly name (`dlna-rs (<your-hostname>)`).
6969+5. Open it; configured folders appear as containers.
7070+6. Open a video file → playback should start.
7171+7272+Troubleshooting:
7373+- `curl http://localhost:9119/description.xml` should return XML.
7474+- `curl http://localhost:9119/status` should list your folders.
7575+- On a Mac on the same network: `dns-sd -B _ssdp._udp` or `pip install ssdpy && ssdpy-discover` to confirm SSDP announcements.
7676+- If VLC doesn't see it: macOS firewall and "Local Network" privacy settings (Settings → Privacy & Security → Local Network) are the usual culprits.
7777+7878+## License
7979+8080+LLM-assisted. MIT.