Commit Graph

103 Commits

Author SHA1 Message Date
ComputerTech 0ec02507b3 fix: check both _ffmpeg_proc and _srt_ffmpeg_proc in stream.mp3 route 2026-04-04 14:35:35 +01:00
ComputerTech 20bedad639 fix: log ffmpeg stderr in SRT reader to expose connection errors 2026-04-04 14:19:35 +01:00
ComputerTech e88d649f55 fix: correct RTSP URL path from /live to /aussie_dj 2026-04-04 14:14:27 +01:00
ComputerTech 0e0be1069b fix: remove publisher_ip NameError; replace eventlet.tpool with direct IO 2026-04-04 14:08:34 +01:00
ComputerTech 9150d3cc83 feat: remove SRT IP allowlist 2026-04-04 13:59:25 +01:00
ComputerTech b88f6f1e5c fix: simplify mediamtx config to minimal valid YAML 2026-04-04 13:38:38 +01:00
ComputerTech 457c5c89c9 fix: correct MediaMTX v1.x config syntax (runOnReady, top-level flags) 2026-04-04 13:35:45 +01:00
ComputerTech 68974261e5 fix: use correct MediaMTX v1.x top-level disable flags in setup script 2026-04-04 13:32:14 +01:00
ComputerTech 1174b65b7d feat: add gunicorn production server with start/stop/restart manager 2026-04-04 13:21:05 +01:00
ComputerTech ad06ee4854 feat: add setup_mediamtx.sh install script 2026-04-04 13:14:44 +01:00
ComputerTech 075deff7bd fix: remove HLS video player from listener page 2026-04-04 13:12:24 +01:00
ComputerTech c4d9fad60f fix: change SRT port default from 5005 to 8890 (MediaMTX default) 2026-04-04 13:00:41 +01:00
ComputerTech effb52c5df fix: revert listener port to 5001; set SRT port to 5005 via mediamtx_srt_port config 2026-04-04 12:39:03 +01:00
ComputerTech 498832bdcb chore: change listener port from 5001 to 5005 2026-04-04 12:36:37 +01:00
ComputerTech 3c0174ff31 feat: MediaMTX SRT integration, IP allowlist, pre-roll bugfixes 2026-04-04 12:33:45 +01:00
ComputerTech 20e56f37b8 Fix Qt client music not playing on listener page
Replace PulseAudio monitor capture with direct file streaming.
Qt6's FFmpeg/PipeWire-native audio backend ignores PULSE_SINK so
the monitor captured silence. StreamingWorker now receives the
playing file path via a command queue and pipes it through ffmpeg
-re (real-time rate) directly to the server as audio_chunk events.

- Add switch_file() / stop_file() to StreamingWorker
- Replace ffmpeg pulse capture loop with file-based cmd loop
- DeckWidget.play() calls switch_file(path, position_ms)
- DeckWidget.pause()/stop() calls stop_file()
- Add now_playing socket relay in server.py
- listener.js handles now_playing event to show track title
- Add deck_glow emission from Qt deck play/pause/stop
2026-04-03 14:18:28 +01:00
ComputerTech 46128f5c58 fix: use listener port (no auth) for server library fetch and track downloads
Previously, fetch_server_library() and populate_server_library() used
get_server_base_url() which resolves to the DJ panel port (5000). When
dj_panel_password is set, ALL routes on port 5000 require an authenticated
session cookie. The Qt client had no cookie, so every library.json request
was redirected to /login (HTML), json.loads() failed, and the server list
stayed empty.

Fix:
- Add get_listener_base_url() that derives the listener port (DJ port + 1,
  default 5001) from the configured stream_server_url
- fetch_server_library() now fetches /library.json from the listener port
- Track download URLs built in populate_server_library() now point to the
  listener port's /music_proxy/ route — both are auth-free on the listener
  server (port 5001)
- upload_track() still correctly POSTs to the DJ port (5000) since the
  listener server blocks /upload; it now also authenticates with the DJ
  panel cookie before uploading so uploads work with a password too
2026-04-03 13:47:47 +01:00
ComputerTech 80a4286bc0 fix: defer broadcast_started for Qt MP3-direct mode until first audio chunk
Previously, start_broadcast immediately emitted broadcast_started and
stream_status: active to listeners, even before the DJ pressed play.
Listeners would connect to /stream.mp3, wait 60s with no data, then
disconnect — so music never reached them from the PyQt client.

The web DJ panel was unaffected because it only sends audio_chunk while
music is actively playing, so start_broadcast and data arrive together.

Fix: in MP3-direct mode (Qt client, format=mp3), hold back broadcast_started
and stream_status: active until the very first audio_chunk arrives. The
first chunk guarantees the preroll buffer has data and listeners will
immediately receive audio when they connect.

- _mp3_broadcast_announced flag tracks whether the deferred announcement
  has been sent in the current session
- Resets on stop_broadcast, grace-period auto-stop, and fresh start_broadcast
- Browser (webm/opus) mode is unaffected — announces immediately as before
2026-04-03 13:44:09 +01:00
ComputerTech 35adfa7feb Tauri v2 migration: asset protocol, desktop CSS polish, absolutePath in library 2026-03-28 11:49:00 +00:00
ComputerTech d2e6e2a7d7 Update script.js, settings.json; remove MOBILE_IMPROVEMENTS.md 2026-03-28 11:24:46 +00:00
ComputerTech eb3e66ba61 Implement Duplicate Upload Prevention
- Server: /upload rejects existing files with 409 Conflict
- Web: handleFileUpload skips duplicates with toast feedback
- Qt: upload_track blocks duplicate imports and uploads with dialog alert
2026-03-12 19:12:07 +00:00
ComputerTech 44b36bf08d Comprehensive DJ Panel Improvements:
- Added toast notification system for visible feedback
- Implemented settings persistence via localStorage
- Added auto-crossfade logic (smooth 5s transition)
- Removed ~100 lines of dead SERVER_SIDE_AUDIO code
- Fixed seekTo speed bug by capturing current playbackRate
- Debounced drawWaveform with requestAnimationFrame
- Added 'SETTINGS' header and close button to settings panel
- Wired loadFromServer errors to toast notifications
- Stacked control buttons vertically to clear crossfader
2026-03-12 16:52:21 +00:00
ComputerTech 9513c11747 Restore settings panel header with close button 2026-03-11 19:41:20 +00:00
ComputerTech 2e64870daa UI improvements: glow effects, deck colors, listener count, remove black bar, mobile header fix 2026-03-11 19:34:32 +00:00
ComputerTech 6027f2e973 Fix streaming: bypass ffmpeg for MP3 input, fix PyQt latency, fix routing bugs
- server.py: Add _distribute_mp3() to route MP3 chunks directly to listener
  queues without a second ffmpeg passthrough (halves pipeline latency, removes
  the eventlet/subprocess blocking read that caused the Qt client to fail)
- server.py: dj_start no longer starts ffmpeg for is_mp3_input=True
- server.py: dj_audio routes to _distribute_mp3 vs _feed_transcoder based on format
- server.py: _transcoder_watchdog skips MP3-direct mode
- server.py: stream_mp3 endpoint no longer waits for ffmpeg proc when MP3 direct
- techdj_qt.py: Add -fflags nobuffer + -flush_packets 1 to reduce source latency
- techdj_qt.py: bufsize=0 and read(4096) instead of read(8192) for ~260ms chunks
- listener.js: Reduce broadcast_started connect delay 800ms -> 300ms
2026-03-10 19:54:06 +00:00
ComputerTech 514f9899a3 Remove listener count from listening page 2026-03-10 19:33:56 +00:00
ComputerTech af109381c1 Reduce buffering: 250ms DJ chunks, 1024-chunk preroll, X-Accel-Buffering header 2026-03-10 19:32:24 +00:00
ComputerTech 43a3e692fc Fix upload error handling; log 413 nginx size limit clearly 2026-03-10 19:13:39 +00:00
ComputerTech 1fa6887efd Fix stream URL detection for custom domains; add listener_url config 2026-03-10 19:07:04 +00:00
ComputerTech dfccec2b48 Stability fixes: loop end-of-track guard, DJ disconnect grace period, StreamingWorker race condition fix, various audit cleanups 2026-03-10 18:53:17 +00:00
ComputerTech 8c3c2613b1 Fix broadcast broken: reconnect loop, listener stuck on waiting
- server.py: Increase ping_timeout 10->60, ping_interval 5->25 to prevent
  frequent socket disconnects during audio streaming
- server.py: Guard dj_start() against reconnect loops - only clear pre-roll
  and emit broadcast_started on a fresh broadcast, not on DJ reconnects
- listener.js: Add polling fallback to transports (websocket-only caused
  silent failure on upgrade error), set reconnectionAttempts to Infinity
- script.js: Same transport fallback fix for DJ panel socket
- techdj_qt.py: Add _broadcast_started flag to StreamingWorker.on_connect
  so streaming_started signal only fires once; reconnects resume silently.
  Reset flag in stop_streaming() for clean next session.
2026-03-09 20:47:52 +00:00
ComputerTech 5ba5c45e64 Fix: audio isolation via PULSE_SINK env var before QApplication
- Replace fragile PID-based PulseAudioIsolator class with module-level
  PULSE_SINK approach: create virtual null sink BEFORE QApplication()
  so Qt routes all audio there automatically
- Add verification that the monitor source actually exists before trusting it
- Add clear startup diagnostics (✓ confirmations for each step)
- get_audio_capture_source() now double-checks monitor still exists
- Fails loudly instead of silently falling back to default.monitor
- Remove threading import (no longer needed)
- Add atexit cleanup for virtual sink teardown
2026-03-09 20:26:36 +00:00
ComputerTech cddce99b29 Fix: isolate DJ audio from system audio in streaming/recording
The Qt app was using PulseAudio's 'default.monitor' which captures ALL
system audio (YouTube Music, Spotify, browser, etc.). This caused listeners
to hear whatever was playing on the DJ's system, not just the DJ mix.

Added PulseAudioIsolator class that:
- Creates a virtual PulseAudio null sink ('techdj_stream')
- Routes only this app's audio to the virtual sink
- Creates a loopback so the DJ still hears their mix through speakers
- Captures from the virtual sink's monitor (only DJ audio)
- Reference-counted: shared between streaming and recording workers
- Automatically cleans up stale sinks from previous crashes
- Periodically re-routes audio to catch new tracks/streams
- Falls back to default.monitor if pactl is unavailable

Both StreamingWorker and RecordingWorker now use the isolator.
2026-03-09 19:45:43 +00:00
ComputerTech abf907ddfb Fix 6 bugs: remove dead listener code from DJ panel, fix StreamingWorker socket reuse, fix GUI-blocking time.sleep, fix abort import
- script.js: Remove ~500 lines of dead listener mode code (initListenerMode, enableListenerAudio, setListenerVolume, startListenerVUMeter, getMp3FallbackUrl, listener variables). Listener page now uses listener.js exclusively.
- script.js: Remove ?listen=true detection from DOMContentLoaded that could activate broken listener UI on DJ panel.
- script.js: Clean up initSocket() to remove dead listener mode detection logic.
- index.html: Remove dead #listener-mode div (now served by listener.html).
- server.py: Move 'abort' import to top-level Flask import instead of per-request import.
- techdj_qt.py: Fix StreamingWorker to create fresh socketio.Client on each streaming session, preventing stale socket state on reconnect.
- techdj_qt.py: Fix time.sleep(0.2) blocking GUI thread in stop_streaming() by removing it and using try/except for clean disconnect.
2026-03-09 19:16:42 +00:00
ComputerTech 7c33c678aa Fix listener serving DJ panel instead of listener page
- Block DJ-only files (index.html, script.js, style.css) on listener server
- Disable Flask built-in static handler on listener (static_folder=None)
  to prevent it from serving index.html before custom routes
- Add Cache-Control no-store headers to index route to prevent
  nginx/browser from caching stale index.html for listener URL
2026-03-09 19:01:42 +00:00
ComputerTech 5a7f4e81a4 Separate listener page from DJ panel
- Created standalone listener.html, listener.js, listener.css
- Listener server now serves listener.html instead of index.html
- Eliminates flash of DJ panel when loading listener page
- setup_shared_routes() accepts index_file parameter
2026-03-09 18:50:04 +00:00
ComputerTech df283498eb Add config.json system; fix bugs across server.py, script.js, techdj_qt.py
- Add config.example.json with all options: host, dj_port, listener_port,
  dj_panel_password, secret_key, music_folder, stream_bitrate, max_upload_mb,
  cors_origins, debug (copy to config.json to use)
- server.py: drive host/ports/secrets/CORS/upload limit from config.json;
  fix serve_static to use allowlist only; move re import to top-level;
  fix inconsistent indentation in login/logout/before_request handlers
- script.js: fix undefined decks.crossfader in updateUIFromMixerStatus;
  declare mediaRecorder as a proper let variable
- techdj_qt.py: replace blocking time.sleep poll in YTDownloadWorker with
  non-blocking QTimer; fix fragile or-chained lambda in recording reset
2026-03-09 18:02:47 +00:00
ComputerTech 1f07b87c36 Fix actual root causes: waveform black block, body gradient bleed, JS glow override 2026-03-05 18:02:08 +00:00
ComputerTech 663ea17040 Fix visual bugs: hide VU canvases (black block), inset deck box-shadows (colored line bleed) 2026-03-05 17:42:37 +00:00
ComputerTech 49062cf6de Fix VU canvas black blocks and colored glow-bleed lines 2026-03-05 17:25:40 +00:00
ComputerTech b5ea9e8d01 Final bug sweep: fix event param, remove dead code, dedupe CSS; add .gitignore recordings/ 2026-03-05 14:28:17 +00:00
ComputerTech 12c01faa83 feat: add integrated deck queues and track loop functionality 2026-02-07 20:14:04 +00:00
ComputerTech 6246b26925 Mobile UX improvements: Remove emojis, convert to British English, fix queue navigation and floating buttons
- Removed all emojis from UI (replaced with text labels)
- Converted all American English to British English (initialise, optimise, visualiser)
- Fixed mobile queue section visibility in portrait/landscape modes
- Added proper CSS rules for show-queue-A and show-queue-B classes
- Repositioned floating action buttons to prevent overlap with mobile tabs
- Added responsive button sizing for mobile (50px) and small screens (45px)
- Stacked buttons vertically on screens ≤480px
- Disabled all body::before border effects that were blocking UI
- Fixed crossfader width: 70% in portrait, 100% in landscape
- Removed unnecessary .md files (COMPARISON.md, PYQT5_FEATURES.md, QUICKSTART.md, README_PYQT5.md)
- Updated README.md with British English and removed emojis
2026-02-02 02:37:56 +00:00
ComputerTech c2085291c0 hm 2026-01-20 20:04:39 +00:00
ComputerTech 02f72e2372 Fix buffering issue and app bugs: improve stream delivery, fixed reset UI desync, and EQ naming 2026-01-20 18:14:50 +00:00
ComputerTech 1776f631ef Fix filter sliders - connect low-pass and high-pass to audio engine 2026-01-20 18:05:50 +00:00
ComputerTech 740fa34f93 Make deck header more compact with smaller fonts and tighter spacing 2026-01-20 18:01:45 +00:00
ComputerTech de973b2a0e Add loop/repeat and queue features for both decks 2026-01-20 17:57:19 +00:00
ComputerTech ee26294106 Fix critical bugs: broadcast thread, resource cleanup, and Socket.IO error handling 2026-01-20 17:49:00 +00:00
ComputerTech d7a11c2af2 Add window icon to PyQt5 application 2026-01-20 17:30:56 +00:00