feat: stream base url as variable on templates
This commit is contained in:
parent
91c77206d1
commit
70263fbfbc
|
|
@ -19,6 +19,7 @@
|
|||
(merge-pathnames "music/library/"
|
||||
(asdf:system-source-directory :asteroid)))
|
||||
(defparameter *supported-formats* '("mp3" "flac" "ogg" "wav"))
|
||||
(defparameter *stream-base-url* "http://localhost:8000")
|
||||
|
||||
;; Configure JSON as the default API format
|
||||
(define-api-format json (data)
|
||||
|
|
@ -444,6 +445,10 @@
|
|||
:status-message "🟢 LIVE - Broadcasting asteroid music for hackers"
|
||||
:listeners "0"
|
||||
:stream-quality "128kbps MP3"
|
||||
:stream-base-url *stream-base-url*
|
||||
:default-stream-url (concatenate 'string *stream-base-url* "/asteroid.aac")
|
||||
:default-stream-encoding "audio/aac"
|
||||
:default-stream-encoding-desc "AAC 96kbps Stereo"
|
||||
:now-playing-artist "The Void"
|
||||
:now-playing-track "Silence"
|
||||
:now-playing-album "Startup Sounds"
|
||||
|
|
@ -458,7 +463,7 @@
|
|||
(defun check-icecast-status ()
|
||||
"Check if Icecast server is running and accessible"
|
||||
(handler-case
|
||||
(let ((response (drakma:http-request "http://localhost:8000/status-json.xsl"
|
||||
(let ((response (drakma:http-request (concatenate 'string *stream-base-url* "/status-json.xsl")
|
||||
:want-stream nil
|
||||
:connection-timeout 2)))
|
||||
(if response "🟢 Running" "🔴 Not Running"))
|
||||
|
|
@ -739,7 +744,8 @@
|
|||
(clip:process-to-string
|
||||
(plump:parse (alexandria:read-file-into-string template-path))
|
||||
:title "Asteroid Radio - Web Player"
|
||||
:stream-url "http://localhost:8000/asteroid"
|
||||
:stream-base-url *stream-base-url*
|
||||
:default-stream-url (concatenate 'string *stream-base-url* "/asteroid.aac")
|
||||
:bitrate "128kbps MP3"
|
||||
:now-playing-artist "The Void"
|
||||
:now-playing-track "Silence"
|
||||
|
|
@ -756,14 +762,14 @@
|
|||
("artist" . "The Void")
|
||||
("album" . "Startup Sounds")))
|
||||
("listeners" . 0)
|
||||
("stream-url" . "http://localhost:8000/asteroid.mp3")
|
||||
("stream-url" . ,(concatenate 'string *stream-base-url* "/asteroid.mp3"))
|
||||
("stream-status" . "live"))))
|
||||
|
||||
;; Live stream status from Icecast
|
||||
(define-api asteroid/icecast-status () ()
|
||||
"Get live status from Icecast server"
|
||||
(handler-case
|
||||
(let* ((icecast-url "http://localhost:8000/admin/stats.xml")
|
||||
(let* ((icecast-url (concatenate 'string *stream-base-url* "/admin/stats.xml"))
|
||||
(response (drakma:http-request icecast-url
|
||||
:want-stream nil
|
||||
:basic-authorization '("admin" "asteroid_admin_2024"))))
|
||||
|
|
@ -783,7 +789,7 @@
|
|||
(listeners (or (cl-ppcre:regex-replace-all ".*<listeners>(.*?)</listeners>.*" source-section "\\1") "0")))
|
||||
;; Return JSON in format expected by frontend
|
||||
(api-output
|
||||
`(("icestats" . (("source" . (("listenurl" . "http://localhost:8000/asteroid.mp3")
|
||||
`(("icestats" . (("source" . (("listenurl" . ,(concatenate 'string *stream-base-url* "/asteroid.mp3"))
|
||||
("title" . ,title)
|
||||
("listeners" . ,(parse-integer listeners :junk-allowed t)))))))))
|
||||
;; No source found, return empty
|
||||
|
|
@ -842,8 +848,12 @@
|
|||
|
||||
(defun -main (&optional args (debug t))
|
||||
(declare (ignorable args))
|
||||
(when (uiop:getenvp "ASTEROID_STREAM_URL")
|
||||
(setf *stream-base-url* (uiop:getenv "ASTEROID_STREAM_URL")))
|
||||
(format t "~&args of asteroid: ~A~%" args)
|
||||
(format t "~%🎵 ASTEROID RADIO - Music for Hackers 🎵~%")
|
||||
(format t "Using stream server at ~a~%" *stream-base-url*)
|
||||
|
||||
(format t "Starting RADIANCE web server...~%")
|
||||
(when debug
|
||||
(slynk:create-server :port 4009 :dont-close t))
|
||||
|
|
|
|||
|
|
@ -1,29 +1,34 @@
|
|||
// Stream quality configuration
|
||||
const streamConfig = {
|
||||
aac: {
|
||||
url: 'http://localhost:8000/asteroid.aac',
|
||||
format: 'AAC 96kbps Stereo',
|
||||
type: 'audio/aac',
|
||||
mount: 'asteroid.aac'
|
||||
},
|
||||
mp3: {
|
||||
url: 'http://localhost:8000/asteroid.mp3',
|
||||
format: 'MP3 128kbps Stereo',
|
||||
type: 'audio/mpeg',
|
||||
mount: 'asteroid.mp3'
|
||||
},
|
||||
low: {
|
||||
url: 'http://localhost:8000/asteroid-low.mp3',
|
||||
format: 'MP3 64kbps Stereo',
|
||||
type: 'audio/mpeg',
|
||||
mount: 'asteroid-low.mp3'
|
||||
}
|
||||
function getStreamConfig(streamBaseUrl, encoding) {
|
||||
const config = {
|
||||
aac: {
|
||||
url: `${streamBaseUrl}/asteroid.aac`,
|
||||
format: 'AAC 96kbps Stereo',
|
||||
type: 'audio/aac',
|
||||
mount: 'asteroid.aac'
|
||||
},
|
||||
mp3: {
|
||||
url: `${streamBaseUrl}/asteroid.mp3`,
|
||||
format: 'MP3 128kbps Stereo',
|
||||
type: 'audio/mpeg',
|
||||
mount: 'asteroid.mp3'
|
||||
},
|
||||
low: {
|
||||
url: `${streamBaseUrl}/asteroid-low.mp3`,
|
||||
format: 'MP3 64kbps Stereo',
|
||||
type: 'audio/mpeg',
|
||||
mount: 'asteroid-low.mp3'
|
||||
}
|
||||
};
|
||||
|
||||
return config[encoding]
|
||||
};
|
||||
|
||||
// Change stream quality
|
||||
function changeStreamQuality() {
|
||||
const selector = document.getElementById('stream-quality');
|
||||
const config = streamConfig[selector.value];
|
||||
const streamBaseUrl = document.getElementById('stream-base-url');
|
||||
const config = getStreamConfig(streamBaseUrl.value, selector.value);
|
||||
|
||||
// Update UI elements
|
||||
document.getElementById('stream-url').textContent = config.url;
|
||||
|
|
@ -91,7 +96,8 @@ async function updateNowPlaying() {
|
|||
window.addEventListener('DOMContentLoaded', function() {
|
||||
// Set initial quality display to match the selected stream
|
||||
const selector = document.getElementById('stream-quality');
|
||||
const config = streamConfig[selector.value];
|
||||
const streamBaseUrl = document.getElementById('stream-base-url');
|
||||
const config = getStreamConfig(streamBaseUrl.value, selector.value);
|
||||
document.getElementById('stream-url').textContent = config.url;
|
||||
document.getElementById('stream-format').textContent = config.format;
|
||||
|
||||
|
|
|
|||
|
|
@ -525,28 +525,33 @@ async function loadPlaylist(playlistId) {
|
|||
}
|
||||
|
||||
// Stream quality configuration (same as front page)
|
||||
const liveStreamConfig = {
|
||||
aac: {
|
||||
url: 'http://localhost:8000/asteroid.aac',
|
||||
type: 'audio/aac',
|
||||
mount: 'asteroid.aac'
|
||||
},
|
||||
mp3: {
|
||||
url: 'http://localhost:8000/asteroid.mp3',
|
||||
type: 'audio/mpeg',
|
||||
mount: 'asteroid.mp3'
|
||||
},
|
||||
low: {
|
||||
url: 'http://localhost:8000/asteroid-low.mp3',
|
||||
type: 'audio/mpeg',
|
||||
mount: 'asteroid-low.mp3'
|
||||
}
|
||||
function getLiveStreamConfig(streamBaseUrl, quality) {
|
||||
const config = {
|
||||
aac: {
|
||||
url: `${streamBaseUrl}/asteroid.aac`,
|
||||
type: 'audio/aac',
|
||||
mount: 'asteroid.aac'
|
||||
},
|
||||
mp3: {
|
||||
url: `${streamBaseUrl}/asteroid.mp3`,
|
||||
type: 'audio/mpeg',
|
||||
mount: 'asteroid.mp3'
|
||||
},
|
||||
low: {
|
||||
url: `${streamBaseUrl}/asteroid-low.mp3`,
|
||||
type: 'audio/mpeg',
|
||||
mount: 'asteroid-low.mp3'
|
||||
}
|
||||
};
|
||||
|
||||
return config[quality];
|
||||
};
|
||||
|
||||
// Change live stream quality
|
||||
function changeLiveStreamQuality() {
|
||||
const streamBaseUrl = document.getElementById('stream-base-url');
|
||||
const selector = document.getElementById('live-stream-quality');
|
||||
const config = liveStreamConfig[selector.value];
|
||||
const config = getLiveStreamConfig(streamBaseUrl.value, selector.value);
|
||||
|
||||
// Update audio player
|
||||
const audioElement = document.getElementById('live-stream-audio');
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
<!-- Stream Quality Selector -->
|
||||
<div class="live-stream-quality">
|
||||
<input type="hidden" id="stream-base-url" lquery="(val stream-base-url)">
|
||||
<label for="stream-quality" ><strong>Quality:</strong></label>
|
||||
<select id="stream-quality" onchange="changeStreamQuality()">
|
||||
<option value="aac">AAC 96kbps (Recommended)</option>
|
||||
|
|
@ -45,12 +46,12 @@
|
|||
</select>
|
||||
</div>
|
||||
|
||||
<p><strong>Stream URL:</strong> <code id="stream-url">http://localhost:8000/asteroid.aac</code></p>
|
||||
<p><strong>Format:</strong> <span id="stream-format">AAC 96kbps Stereo</span></p>
|
||||
<p><strong>Stream URL:</strong> <code id="stream-url" lquery="(text default-stream-url)"></code></p>
|
||||
<p><strong>Format:</strong> <span id="stream-format" lquery="(text default-stream-encoding-desc)"></span></p>
|
||||
<p><strong>Status:</strong> <span id="stream-status" style="color: #00ff00;">● BROADCASTING</span></p>
|
||||
|
||||
<audio id="live-audio" controls style="width: 100%; margin: 10px 0;">
|
||||
<source id="audio-source" src="http://localhost:8000/asteroid.aac" type="audio/aac">
|
||||
<source id="audio-source" lquery="(attr :src default-stream-url :type default-stream-encoding)">
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
<div class="player-section">
|
||||
<h2 style="color: #00ff00;">🟢 Live Radio Stream</h2>
|
||||
<div class="live-stream">
|
||||
<input type="hidden" id="stream-base-url" lquery="(val stream-base-url)">
|
||||
<p><strong>Now Playing:</strong> <span id="live-now-playing">Loading...</span></p>
|
||||
<p><strong>Listeners:</strong> <span id="live-listeners">0</span></p>
|
||||
<!-- Stream Quality Selector -->
|
||||
|
|
@ -37,7 +38,7 @@
|
|||
</div>
|
||||
|
||||
<audio id="live-stream-audio" controls style="width: 100%; margin: 10px 0;">
|
||||
<source id="live-stream-source" src="http://localhost:8000/asteroid.aac" type="audio/aac">
|
||||
<source id="live-stream-source" lquery="(attr :src default-stream-url)" type="audio/aac">
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
<p><em>Listen to the live Asteroid Radio stream</em></p>
|
||||
|
|
|
|||
Loading…
Reference in New Issue