Created: 2026
By: Mukesh Singh
Email: mukesh@mkswebs.com
Thank you for purchasing Web Radio Portal. This help file walks you through installation, configuration and day-to-day use of the script, and assumes you are comfortable with basic web hosting (uploading files and creating a MySQL database). If you have any questions that are beyond the scope of this help file, please use the contact form on my author profile. Thanks so much!
Web Radio Portal is a complete internet radio discovery and streaming platform. Visitors can browse and search stations by genre, country and language, play them in a persistent bottom player that keeps playing while browsing the site, and engage with stations through favorites, likes/dislikes, comments, reports and sharing. The platform ships with a full admin panel, an API, automatic stream health checks (live status, current track and listener counts), and a one-click migration tool for existing v1.x installations.
Key features:
.m3u8)
supported via hls.js.The script runs on any modern shared hosting that supports PHP and MySQL. Please check the checklist below before installing.
| Requirement | Minimum / Recommended |
|---|---|
| PHP | 8.3 or higher (8.4 recommended) |
| PHP extensions | pdo_mysql, mbstring, openssl, tokenizer, ctype, json, fileinfo, gd, curl (intl and redis are optional) |
| Database | MySQL 8 / MariaDB 10.6+ (SQLite is supported for local development) |
| Composer | 2.x (needed for installation / updates) |
| Node.js | 20+ (only needed to build the frontend assets, not to run) |
| Web server | Apache (mod_rewrite) or Nginx |
| Cron | Required — one job running every minute (see section J) |
| Browsers | Modern Chrome, Edge, Firefox, Safari (HTML5 Audio + hls.js) |
| Writable folders | storage/ and bootstrap/cache/ |
Note: Flash/RTMP playback is not supported by modern browsers. RTMP stations are flagged and should be replaced with HLS or HTTP streams (see section H).
The easiest way to install is the built-in web installer. It checks your server, then guides you through database, SMTP and admin account setup.
public/ folder. (If your host does not allow that, see section F —
subdirectory install.)composer install --no-dev --optimize-autoloader
cp .env.example .env php artisan key:generate
/install (e.g.
https://yourdomain.com/install).
php artisan storage:link so station logos and uploads resolve (one-time).Prefer the command line? The full manual install is:
composer install --no-dev --optimize-autoloader cp .env.example .env # edit .env — set APP_URL, DB_*, MAIL_* (see section E) php artisan key:generate php artisan migrate --force php artisan db:seed --force npm ci && npm run build # builds the frontend (only needed once) php artisan storage:link
The default admin account created by the seeder is admin@radio-portal.test /
password. Change it immediately after your first login (or use the web
installer to create your own).
All configuration lives in the .env file at the root of the item (created by copying
.env.example). The most important values:
| Key | Purpose |
|---|---|
APP_URL |
The full public URL of your site, e.g. https://yourdomain.com. Include the subdirectory
path if installed in one (section F). |
APP_ENV / APP_DEBUG |
Set APP_ENV=production and APP_DEBUG=false on your live server. |
DB_* |
MySQL connection (host, port, database, username, password). |
MAIL_* |
SMTP settings for verification / password reset emails. |
SESSION_DRIVER |
database (default, shared-hosting friendly). |
CACHE_STORE |
database by default; switch to redis if available. |
QUEUE_CONNECTION |
database by default; the cron worker processes it (section J). |
LEGACY_DB_* |
Only needed for the v1.x migration tool (section L). Remove them after migrating. |
After editing .env, clear the config cache with php artisan config:clear (or
php artisan optimize:clear).
The item supports two hosting layouts:
public/ (recommended) — the web server serves the
public folder directly. This is the cleanest setup.
public_html/radio-portal), the included root .htaccess +
index.php route requests into public/. This works for both the domain root and
subfolders like https://yourdomain.com/radio-portal.
For a subdirectory install, set APP_URL to the full path:
APP_URL=https://yourdomain.com/radio-portal
The script detects the path automatically, so the player, stream proxy, share links and PWA all work under the subfolder.
Important (Apache): the root .htaccess must contain the Livewire exclusion line
so the admin panel’s scripts load correctly:
RewriteCond %{REQUEST_URI} !livewire- [NC]
RewriteRule ^(.+\.js)$ public/$1 [L]
If your host does not allow changing the document root and you skip this file, the admin panel’s Livewire script will be blocked by the browser (see Troubleshooting).
The admin panel is a modern dashboard available at /admin (e.g.
https://yourdomain.com/admin). Log in with an admin account (the seeder default is
admin@radio-portal.test / password — change it right away).
Role permissions: only users with the view.admin permission (Super Admin,
Admin, Moderator, Editor) can access the panel. Every admin mutation is logged to the audit log.
Every station has a stream URL and a stream type. The type must match the actual server, otherwise playback will fail.
| Stream type | Use for |
|---|---|
| Shoutcast / Icecast | Classic HTTP radio streams (MP3 / AAC) — the most common type. |
| HLS (M3U8) | Apple-friendly segmented streams (.m3u8). Played with hls.js. |
| FLAC / generic | Raw HTTP audio (FLAC, OGG, MP3, M4A) — the format is auto-detected. |
| RTMP | Legacy Flash only — not playable in modern browsers. Replace these with HLS or HTTP streams. |
Practical notes (carried over from the original script — still true):
StreamTitle on raw streams) and combines them with your
own listening listeners. Checks run on-demand — opening or playing a station refreshes
it (rate-limited to once per 5 minutes), plus a daily safety sweep.The script uses a single cron entry that runs every minute. It powers the stream health checks, the queue worker and session cleanup — no Supervisor or Redis required.
* * * * * cd /path/to/item && php artisan schedule:run >> /dev/null 2>&1
No SSH / URL-only cron? Point your host’s cron at the included cron.php
file (project root) instead — it runs the exact same scheduler:
# CLI-style cron (cPanel) php /home/USER/path/to/item/cron.php # Web cron / wget (hosts that only allow URLs) wget -q -O /dev/null "https://yourdomain.com/cron.php?token=YOUR_CRON_TOKEN"
For the web variant, set CRON_TOKEN in .env to a long random string (e.g.
php -r "echo bin2hex(random_bytes(24));") — requests without the correct token are rejected
with a 403.
This cron job drives:
radio:check-streams sweep covers stations nobody views.Verify with php artisan schedule:list. You can also run a health check manually:
php artisan radio:check-streams.
A versioned REST API is available under /api/v1. Responses use a consistent envelope:
{data, meta, errors}. Public endpoints:
GET /api/v1/stations — station list (filters: query, genre,
country, language).
GET /api/v1/stations/{slug} — station detail.GET /api/v1/genres and GET /api/v1/genres/{slug} — genres.GET /api/v1/countries — countries.GET /api/v1/search — search stations.GET /api/v1/player/{slug} — player payload (stream URL, playback URL, now-playing).GET|POST|DELETE /api/v1/favorites/{slug} — favorites (requires Sanctum
token).API requests are rate-limited (60/minute by default).
If you already own the original “Web Radio Portal” v1.x and want to move your data to this version, the built-in migration command does it for you. It imports users (passwords preserved), admins, stations, genres, countries, languages, favorites, comments, ratings, reports and settings. Nothing in the old database is modified.
.env:
LEGACY_DB_HOST=127.0.0.1 LEGACY_DB_PORT=3306 LEGACY_DB_DATABASE=your_legacy_db LEGACY_DB_USERNAME=root LEGACY_DB_PASSWORD=your-password
php artisan radio:import --force
# or, from a dump file with logos:
php artisan radio:import --force \
--sql=/full/path/to/radio_sql.sql \
--download-logos \
--logo-base-url=https://your-old-site.example.com
php artisan storage:link (if you downloaded logos) and
php artisan radio:check-streams to kick off health checks.
/radio/{slug} route is kept and
/stations/{slug} redirects to it with a 301.
Notes:
unsafe_streams.| Problem | Solution |
|---|---|
“Table sessions doesn’t exist” when opening the site for the first
time |
The app now handles this automatically — until the installer finishes, sessions/cache fall back to
file storage. If you still see it, run php artisan migrate --force to apply the schema.
|
db:seed fails with “Data too long for column ‘code’” |
Run php artisan migrate --force to apply the latest migration (it widens
languages.code), then re-run php artisan db:seed --force. Seeding is safe
to re-run.
|
Admin panel loads, but scripts are blocked (“MIME type ‘text/html’ is not
executable” / (blocked:other)) |
You are using the subdirectory/webroot mode and the root .htaccess is missing the
Livewire exclusion line (see section F), or public/js/filament was not uploaded. Fix
the .htaccess, upload public/js/filament (or run
php artisan filament:assets), then hard-refresh (Ctrl/Cmd+Shift+R).
|
| Blank home page | The JavaScript bundle failed to load. Hard-refresh once, verify public/build was
uploaded, and make sure the web server serves public/ as the document root. |
| Stream won’t play on an HTTPS site | Plain-HTTP streams are proxied automatically through /stream/{slug}. If the proxy is
blocked (mod_security etc.), disable it in config/streaming.php
(proxy_http_streams => false). |
| Player stops when navigating | The bottom player is turbo-permanent. If it stops, refresh the page once — this only
regresses if the player’s id/data-turbo-permanent attributes were
removed by a customization. |
| No current track / listener count shown | The station’s server does not expose metadata (some raw streams / CDN HLS), or the 5-minute
health check has not run yet. The app reads Icecast, SHOUTcast v1/v2 (stats?sid=1 /
7.html) and ICY StreamTitle. Use the admin panel’s Test
stream (it now saves the result) or php artisan radio:check-streams --sync
to populate immediately.
|
| Login emails never arrive | Check MAIL_* in .env. Use a real SMTP account (not log) in
production. |
| Where are the 404/error pages? | The app ships with safe, styled error pages. Never set APP_DEBUG=true in production.
|
The item is built on the following open-source projects (all permissively licensed — no attribution obligations, but they deserve the credit):
v2.0 — complete modern rebuild:
Once again, thank you so much for purchasing Web Radio Portal. As I said at the beginning, I’d be glad to help you if you have any questions relating to this item. No guarantees, but I’ll do my best to assist. If you have a more general question relating to items on CodeCanyon, you might consider visiting the forums and asking your question in the “Item Discussion” section.
Mukesh Singh