diff --git a/README.md b/README.md index 194f4cb..e2da752 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ TechDJ Pro is a local DJ web app with a dual-port architecture: - **DJ Panel** (mix/load tracks + start broadcast): `http://localhost:5000` -- **Listener Page** (receive the live stream): `http://localhost:5005` +- **Listener Page** (receive the live stream): `http://localhost:5001` It supports: - Local library playback (files in `music/`) @@ -104,7 +104,7 @@ If you want to lock it while you’re playing live, create a `config.json` (not Behavior: - If `dj_panel_password` is empty/missing, the DJ panel is **unlocked** (default). - If set, visiting `http://:5000` shows a login prompt. -- Listener (`:5005`) is not affected. +- Listener (`:5001`) is not affected. --- @@ -120,7 +120,7 @@ python server.py You should see output like: - DJ panel: `http://localhost:5000` -- Listener page: `http://localhost:5005` +- Listener page: `http://localhost:5001` --- @@ -149,10 +149,10 @@ TechDJ can relay live streams from other DJ servers: ### Listener workflow 1. Open the Listener Page: - - Same machine: `http://localhost:5005` + - Same machine: `http://localhost:5001` - Another device on your LAN/Wi‑Fi: - `http://:5005` + `http://:5001` 2. Click **ENABLE AUDIO** if prompted - Browsers block autoplay by default; user interaction is required.3. Enjoy the live stream with real-time spectrum visualization @@ -186,7 +186,7 @@ Use the LAN IP (commonly `192.168.x.x` or `10.x.x.x`). Make sure the DJ machine allows inbound connections on: - TCP `5000` (DJ Panel) -- TCP `5005` (Listener) +- TCP `5001` (Listener) If listeners can’t connect, this is often the cause. @@ -196,7 +196,7 @@ If listeners can’t connect, this is often the cause. TechDJ serves the listener audio as an **MP3 HTTP stream**: -- MP3 stream endpoint: `http://:5005/stream.mp3` +- MP3 stream endpoint: `http://:5001/stream.mp3` This requires `ffmpeg` installed on the DJ/server machine. @@ -204,7 +204,7 @@ This requires `ffmpeg` installed on the DJ/server machine. - Stream debug JSON: - `http://:5005/stream_debug` + `http://:5001/stream_debug` This shows whether ffmpeg is running and whether MP3 bytes are being produced. @@ -240,7 +240,7 @@ Example Cloudflare page rule: - Ensure `ffmpeg` is installed on the server - Try opening the MP3 fallback directly: - `http://:5005/stream.mp3` + `http://:5001/stream.mp3` ### DJ says broadcast is live but listeners hear nothing @@ -248,7 +248,7 @@ Example Cloudflare page rule: - A deck is actually playing - Crossfader isn’t fully on the silent side - Volumes aren’t at 0 -- Check `http://:5005/stream_debug` and see if `transcoder_bytes_out` increases +- Check `http://:5001/stream_debug` and see if `transcoder_bytes_out` increases ### Spectrum visualiser not showing - Ensure the listener page is loaded and audio is enabled. diff --git a/config.example.json b/config.example.json index fa1d78e..fb7a730 100644 --- a/config.example.json +++ b/config.example.json @@ -3,7 +3,7 @@ "host": "0.0.0.0", "dj_port": 5000, - "listener_port": 5005, + "listener_port": 5001, "dj_panel_password": "", "secret_key": "", @@ -19,6 +19,8 @@ "_comment_mediamtx": "MediaMTX / SRT integration. mediamtx_webhook_secret is the shared secret sent in the X-MediaMTX-Webhook-Secret header by webhook callers (leave blank to disable auth). mediamtx_rtsp_url is the RTSP URL MediaMTX exposes for the incoming SRT path.", "mediamtx_webhook_secret": "", + "_comment_mediamtx_srt_port": "SRT ingest port MediaMTX listens on. Flask does not bind this port — set it in mediamtx.yml. Stored here for reference.", + "mediamtx_srt_port": 5005, "mediamtx_rtsp_url": "rtsp://127.0.0.1:8554/live", "mediamtx_hls_url": "http://techy.music:8888/aussie_dj/index.m3u8", "_comment_srt_allowed_ips": "List of DJ source IPs allowed to publish an SRT stream. Empty = allow all.", diff --git a/index.html b/index.html index 5413de5..7d63851 100644 --- a/index.html +++ b/index.html @@ -392,7 +392,7 @@
- +
diff --git a/script.js b/script.js index c5046ef..5f8fd30 100644 --- a/script.js +++ b/script.js @@ -366,7 +366,7 @@ function animateVUMeters() { requestAnimationFrame(animateVUMeters); const anyPlaying = decks.A.playing || decks.B.playing; - const isListener = window.location.port === '5005' || window.location.search.includes('listen=true'); + const isListener = window.location.port === '5001' || window.location.search.includes('listen=true'); // When nothing is playing, clear canvases to transparent so they don't show as dark blocks if (!anyPlaying && !isListener) { @@ -1880,7 +1880,7 @@ window.addEventListener('DOMContentLoaded', () => { if (host.startsWith('dj.')) { return `${window.location.protocol}//${host.slice(3)}`; } - return `${window.location.protocol}//${host}:5005`; + return `${window.location.protocol}//${host}:5001`; }; fetch('/client_config') .then(r => r.json()) diff --git a/server.py b/server.py index 051f732..154b694 100644 --- a/server.py +++ b/server.py @@ -38,7 +38,7 @@ CONFIG = _load_config() # --- Config-driven settings (config.json > env vars > defaults) --- CONFIG_HOST = (CONFIG.get('host') or os.environ.get('HOST') or '0.0.0.0').strip() CONFIG_DJ_PORT = int(CONFIG.get('dj_port') or os.environ.get('DJ_PORT') or 5000) -CONFIG_LISTENER_PORT = int(CONFIG.get('listener_port') or os.environ.get('LISTEN_PORT') or 5005) +CONFIG_LISTENER_PORT = int(CONFIG.get('listener_port') or os.environ.get('LISTEN_PORT') or 5001) CONFIG_SECRET = (CONFIG.get('secret_key') or '').strip() or 'dj_panel_secret' CONFIG_CORS = CONFIG.get('cors_origins', '*') CONFIG_MAX_UPLOAD_MB = int(CONFIG.get('max_upload_mb') or 500) @@ -48,6 +48,8 @@ CONFIG_LISTENER_URL = (CONFIG.get('listener_url') or '').strip() # MediaMTX / SRT integration # secret shared with MediaMTX webhook requests (leave blank to disable auth) _SRT_WEBHOOK_SECRET = (CONFIG.get('mediamtx_webhook_secret') or '').strip() +# SRT ingest port MediaMTX listens on (Flask does not bind this — configure in mediamtx.yml) +_MEDIAMTX_SRT_PORT = int(CONFIG.get('mediamtx_srt_port') or 5005) # RTSP URL MediaMTX exposes for the incoming SRT path (used by ffmpeg to pull audio) _MEDIAMTX_RTSP_URL = (CONFIG.get('mediamtx_rtsp_url') or 'rtsp://127.0.0.1:8554/live').strip() _MEDIAMTX_HLS_URL = (CONFIG.get('mediamtx_hls_url') or 'http://techy.music:8888/aussie_dj/index.m3u8').strip() @@ -712,7 +714,7 @@ setup_shared_routes(dj_app) def _protect_dj_panel(): """Optionally require a password for the DJ panel only (port 5000). - This does not affect the listener server (port 5005). + This does not affect the listener server (port 5001). """ if not DJ_AUTH_ENABLED: return None @@ -1103,11 +1105,11 @@ def mediamtx_webhook(): MediaMTX path config example (mediamtx.yml): paths: live: - runOnPublish: 'curl -s -X POST http://127.0.0.1:5005/api/webhook -H "Content-Type: application/json" -d \'{"event":"publish","path":"%MTX_PATH%","id":"%MTX_ID%"}\'' - runOnUnpublish: 'curl -s -X POST http://127.0.0.1:5005/api/webhook -H "Content-Type: application/json" -d \'{"event":"unpublish","path":"%MTX_PATH%","id":"%MTX_ID%"}\'' + runOnPublish: 'curl -s -X POST http://127.0.0.1:5001/api/webhook -H "Content-Type: application/json" -d \'{"event":"publish","path":"%MTX_PATH%","id":"%MTX_ID%"}\'' + runOnUnpublish: 'curl -s -X POST http://127.0.0.1:5001/api/webhook -H "Content-Type: application/json" -d \'{"event":"unpublish","path":"%MTX_PATH%","id":"%MTX_ID%"}\'' Or if using MediaMTX >= 1.x webhook integration, point: - api > hooks > [publish|unpublish] > url: http://127.0.0.1:5005/api/webhook + api > hooks > [publish|unpublish] > url: http://127.0.0.1:5001/api/webhook """ global _mp3_broadcast_announced @@ -1197,7 +1199,7 @@ def srt_auth(): attempt. Returning HTTP 200 allows the connection; anything else rejects it. mediamtx.yml: - externalAuthenticationURL: http://127.0.0.1:5005/api/srt_auth + externalAuthenticationURL: http://127.0.0.1:5001/api/srt_auth MediaMTX sends JSON like: {"ip": "1.2.3.4", "action": "publish", "protocol": "srt", diff --git a/techdj_qt.py b/techdj_qt.py index 95a2520..a915314 100644 --- a/techdj_qt.py +++ b/techdj_qt.py @@ -2686,7 +2686,7 @@ class DJApp(QMainWindow): def get_listener_base_url(self): """Return the listener server base URL (no auth required). - The listener server runs on DJ_port + 1 by convention (default 5005). + The listener server runs on DJ_port + 1 by convention (default 5001). Library JSON and music_proxy routes are available there without any password, so we use this for all library / track-download requests. """ @@ -2702,8 +2702,8 @@ class DJApp(QMainWindow): # Normalise: if the configured port IS the listener port, keep it; # otherwise derive listener port as DJ port + 1. - if dj_port == 5005: - listener_port = 5005 + if dj_port == 5001: + listener_port = 5001 else: # Remap any reverse-proxy or listener port back to DJ port first, # then add 1 to get the listener port. @@ -2726,7 +2726,7 @@ class DJApp(QMainWindow): port = parsed.port or 5000 # Remap listener port and common reverse-proxy port to the DJ server port - if port in (5005, 8080): + if port in (5001, 8080): port = 5000 # Always use plain HTTP — the server never terminates TLS directly.