iArt.ai
AI motion graphics software — the After Effects alternative anyone can use. Create animations and explainer videos from a text prompt in minutes.
A self-hosted music service for people that enjoy listening to music and not platforms.
MediaC# · SvelteGitHub @t1stmOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
musicrain is a self-hosted music player for the web. A SvelteKit app built to static files, it plays from a local file library, YouTube, Spotify and Deezer, keeps a queue, holds playlists and accounts, and can put several listeners in a room on the same track at the same position — inside about 50 ms of each other. The same build runs as an ordinary site, as an installable PWA, or embedded in a Discord voice channel as an Activity.
Currently running at.Read the full README ↗musicrain is a self-hosted music player for the web. A SvelteKit app built to static files, it plays from a local file library, YouTube, Spotify and Deezer, keeps a queue, holds playlists and accounts, and can put several listeners in a room on the same track at the same position — inside about 50 ms of each other. The same build runs as an ordinary site, as an installable PWA, or embedded in a Discord voice channel as an Activity.
Currently running at https://music.gergov.bg/.
Behind it is Gaida, the self-hosted backend in this repository: one public API in front of several interchangeable "platform pods", one per music service. Every pod speaks the same small HTTP contract, so adding a service means adding a container, not touching the API. Two of the four pods are Python; the rest is .NET 10. The endpoint contract is in Backend/API.md, the room protocol in Backend/MULTIPLAYER_API.md, and the whole stack comes up from Backend/compose.yaml.
Prerequisites: Node.js 20 or newer for musicrain, and Docker with Compose v2 for the backend. Building the .NET services outside a container also wants the .NET 10 SDK.
Run musicrain:
cd Frontend
npm install
npm run dev
Vite serves on http://localhost:5173, bound to every interface so a phone on the same network can open it. Frontend/README.md has the full script list, the Discord Activity setup and the frontend's own structure.
[!IMPORTANT]
Frontend/.envships placeholders, so point musicrain at your own API before it can play anything:echo 'PUBLIC_API_URL=http://localhost:5340/Audio' >> Frontend/.env.local— the backend on compose's defaults. The value is inlined at build time, so changing it needs a rebuild rather than a restart.
Then the backend:
cd Backend
docker compose up --build
The compose defaults are what a fresh checkout runs on: no secrets, no accounts, every volume under Backend/data/, and the API on http://localhost:5340. Put music in Backend/data/music — or point MUSIC_LIBRARY_PATH at where it already lives — and the library pod picks it up on its next start. Spotify and Deezer search work with no credentials; Deezer audio is the one thing that needs a cookie.
Host-specific values and secrets live in Backend/.env, which compose reads on its own and git ignores. Backend/README.md lists them, and Backend/nginx.example.conf shows the path routing that goes in front of the stack.
timeupdate reports using AudioContext.currentTime, then subtracts baseLatency and outputLatency to get the position actually reaching the ear..svelte.ts files outside components, which is what lets the sync clock and the queue be unit-tested with no DOM@theme tokensIAsyncEnumerable<T> responses as the streaming primitive, and Serilog throughout.
├── Frontend/
│ ├── src/
│ │ ├── components/
│ │ ├── lib/
│ │ ├── requests/
│ │ ├── routes/
│ │ └── state/
│ ├── static/
│ └── tools/
└── Backend/
├── data/
│ ├── deezer-audio/
│ ├── music/
│ ├── youtube-audio/
│ └── youtube-cache/
├── Gaida Library/
│ ├── Gaida.Admin/
│ ├── Gaida.CLI/
│ ├── Gaida.Core/
│ └── Gaida.Sqlite/
├── Platforms/
│ ├── Gaida.Platforms.MusicDatabase/
│ ├── Gaida.Platforms.YouTube/
│ ├── Gaida.Pods.Deezer/
│ ├── Gaida.Pods.MusicDatabase/
│ ├── Gaida.Pods.Spotify/
│ └── Gaida.Pods.YouTube/
├── scripts/
├── Services/
│ ├── Dom/
│ ├── Dunav/
│ ├── Gaida.API/
│ ├── Gaida.Bot/
│ ├── Moliv/
│ ├── Oko/
│ ├── Selo/
│ ├── Snimka/
│ └── Stih/
└── Tests/
├── Gaida.Tests/
└── Pods.Tests/
Frontend is musicrain itself, with its own README covering the scripts, the Discord Activity setup and the per-directory layout. Frontend/src/state holds the rune-based state classes — audio, queue, room session, account, playlists. Frontend/src/lib is the logic with no UI attached: the two clocks, the back stack, the JSON stream scanner, the Discord URL rewriting. Frontend/static is served at the site root: favicons, the PWA icons and the web app manifest.
Backend/Platforms holds the pods. A Gaida.Platforms.* project is library code — search providers and content getters against one service. A Gaida.Pods.* project is the container that wraps one of them in HTTP, or, for Spotify and Deezer, a standalone Python app. Each has its own README.
Backend/Services holds everything that is not a pod, named in Bulgarian: Gaida.API is the public front door and the transcoder, Dunav the fan-out download cache, Selo the room server, Dom accounts and playlists, Moliv the listening history, Stih the lyrics, Snimka every track image, Oko the admin panel, and Gaida.Bot a Discord bot on the same library.
Backend/data is where the compose defaults mount their volumes — the music library and the YouTube and Deezer audio caches. All of it is gitignored, and none of it is served by nginx directly. Album art lives in Snimka's own volume and reaches the browser through /Audio/Cover/Get.
Everything in this repository is released into the public domain under the Unlicense, with one exception: Backend/Platforms/Gaida.Pods.Deezer is under GPL-3.0-only, because its download and decrypt logic is vendored from streamrip. That pod is a container of its own and talks to the rest over HTTP, so nothing else here inherits the copyleft.
micro variant as @media (max-height: 320px), which covers Discord picture-in-picture, a popped-out window and a phone on its side in one rule, with no SDK layout-mode event.StreamSpreader lets an in-progress download serve every client that asked for it, using FileShare.ReadWrite | FileShare.Delete so the file can be evicted while readers still hold it — the bytes live until the last descriptor closes.ConcurrentDictionary<string, Lazy<Task<…>>>, so a thousand clients racing for a cold track cause exactly one encode.sqlite3wvunpack for hybrid tracks FFmpeg decodes lossyVoice extension takes Opus straight from the API without decoding it