Every knob a radio station needs.
LetsStreamIt is a self-hosted control panel for internet radio: the streaming engines, the automation, an editable DJ website with listener uploads, the public pages and the operator tooling — all in one app you run on your own server. It can even name the on-air track by fingerprinting the audio itself. And when the feature you want is not here yet, build it as a plugin. Here is everything it does.
Broadcast engine
Real streaming engines, started and supervised from one console — no shell scripts, no cron.
Three engines, one dashboard
Icecast2, Shoutcast DNAS and a Liquidsoap AutoDJ run side by side. Start, stop and health-check every engine per station, with source credentials and port allocation handled for you.
AutoDJ that heals itself
Liquidsoap rotates your library when nobody is live. The reconciler checks every 60s and restarts crashed engines with backoff, so the stream comes back on its own.
Take over live
Point BUTT, Mixxx or Winamp at the station's port with the source password and go live instantly — AutoDJ steps aside for your live feed.
HTTPS stream proxy
Listeners play through /api/stations/<id>/stream — Range-capable, CORS-open and buffered just right, so you never have to open stream ports to the world.
Engines
What actually sends the audio — real streaming servers and a programmable AutoDJ, supervised and portable.
Icecast2 & Shoutcast DNAS
Real streaming servers with their own ports, source passwords and mount points, configured per station and supervised by the panel's reconciler — not a wrapper around someone else's cloud. Opening IP:port in a browser shows the engine's own public status page with now-playing, listeners, peak and bitrate.
Liquidsoap AutoDJ
Crossfades, loudness normalisation, weighted dayparted rotation rules, no-repeat windows, sponsor spots, voice tracks and a live harbor — all in a generated script you can actually read.
Bitrate ladder
Serve lower-bitrate companion mounts (64k, 96k…) from the same source so listeners on slow mobile connections still tune in without buffering.
Health checks & self-healing
A 60-second poller watches every engine, logs downtime and recoveries, restarts whatever crashed, and fires your webhooks when a station goes live or offline.
16 optional integrations, none required
Managed Postgres, external uptime monitoring with a public /status page, a scheduler heartbeat, CDN video replays (Mux), instant search (Meilisearch), a support inbox (Chatwoot), product analytics, newsletters, AI voice providers, a listener call-in line, merch, artist news, offsite archiving, abuse protection, SoundCloud & Mixcloud players with publishing, and song recognition (SoundHound, Shazam or AudD). Each one turns on with its keys and otherwise falls back to built-in behaviour — Admin → Integrations shows what is live and runs the maintenance actions.
Webhooks you can trust
Point a station at Discord, Telegram or any URL and choose which events it sends. Generic payloads can be HMAC-signed, a failed delivery is retried automatically, and the delivery log shows the status, latency and answer of every attempt — with a one-click test so you know it works before you rely on it.
Your brand, your pages
Every station ships with a public presence that looks like it was designed for it.
Public station landing pages
Each station gets /s/<slug> with a profile image, custom background, accent color, tagline, live player, on-air badge, now playing and tune-in links — all editable from the station page.
Tune-in links & public API
Every station publishes one set of tune-in links — the HTTPS stream, the direct engine port, the TLS listener, a .m3u playlist for VLC and iTunes, and an iframe embed. They appear on the station page, the directory, your dashboard and Admin, and as JSON at /api/stations/<id-or-slug>/tune-in; /api/tune-in lists every station a caller may see, or hands the whole lineup over as a single playlist.
Embeddable player
One iframe line drops a compact, auto-playing-capable player onto any website, blog or forum with your station's colors.
Last.fm artist info
The on-air song resolves to the artist's bio, photo, genre tags, album art and popular tracks — shown on the landing page and the dashboard (bring your own free API key).
Song recognition — SoundHound, Shazam or AudD
The panel samples about twelve seconds of a station's own stream server-side and fingerprints it, so a stream with no metadata — or wrong metadata — still names the track. Configure any one provider: SoundHound (your key plus the licensed endpoint), Shazam through a RapidAPI key, or AudD. The “Identify this track” card sits on every station page and in the dashboard, returns album art, genre, release date, label and the Apple Music / Spotify / provider links it has, and shows the engine's own title beside it for comparison. Results are cached for a minute per station and no provider is called more than once every 15 seconds, so a page full of listeners costs one lookup. Nothing is rewritten: your engine's metadata stays untouched.
Theme engine
Eight built-in palettes — Ember Dark and Ember Light plus Midnight, Carbon, Forest, Sunset, Paper and High Contrast — any accent color, and a corner-radius scale. The ember ramp, gradient partner and on-air dot are derived from your accent and auto-corrected until they stay readable, each visitor keeps their own choice per browser, and a theme exports as plain CSS.
Per-station themes
Every station picks its own preset for its public pages — landing page, embed player, now playing, episodes and history — with its own accent and corner radius. Station default keeps the classic dark hero with your accent color, so nothing repaints until you choose, and a light preset stays light on every page instead of leaking the panel's palette.
Station directory
Tick one box and a station joins the panel's own public directory at /stations — searchable by name, genre and tagline, on-air stations first, with live listener counts and genre tags. Listings are strictly opt-in, and the public crew line-up shows the DJs you choose to credit.
The DJ website
Every station can have a website of its own — written in the dashboard, served from your server, and kept current on its own.
An editable artist site
Each station gets /s/<slug>/site: a headline, intro and bio, genre tags, up to twelve links, a booking email and as many as eight custom pages — written in the dashboard editor and published with one switch. The nav is derived from the pages you keep, the copy is capped and drawn as text, and unpublishing hides the whole site without deleting the writing.
Schedule & episodes, automatic
The site reads the station's own data: the weekly schedule (with what is on air now, what is up next, and a subscribable .ics feed) and the newest finished episodes, playable and linked to the full list. Nothing to copy across and nothing to keep in sync — either section turns off with a checkbox.
Tune-in links & a built-in player
The site's Listen section plays the station directly — an audio player for radio, a video player for live video — and lists every tune-in link with a copy button: the HTTPS stream, the direct engine port, the TLS listener, a .m3u playlist for VLC and iTunes, and the iframe embed.
Mixes from your listeners
A downloads section where fans upload their own sets. An upload must be signed in, pass an extension and magic-byte check (the same one the media library uses), stay under 128 MB, and fit inside three uploads per listener per station and sixty per station — all counted against the station's media budget. The owner moderates from the dashboard (hide, restore, delete), and a hidden mix is served to no one but the owner.
Made safe for public pages
Everything the public site renders is treated as untrusted: links must parse as http(s), page slugs are URL-safe and may not shadow a route, text is capped and drawn as text. There is no HTML-injection path from a listener, a link or a page title.
Library & delivery
Get music in, keep it organized, and know exactly who is listening.
Disk-synced media library
Upload, search, rename, download and delete tracks from the browser. Files live on disk next to each station, so AutoDJ and the library can never drift apart.
Built-in FTP server
No external daemon: connect with your panel email and password over explicit FTPS, drop files into a station folder, and they start rotating. Off by default, bound to loopback until you open it, with per-address login throttling and configurable passive ports for NAT.
Playlists for shows
Group tracks into playlists per station so your shows play in order — or let the library rotate randomly.
Listener stats & charts
A 60s scheduler records listeners and peaks into PostgreSQL; the station page renders a live 24-hour chart of who showed up.
Live audience polls
Owners open a question with two to six choices from Fans. Public station and DJ website pages show results refreshed every five seconds. Each signed-in account gets one immutable vote; closing a poll prevents further votes and keeps its results visible. One open poll per station.
Accessible radio listening
Native browser playback and volume controls, visible keyboard focus, reduced-motion support, explicit live/replay labels, and playback error announcements. Icecast stations with configured lower-bitrate mounts offer a low-bandwidth selector. These are practical improvements, not a claim of certified accessibility compliance.
Listener hype & public charts
Listeners tap ♡ on the track that is on air, and /s/<slug>/charts sets what the AutoDJ played against what the audience actually loved — over 24 hours, 7 days and 30 days. One hype per listener per track, only tracks the station really played, and a per-listener rate limit, so the board stays a chart.
For DJs
Everything a DJ needs to run a show — without ever touching the server.
Private station studio
A backstage workspace for the owner and accepted DJs: join a shared handover checklist, mark yourself ready, and exchange private producer cues. The queue is coordination only — it does not switch your broadcast source. Crew updates refresh every five seconds and cue history is limited to seven days.
Local microphone soundcheck
Check microphone levels and clipping risk before going live. Audio is processed only in your browser — never recorded, uploaded or connected to the broadcast. Requires HTTPS or localhost; encoder connectivity must still be tested separately.
Spreadsheet-safe tracklists
Download the last seven days of now-playing history as CSV, with UTC timestamps, artists, titles and sources. Up to 10,000 entries, ordered oldest first, with spreadsheet formula protection. A useful programming log, not a licensing-compliance certification.
Timezone-aware weekly scheduling
Pick an IANA station timezone, assign the owner or accepted crew DJs, and build a weekly lineup with overlap warnings and server-enforced conflict rejection. Public on-air and up-next views use the station clock; the .ics feed uses timezone-aware recurrence across daylight saving. Nonexistent spring-forward times are skipped; repeated fall-back wall times match both occurrences.
Cover requests & programming audit
Presenters request a replacement for an assigned weekly show. Owners or admins approve or reject the request after the replacement's station access is checked. Approval changes the ongoing weekly assignment, not a single dated occurrence. Schedule changes and chapter saves record the actor and detail in a private station audit trail.
Manual replay chapters
Owners bookmark tracks, interviews and memorable moments in finished episodes from the Fans tab. Whole-second chapter times are checked for duplicates and recording bounds, sorted, and shown on the public episode page. No transcription service or API key is required.
Go live from your DJ software
Point BUTT, Mixxx or any Icecast source at the station's live harbor and you're on air — AutoDJ hands over instantly and picks right back up the moment you disconnect.
Voice tracks, requests & tips
Drop liners and station IDs into the rotation every few tracks, approve listener song requests straight to the front of the queue, and collect tips from your public page.
DJ profiles & analytics
Every DJ gets a bio shown on the schedule, while the station's country and referrer breakdown shows exactly who is tuning in to the show.
Station crew
Invite DJs by email to a station and they get their own account access — library, playlists, schedule, rotation, stats and going live. Invites to an address with no account yet become a one-time link the owner hands over, and removing someone cuts access instantly. Settings, branding and billing stay with the owner.
Plugins
The panel is a platform: load small feature modules of your own, written in TypeScript, managed from the console.
A plugin system for new features
Drop a folder into plugins/ with a manifest and a self-contained entry module, press Rescan, and it becomes part of the panel. React to broadcast events, add your own API endpoints, log, keep persisted state, send mail and call any API — a broken plugin is reported and contained, never half-applied.
Hooks into everything
Plugins fire on the 60-second scheduler tick, engine start/stop, every broadcast track (straight from the play history), listener song requests and tips — and on any request under /api/plugins/<your-plugin>/, where a plugin can expose the endpoints it wants.
A permission-gated api
Each hook receives a panel object: structured logging, restart-safe key-value state, outbound HTTP with a timeout, {{name}} template mail over the panel's SMTP, and a topic pub/sub for talking to other plugins. A capability the manifest does not declare throws — the api is the contract.
Managed from one console
Admin → Plugins shows every discovered plugin with version, permissions, hooks, state size, last log line and load errors; flip plugins on or off without deleting files, rescan after edits, and prune each plugin's log to its newest 200 lines.
Accounts, security & ops
The unglamorous parts, already handled.
Station health dashboard
Inspect the engine endpoint, published source mount, AutoDJ process, live harbor port, library quota and free server disk. Run a six-second decoded audio check for silence warnings; failed or unsupported checks report unavailable. Sampling is manual, not continuous silence monitoring.
Backup & restore rehearsal
Admins download a full database snapshot, upload it and rehearse a real transactional import with constraint and row-count checks before restoring. Rehearsal rolls back; restore requires typed confirmation and creates a restricted safety snapshot. Stations must be stopped. Media and server files are excluded; the wizard is capped at 20 MB and 50,000 rows per table.
Multi-user with roles
bcrypt password hashes, server-side sessions, email verification and password resets — with admin and DJ roles plus suspension from the admin console.
Two-factor sign-in
Turn on TOTP two-factor from your account settings and sign in with any standard authenticator app (Google Authenticator, Authy, 1Password, Aegis). The shared secret and ten single-use recovery codes are shown exactly once, code checks tolerate a step of clock drift, and it is about a hundred readable lines of node:crypto rather than another dependency.
Hardened by default
Uploads are checked by extension, magic bytes, per-file size, per-station quota and free disk space; sign-in is throttled per account and per address; FTP refuses a password on an unencrypted channel; outbound requests from the panel refuse private and loopback addresses; and security headers are set on every response.
Free SSL, three authorities
Issue and auto-renew a trusted certificate from Admin → SSL with Let's Encrypt, ZeroSSL or Google Trust Services — no certbot, no cron. Prove the name over HTTP-01, a Cloudflare DNS record, or a TXT record you add yourself, and Icecast then serves listeners over real HTTPS. External Account Binding is checked before an order is placed, and each authority gets its own account key.
Cloudflare at the edge
Set an API token and the admin console shows live zone status for edge SSL, CDN and DDoS in front of your origin.
Sell hosting from a billing panel
Sell radio hosting through WHMCS, Blesta, HostBill, ClientExec, FOSSBilling or Upmind with the modules in the source. One key and one JSON endpoint: a paid order creates the customer's account and station, an unpaid invoice stops the stream and locks their Start button, and a cancellation deletes it. Create is idempotent, so a billing cron re-run cannot open a second station nobody is paying for, and the client area links in with a one-time sign-in instead of storing a second password.
Install, update, uninstall
A one-line installer provisions PostgreSQL, the engines and Node, builds and starts the panel. Updates are one line too — and uninstalling prints its plan before removing anything.
From zero to on air
Four steps, no hidden requirements.
Install
One line on a fresh Linux server — or follow the manual guide step by step.
Run the wizard
Database, domain & IP, admin account — four screens on /setup, then it locks itself.
Create a station
Name, engine and a free port are chosen for you; credentials are ready to paste into your DJ software.
Broadcast & share
Go live or start AutoDJ, then share your /s/<slug> page and embed snippet with the world.
Under the hood
No proprietary runtime and no lock-in: standard open-source engines, a standard database and a standard Node app — anything the installer sets up, the uninstaller can take back down.
Ready to broadcast?
The install guide walks through every command — the wizard then takes about a minute to get you streaming.