{"id":51539518,"url":"https://github.com/dfallman/spritz","last_synced_at":"2026-07-09T12:01:37.245Z","repository":{"id":353020093,"uuid":"1205658547","full_name":"dfallman/spritz","owner":"dfallman","description":"Spritz — a nano DLNA media server. Run in any folder and it becomes instantly discoverable on the local network.","archived":false,"fork":false,"pushed_at":"2026-05-26T15:49:15.000Z","size":145,"stargazers_count":9,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-26T17:24:54.889Z","etag":null,"topics":["dlna","dlna-mediaserver","dlna-server","dlna-upnp","media","media-server","music","music-server","rust","self-hosted","server","ssdp","upnp","video","video-server"],"latest_commit_sha":null,"homepage":"https://github.com/dfallman/spritz","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dfallman.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-09T06:56:11.000Z","updated_at":"2026-05-26T15:49:25.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dfallman/spritz","commit_stats":null,"previous_names":["dfallman/spritz"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/dfallman/spritz","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfallman%2Fspritz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfallman%2Fspritz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfallman%2Fspritz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfallman%2Fspritz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dfallman","download_url":"https://codeload.github.com/dfallman/spritz/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfallman%2Fspritz/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35298222,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-09T02:00:07.329Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dlna","dlna-mediaserver","dlna-server","dlna-upnp","media","media-server","music","music-server","rust","self-hosted","server","ssdp","upnp","video","video-server"],"created_at":"2026-07-09T12:01:35.568Z","updated_at":"2026-07-09T12:01:37.193Z","avatar_url":"https://github.com/dfallman.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spritz\n\n[![ci](https://github.com/dfallman/spritz/actions/workflows/ci.yml/badge.svg)](https://github.com/dfallman/spritz/actions/workflows/ci.yml)\n[![release](https://img.shields.io/github/v/release/dfallman/spritz)](https://github.com/dfallman/spritz/releases)\n[![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\n`spritz` is a terminal-based, nano DLNA media server. Run it in a folder, and that folder's video and audio files become available to any TVs, phones, speakers, and other media players on your local network using the DLNA protocol.\n\n\u003cimg width=\"1684\" height=\"1148\" alt=\"spritz-github\" src=\"https://github.com/user-attachments/assets/32228ce0-14c6-4a5a-9222-95802132ec17\" /\u003e\n\n### Quick start\n```\ncd /mnt/nas/movies\nspritz\n```\n\n...or, alternatively, run it from anywhere and specify which path(s) to serve up:\n\n```\nspritz /mnt/nas/movies /mnt/nas/music\n```\n\nDLNA clients — such as modern TVs, Apple TV (via Infuse or VLC), PS5, Xbox, Kodi, tablets, phones, and many more — should see the spritz share appear in their network sources within a few seconds, as long as your client supports DLNA.\n\n\n## Features\n\n- Runs from a single command, `spritz` — zero config, zero state\n- Announces itself via SSDP/UPnP, so clients find it without typing an IP\n- Serves one or more folders (recursively — subdirectories are indexed automatically) from a single instance\n- Presents three browse views at the root: `Videos`, `Music`, and `By folder` (the on-disk structure)\n- Supports video and audio formats (MP4/MKV/AVI/MOV/… and MP3/FLAC/OGG/…)\n- Implements `ContentDirectory:1` and `ConnectionManager:1` for DLNA Browse\n- Exposes an M3U playlist at `/spritz` for VLC, Infuse, and similar players\n- Sends `ssdp:byebye` on Ctrl+C so clients drop it immediately\n\n## Why Spritz?\n\nMost DLNA and media servers (such as Plex, Jellyfin, Emby, MiniDLNA/ReadyMedia, Rygel, Serviio, and others) are meant to be persistent servers: that is, you install a service, point a config file at your media library, often on a NAS or similar, maintain a database, and leave it running.\n\nSpritz is the opposite — you've downloaded a file, you point spritz opportunistically at the folder that file is in, share it for as long as you need, and Ctrl+C when done. As we say in Australia, \"no dramas\": there are no config files, no database, no indexing and reindexing jobs, and no background services.\n\nWhile Spritz is primarily meant as a means for serving up folders ad hoc, that is folders you don't serve every day, it _can_ also be used as a no-nonsense alternative to the heavier, more complex media file servers mentioned above. You can just leave it running on your NAS's `Media` folder too and spritz will do its thing.\n\n**Note**: If you leave it running, note that Spritz parses the file tree at startup, but it doesn't monitor it for changes. Hence, if you add a file to a share, just restart Spritz. Alternatively, if you want to be fancy pants, try using something like [watchexec](https://github.com/watchexec/watchexec): `watchexec -r -- spritz` \n\n## Install\n\n### Pre-built binaries\n\nDownload the latest archive for your platform from the [Releases](https://github.com/dfallman/spritz/releases) page. Builds are provided for:\n\n- Linux x86_64 and aarch64\n- macOS x86_64 and Apple Silicon\n- Windows x86_64\n\nEach archive ships with a `.sha256` checksum.\n\n### From source\n\nTo compile Spritz from source, you'll need Rust. Use [rustup](https://rustup.rs/) for the installation:\n```\ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n```\n\nOnce installed:\n```bash\ngit clone https://github.com/dfallman/spritz\ncd spritz\ncargo install --path cli\n```\n\n## Usage\n\n```\nspritz [FOLDERS]... [OPTIONS]\n\nArguments:\n  [FOLDERS]...  Folders to serve (defaults to the current directory)\n\nOptions:\n  -p, --port \u003cPORT\u003e  Port to listen on [default: 8080]\n  -h, --help         Print help\n```\n\n### Examples\n\n```bash\n# Serve the current directory\nspritz\n\n# Serve a specific folder\nspritz /mnt/nas/movies\n\n# Serve multiple folders\nspritz /mnt/nas/movies /mnt/nas/tv /mnt/nas/kids\n\n# Use a different port\nspritz --port 9000 /media/videos\n```\n\n## Connecting a client\n\n### Smart TVs, game consoles, or media players (DLNA)\nOpen your TV's Media Server or Network source. Spritz should show up within a few seconds. Inside, you'll see three containers — `Videos`, `Music`, and `By folder`. The first two are flat lists of every file by type; `By folder` mirrors your on-disk directory structure so you can navigate Shows → Season 1 → ep1.mkv the way you'd expect.\n\n### VLC\n`Media → Open Network Stream → http://\u003cyour-spritz-server-ip\u003e:8080/spritz`, or browse via `View → Playlist → Local Network → Universal Plug and Play`. VLC only scans at startup and when it receives a NOTIFY packet, so if it doesn't appear, restart VLC once Spritz is already running.\n\n### Infuse (Apple TV / iOS / iPadOS)\n`Add Files → Network Share` and pick Spritz Media Server from the list, or enter the M3U URL manually. Works on tvOS as well — the share browses the three-container layout described above.\n\n### Any M3U-capable player\nPoint it at `http://\u003cyour-spritz-server-ip\u003e:8080/spritz`.\n\n**Note**: `\u003cyour-spritz-server-ip\u003e` is the IP address of the machine you run spritz on, that's the \"server\" here — the \"client\" (see above) is the device from which you play your content. To find your server's IP, use `ipconfig` in the Windows Command Prompt. On macOS, check `System Settings → Network` (or use `ipconfig getifaddr en0` in a terminal). On linux, run `ip addr` or `hostname -I`.\n\n\n## Supported formats\n\n**Video**\n\n| Extension      | MIME type            |\n|----------------|----------------------|\n| `.mp4`, `.m4v` | `video/mp4`          |\n| `.mkv`         | `video/x-matroska`   |\n| `.avi`         | `video/x-msvideo`    |\n| `.mov`         | `video/quicktime`    |\n| `.webm`        | `video/webm`         |\n| `.flv`         | `video/x-flv`        |\n\n**Audio**\n\n| Extension               | MIME type       |\n|-------------------------|-----------------|\n| `.mp3`                  | `audio/mpeg`    |\n| `.m4a`                  | `audio/mp4`     |\n| `.aac`                  | `audio/aac`     |\n| `.flac`                 | `audio/flac`    |\n| `.ogg`, `.oga`, `.opus` | `audio/ogg`     |\n| `.wav`                  | `audio/wav`     |\n| `.wma`                  | `audio/x-ms-wma`|\n| `.aiff`, `.aif`         | `audio/aiff`    |\n\n## Compatibility\n\n| Device                                | Status | Notes                                                              |\n|---------------------------------------|--------|--------------------------------------------------------------------|\n| Samsung (Tizen)                       | Works  | Requires `\u003cdc:date\u003e` on each DIDL item — included                  |\n| LG (webOS)                            | Works  | Shows an \"unknown device\" icon (no icon endpoint yet)              |\n| Sony / Bravia                         | Works  | Strict about `Content-Type: text/xml; charset=\"utf-8\"` — handled   |\n| Apple TV — Infuse (tvOS, iOS, iPadOS) | Works  | Requires the full DIDL treatment for tvOS playback                 |\n| Apple TV — VLC (tvOS, iOS, iPadOS)    | Works  | tvOS VLC sometimes misses SSDP; add the M3U URL manually           |\n\n## Troubleshooting\n\nDLNA is fiddly by nature, especially in combination with certain devices and operating systems (looking at you, Apple TV).\n\nIf your client can't find Spritz, check your firewall rules first (on both the server and client side, but typically the server side): SSDP needs UDP 1900 open, and HTTP needs your serving port (8080 by default).\n\nOn Apple TV, Infuse tends to work better than VLC. If you're using VLC and can't find the share, you can bypass discovery entirely by pasting the M3U URL into VLC: `Media → Open Network Stream → http://192.168.X.X:8080/spritz`. If that plays, the server is fine and the issue is discovery.\n\nRestart VLC once Spritz is already running — VLC only scans at startup and on NOTIFY packets.\n\n### Windows / WSL2\n\nSpritz works under WSL2 with mirrored networking. Add this to your `~/.wslconfig`:\n\n```ini\n[wsl2]\nnetworkingMode=mirrored\n```\n\nThen open the required ports in Windows Firewall (PowerShell, running as Administrator):\n\n```powershell\nNew-NetFirewallRule -DisplayName \"Spritz HTTP\" `\n  -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow\nNew-NetFirewallRule -DisplayName \"Spritz SSDP\" `\n  -Direction Inbound -Protocol UDP -LocalPort 1900 -Action Allow\n```\n\n\u003e **Known issue:** SSDP multicast sometimes requires elevated privileges under WSL2. If devices don't auto-discover the server, try `sudo spritz` or grant the binary `CAP_NET_RAW`. HTTP file serving and the M3U endpoint work either way.\n\n## Architecture\n\nSpritz implements DLNA/UPnP AV directly instead of wrapping an existing library. At a glance:\n\n- **Discovery (SSDP).** Sends `ssdp:alive` on startup, responds to `M-SEARCH`, and sends `ssdp:byebye` on exit.\n- **Device description.** `GET /upnp/description.xml` returns a `MediaServer:1` description advertising ContentDirectory and ConnectionManager.\n- **Browse (SOAP).** `POST /upnp/control/contentdirectory` handles `Browse` and related actions, exposing three root containers: Videos (flat), Music (flat), and By folder (recursive).\n- **File serving.** Each source directory is mounted at `/m/{index}/` and served over HTTP with range support.\n\nSee [ARCHITECTURE.md](ARCHITECTURE.md) for the full protocol walkthrough.\n\n## Note on AI use\n\nThe author of this application has been writing code for over 30 years. Lately, LLM agent-enhanced coding practices have rekindled my sense of awe at what's possible. This project has been built using a range of tools, with Anthropic's Claude Code (using Opus 4.7) among them.\n\nUnlike some who dismiss anything touched by a coding agent as \"slop,\" I don't see it that way. To me, these tools are a way to move much faster, explore many more ideas, and test those ideas and implementations more rigorously than I ever could on my own.\n\n## Contributing\n\nIssues and pull requests welcome. For bugs, please include your client device/OS, firewall setup, and the output of `spritz` when the client tries to connect.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdfallman%2Fspritz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdfallman%2Fspritz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdfallman%2Fspritz/lists"}