mirror of
https://github.com/mistergibson/radio.git
synced 2026-11-03 19:31:41 -08:00
bugfixes --> station.liq : workarounds for LiquidSoap 2.2.4-dev
This commit is contained in:
parent
dc53dd8673
commit
6c31b74d2f
4 changed files with 78 additions and 83 deletions
|
|
@ -192,7 +192,7 @@ chmod 664 "$STORAGE_ROOT/state/"*.db 2>/dev/null || true
|
|||
|
||||
# --- Cron entries (liquidsoap user's crontab already exists from package) -----
|
||||
CRON_FETCH="0 * * * * cd ${INSTALL_DIR} && ${INSTALL_DIR}/run_radio.sh fetch_podcasts.rb --fetch-all >> ${STORAGE_ROOT}/logs/fetch_cron.log 2>&1"
|
||||
CRON_UPDATE="30 * * * * cd ${INSTALL_DIR} && ${INSTALL_DIR}/run_radio.sh update_playlist.rb >> ${STORAGE_ROOT}/logs/update_cron.log 2>&1"
|
||||
CRON_UPDATE="30 * * * * cd ${INSTALL_DIR} && ${INSTALL_DIR}/run_radio.sh update_playlists.rb >> ${STORAGE_ROOT}/logs/update_cron.log 2>&1"
|
||||
|
||||
CURRENT_CRONTAB=$(crontab -u liquidsoap -l 2>/dev/null || true)
|
||||
NEW_CRONTAB="${CURRENT_CRONTAB}"
|
||||
|
|
|
|||
16
schedule.txt
16
schedule.txt
|
|
@ -6,3 +6,19 @@
|
|||
# Examples:
|
||||
# 0 8 * * 2 show hardcore_history
|
||||
# 0 6 * * 1 stream http://example.org:8000/live.mp3 3600
|
||||
# ################################################################### Daily
|
||||
# KOPB --> BBC News & Local (Midnight to 7am)
|
||||
0 0 * * 1-7 stream http://stream1.opb.org/radio.mp3 25200
|
||||
# History of Rome (Noon to 1pm)
|
||||
0 12 * * 1-7 show the_history_of_rome
|
||||
# ################################################################### Weekdays
|
||||
# UpFront KPFA
|
||||
0 7 * * 1-5 stream https://streams.kpfa.org:8443/kpfa 3600
|
||||
# Bradcast
|
||||
0 8 * * 1-5 show the_bradcast_w_brad_friedman
|
||||
# Hardknock Radio KPFA
|
||||
0 16 * * 1-5 stream https://streams.kpfa.org:8443/kpfa 3600
|
||||
# Flashpoints KPFA
|
||||
0 17 * * 1-5 stream https://streams.kpfa.org:8443/kpfa 3600
|
||||
# Evening News KPFA
|
||||
0 18 * * 1-5 stream https://streams.kpfa.org:8443/kpfa 3600
|
||||
|
|
|
|||
122
station.liq
122
station.liq
|
|
@ -1,85 +1,63 @@
|
|||
#!/usr/bin/env liquidsoap
|
||||
# station.liq - Cascadia Digital Collective Radio Automation
|
||||
# Liquidsoap 2.2.4-1+dev compatible
|
||||
# Run from /srv/radio so relative paths resolve correctly
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# station.liq - Liquidsoap configuration for radio automation
|
||||
# Written for Liquidsoap 2.2.x. Run from /srv/radio so that the
|
||||
# relative config.json path resolves correctly; media lives under
|
||||
# the storage path read from that file. Directory playlists scan
|
||||
# recursively for audio files automatically.
|
||||
#
|
||||
# JINGLE/ANNOUNCEMENT NOTE:
|
||||
# random() stalls when one branch is permanently down (empty dir).
|
||||
# Until jingles/announcements directories contain audio files,
|
||||
# they are excluded from the graph. Uncomment the relevant lines
|
||||
# below once you've added content to those folders.
|
||||
# ---------------------------------------------------------------
|
||||
settings.log.file.set(false)
|
||||
|
||||
set("log.stdout", true)
|
||||
set("log.level", 3)
|
||||
# --- Load config ---
|
||||
# Explicit type annotation required: without it, fields used only in #{...}
|
||||
# interpolations default to null (see liquidsoap json docs).
|
||||
let json.parse ({ storage, icecast = { host, port, mount, source_username, source_password } }
|
||||
: { storage: string,
|
||||
icecast: { host: string, port: int, mount: string,
|
||||
source_username: string, source_password: string } })
|
||||
= file.contents("config.json")
|
||||
|
||||
# --- Step 1: path to config.json (relative to working directory) ---
|
||||
let config_path = "config.json"
|
||||
storage_base = storage
|
||||
music_dir = "#{storage}/music"
|
||||
queue_dir = "#{storage}/queues"
|
||||
|
||||
# --- Step 2: read and parse the whole file with explicit types --
|
||||
let json.parse (cfg : {
|
||||
storage: string,
|
||||
icecast: {
|
||||
host: string,
|
||||
port: int,
|
||||
mount: string,
|
||||
username: string,
|
||||
password: string
|
||||
}
|
||||
}) = file.contents(config_path)
|
||||
icecast_host = host
|
||||
icecast_port = port
|
||||
icecast_mount = mount
|
||||
icecast_user = source_username
|
||||
icecast_pass = source_password
|
||||
|
||||
# --- Step 3: pull out the values we need ------------------------
|
||||
let storage = cfg.storage
|
||||
let ic_host = cfg.icecast.host
|
||||
let ic_port = cfg.icecast.port
|
||||
let ic_mount = cfg.icecast.mount
|
||||
let ic_username = cfg.icecast.username
|
||||
let ic_password = cfg.icecast.password
|
||||
print("Config loaded: storage=#{storage_base}, icecast=#{icecast_host}:#{icecast_port}#{icecast_mount}")
|
||||
|
||||
set("log.file.path", "#{storage}/logs/liquidsoap.log")
|
||||
# --- Background music playlist (loops forever by default) ---
|
||||
background_music = playlist(music_dir)
|
||||
|
||||
# --- Background music library (directory scanned recursively) --
|
||||
music_playlist =
|
||||
mksafe(playlist("#{storage}/music"))
|
||||
# --- Show queue source (reads current_queue.txt each tick) ---
|
||||
# In 2.2.x the callback must return a request (type ()->request), not null.
|
||||
# When the queue is empty we play a short synthesized tone so the source
|
||||
# stays up without needing an external file.
|
||||
def read_queue()
|
||||
qf = "#{queue_dir}/current_queue.txt"
|
||||
if file.exists(qf) and file.contents(qf) != "" then
|
||||
request.create(file.contents(qf))
|
||||
else
|
||||
request.create("synth:shape=sine,frequency=440.,duration=1.")
|
||||
end
|
||||
end
|
||||
|
||||
# --- Scheduled content: request queue fed by schedule.txt ------
|
||||
sched_queue = request.queue(id="scheduler")
|
||||
show_source = request.dynamic(prefetch=1, read_queue)
|
||||
|
||||
# --- Jingles / announcements (uncomment when dirs have content) ---
|
||||
# jingles_src =
|
||||
# mksafe(playlist("#{storage}/jingles"))
|
||||
#
|
||||
# announcements_src =
|
||||
# mksafe(playlist("#{storage}/announcements"))
|
||||
# --- Mux: show takes priority, fall back to background music ---
|
||||
main_out = mksafe(fallback([show_source, background_music]))
|
||||
|
||||
# --- Assemble the stream ---------------------------------------
|
||||
primary = fallback(track_sensitive=false, [sched_queue, music_playlist])
|
||||
|
||||
# When jingles are active, uncomment this and comment out the line below:
|
||||
# content = random(weights=[1, 8], [jingles_src, primary])
|
||||
content = primary
|
||||
|
||||
# When announcements are active, uncomment this and comment out the line below:
|
||||
# final_content = fallback(track_sensitive=false, [announcements_src, content])
|
||||
final_content = content
|
||||
|
||||
radio = normalize(final_content)
|
||||
|
||||
# --- Output to Icecast -----------------------------------------
|
||||
# --- Output to Icecast ---
|
||||
output.icecast(
|
||||
%mp3(bitrate=128, samplerate=44100, stereo=true),
|
||||
host=ic_host,
|
||||
port=ic_port,
|
||||
user=ic_username,
|
||||
password=ic_password,
|
||||
mount=ic_mount,
|
||||
name="Radio Station",
|
||||
description="Automated internet radio",
|
||||
genre="Various",
|
||||
%mp3(bitrate=128),
|
||||
host=icecast_host,
|
||||
port=icecast_port,
|
||||
user=icecast_user,
|
||||
password=icecast_pass,
|
||||
mount=icecast_mount,
|
||||
name="Road Unit Radio",
|
||||
description="Community radio automation",
|
||||
genre="various",
|
||||
url="",
|
||||
public=true,
|
||||
radio
|
||||
main_out
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
#!/usr/bin/env jruby
|
||||
Dir.chdir(File.expand_path(__dir__))
|
||||
exec("liquidsoap", File.expand_path("station.liq"))
|
||||
|
|
|
|||
Loading…
Reference in a new issue