#!/bin/bash set -e JUPYTER_TOKEN="${JUPYTER_TOKEN:=huggingface}" NOTEBOOK_DIR="/data" jupyter labextension disable "@jupyterlab/apputils-extension:announcements" sudo rm -f /tmp/*jack* # Start Xvfb echo "Starting Xvfb..." Xvfb :99 -screen 0 1024x768x16 & sleep 2 export DISPLAY=:99 xhost +local:user # Start Icecast silently echo "Starting Icecast..." #icecast2 -c /app/icecast.xml -b > /dev/null 2>&1 & # Wait for icecast sudo cp /app/icecast.xml /etc/icecast2/icecastnew.xml sudo service icecast2 start sleep 2 # Start JACK with dummy backend echo "Starting JACK..." # -r 44100 often works better across devices; dummy backend suitable for docker jackd -r -d dummy -r 44100 & sleep 2 export XDG_RUNTIME_DIR=/data echo "Starting SuperCollider with scsynth..." #echo "{SinOsc.ar(440, 0, 0.1)}.play;" >> setup.sc echo "" >> setup.sc sclang setup2.sc > sclang.out & sleep 5 sclang setup.sc >> sclang.out & sleep 10 # Start FFmpeg to stream from JACK to Icecast # We need to find the JACK ports. Usually SuperCollider outputs to 'SuperCollider:out_1' and 'SuperCollider:out_2' # But SC isn't running yet. We'll start ffmpeg in a loop or start it after SC. # Actually, if we use a jack input in ffmpeg, it might fail if jackd isn't there, but it is there. # However, if SC isn't there, there's nothing to record. # But we can capture from the "system" or wait for SC ports. # A simpler way: Start a dummy loopback or just start ffmpeg listening to expected ports. # 'ffmpeg -f jack -i sc-output ...' # For now, let's just background the ffmpeg process. It might retry or we can start it later. # Better approach: Start SuperCollider first (via FoxDot or standalone), then FFmpeg. # But FoxDot is interactive. # We will start a background script that waits for SuperCollider ports to appear then starts FFmpeg. ( echo "Waiting for SuperCollider ports..." while ! jack_lsp | grep -q "SuperCollider:out_1"; do sleep 1 done echo "SuperCollider found. Starting FFmpeg streamer ..." ffmpeg -vn -re -f jack -thread_queue_size 16 -probesize 32 -analyzeduration 0 \ -i ffmpeg -ac 2 -codec:a libmp3lame -b:a 192k -compression_level 0 -flush_packets 1 \ -content_type audio/mpeg -ice_name "Radio HOP" -ice_description "This is HOP, based on FoxDot" \ -ice_genre "FoxDot" -vn -f mp3 icecast://source:hackme@localhost:8000/stream.mp3 ) & sleep 2 jack_connect SuperCollider:out_1 ffmpeg:input_1 jack_connect SuperCollider:out_2 ffmpeg:input_2 # # PRODUCTION STREAM # # Start Nginx echo "Starting Nginx..." nginx -c /app/nginx.conf & # Starting Consumer echo "Starting API Consumer" python3 Consumer.py > out2.txt & # Start Jupyter Lab on 8888 (internal) with nginx echo "Starting Jupyter Lab..." # # DEVELOPMENT ENVIRONMENT # Jupyter Lab # # --no-browser \ jupyter-lab \ --ip 0.0.0.0 \ --port 8888 \ --allow-root \ --ServerApp.token="$JUPYTER_TOKEN" \ --ServerApp.tornado_settings="{'headers': {'Content-Security-Policy': 'frame-ancestors *'}}" \ --ServerApp.cookie_options="{'SameSite': 'None', 'Secure': True}" \ --ServerApp.base_url="/dev/" --ServerApp.disable_check_xsrf=True \ --LabApp.news_url=None \ --LabApp.check_for_updates_class="jupyterlab.NeverCheckForUpdate" \ --notebook-dir=$NOTEBOOK_DIR Untitled1.ipynb Player.ipynb