From 0ad0aa13fb385036766c81e55dcde89f2f754a01 Mon Sep 17 00:00:00 2001 From: Corwin Brust Date: Mon, 5 May 2025 21:13:00 -0500 Subject: [PATCH 01/10] add nginux icecast configuration --- icecast.nginx-sites-avaialble | 65 +++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 icecast.nginx-sites-avaialble diff --git a/icecast.nginx-sites-avaialble b/icecast.nginx-sites-avaialble new file mode 100644 index 0000000..bc41c63 --- /dev/null +++ b/icecast.nginx-sites-avaialble @@ -0,0 +1,65 @@ +server { + listen 80; + listen [::]:80; + server_name shred.ing; + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + location / { + proxy_pass http://localhost:8000/live.mp3; + } + location ~ play(er)?|html?$ { + root /www/shred.ing; + try_files $1 /shred.html =404; + # kill cache + add_header Last-Modified $date_gmt; + add_header Cache-Control 'no-store, no-cache'; + if_modified_since off; + expires off; + etag off; + } + location ~ js(on)?$ { + root /opt/shred.ing/js; + try_files $1 /title.json =404; + # kill cache + add_header Last-Modified $date_gmt; + add_header Cache-Control 'no-store, no-cache'; + if_modified_since off; + expires off; + etag off; + } +} + +server { + server_name shred.ing; + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + listen [::]:443 ssl; # managed by Certbot + listen 443 ssl; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/shred.ing/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/shred.ing/privkey.pem; # managed by Certbot + include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot + location / { + proxy_pass http://localhost:8000/live.mp3; + } + location ~ play(er)?|html?$ { + root /www/shred.ing; + try_files $1 /shred.html =404; + # kill cache + add_header Last-Modified $date_gmt; + add_header Cache-Control 'no-store, no-cache'; + if_modified_since off; + expires off; + etag off; + } + location ~ js(on)?$ { + root /opt/shred.ing/js; + try_files $1 /title.json =404; + # kill cache + add_header Last-Modified $date_gmt; + add_header Cache-Control 'no-store, no-cache'; + if_modified_since off; + expires off; + etag off; + } +} From 401ca965fc7994710b1697c37479d3ad0cd72515 Mon Sep 17 00:00:00 2001 From: corwin Date: Tue, 6 May 2025 04:15:11 +0200 Subject: [PATCH 02/10] correct garbeled text in placeholder readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5cd1316..2e999ee 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # shred.ing-server -Stuff to install on a (nominally) Ubuntu 24 host to create (e.g.) shred.ing to create an internet hosted radio station. \ No newline at end of file +Stuff to install on a (nominally) Ubuntu 24 host to create (e.g.) shred.ing, an internet hosted radio station. \ No newline at end of file From afbd9a182012f25f6a551d423f02e1acffe7d522 Mon Sep 17 00:00:00 2001 From: corwin Date: Tue, 6 May 2025 04:20:15 +0200 Subject: [PATCH 03/10] add TODO to readme --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2e999ee..3249b9e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ # shred.ing-server -Stuff to install on a (nominally) Ubuntu 24 host to create (e.g.) shred.ing, an internet hosted radio station. \ No newline at end of file +Stuff to install on a (nominally) Ubuntu 24 host to create (e.g.) shred.ing, an internet hosted radio station. + +# TODO + +[ ] fix issue where streams HTML player disconnects after an hour +[ ] create fallback streams to support switching casters +[ ] write a tutoral explain how to use the files in this repo to create a streaming radio station \ No newline at end of file From 437d3129e50e3032ba21174c600e5173e24f7ae5 Mon Sep 17 00:00:00 2001 From: Corwin Brust Date: Tue, 6 May 2025 17:49:10 -0500 Subject: [PATCH 04/10] fix self-inflicted 1h time-out issue; prep config gen The 1h timeout was caused by an express setting in the icecast mount. Other changes will make search and replace easier, thus scripting to create the icecast configuration from a script or settings file. --- icecast.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/icecast.xml b/icecast.xml index e03ecaf..a7be6b2 100644 --- a/icecast.xml +++ b/icecast.xml @@ -18,7 +18,7 @@ 524288 30 15 - 10 + 17 - shredsourcepassword + $shredsourcepassword$ - shredrelaypassword + $shredrelaypassword$ admin - shredadminpassword + $shredadminpassword$ 3600 live - shredlivepassword + $shredlivepassword$ From 130693884be06e364ba33ec50948a5abbb1165dc Mon Sep 17 00:00:00 2001 From: Corwin Brust Date: Tue, 6 May 2025 18:51:41 -0500 Subject: [PATCH 05/10] put stuff in the readme --- README.md | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3249b9e..4423a00 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,44 @@ # shred.ing-server -Stuff to install on a (nominally) Ubuntu 24 host to create (e.g.) shred.ing, an internet hosted radio station. +Stuff to install on a (nominally) Ubuntu 24 host to create (e.g.) shred.ing to create an internet hosted radio station. + # TODO -[ ] fix issue where streams HTML player disconnects after an hour -[ ] create fallback streams to support switching casters -[ ] write a tutoral explain how to use the files in this repo to create a streaming radio station \ No newline at end of file + - [ ] fix issue where streams HTML player disconnects after an hour + - [ ] create fallback streams to support switching casters + - [ ] write a tutoral explaining how to use the files in this repo to create a streaming radio station + + +# ABSTRACT + +Here you will hopefully find everything (aside hardware and content) that you need to get started self-hosting a radio-station. This guide (and the other files in this repository) are focused on creating an internet hosted station but they should work well (albe it, with some adaptions) for creating a station on a private network ("intranet"), too. + +This repository is intended to contain enough information to get started self-hosting an internet radio station. These same instructions should work fairly well for a intranet (private network) based station however some adaptions (such as skipping the "selecting a VPS provider" section) might be advisable. This setup can be a step toward broad-casting over "open" airwaves (however, this generally requires understanding local licesnsing and other applicable governance requirements, etc, which please as you may be inclined ). Additionally, these instructions (the software used here, specifically) should work well use with sophisticaed hardware (lots of analog and/or digital sources, etc.). That said, this is a "getting started" guide as well as instructions for useing the files in this repository. Patches welcome :) + +# DESIGN + +The radio station consists of two parts: the workstation, responsible for broadcasting to the server, and the server responsible for streaming the audio sigal to the devices of whomever may be listening. This repository includes most the configuration, HTML palyer, and other scripting needed for the server however the guild (this file!) contains some tips for working with Mixxx, the recommended broadcaster software. + +## workstation + +Although generally compatable in principle with a wide variety of software, the workstation setup required by this guild consists of a program (Mixxx, GPLv2+). Mixxx is available in the form of pre-compiled binaries for a variety of operating systems. + +## server + +The server is somewhat more complex, but ultimatly relies mainly on two programs (Icecast2, GPLv2; Nginx, BSD-2c): Icecast2 (GPLv2) which receives our mixed signal and streams it to listeners, and nginx (BSD-2c) which is a web-server which will "proxy" the MP3 stream produced by Icecast, not witstanding the underlying (nominally) Ubuntu 24 system software. Since this guide assumes we are building a internet facing server we also cover setting up ufw (a firewall program) and fail2ban (a nusance deturant toolkit), most in the form of explain how to use (and/or adapt!) the same filter rules in this repo. + +## summary + + * This file plus the contents of this repository, along with PC capable running some recent version of Ubuntu (nearly any PC), should be enough to get a simple network radio station online. + * This guild is covers the steps to aquire an virtual private server from internet provider and configure it to server your radio station on the internet. + * Alternately, these steps should work fairly well starting with old PC you might like to use to create an intranet station. + * This guild doesn't give a great deal of coverage to Mixxx (and none to other audio caster software): + * Get comfortable with Mixx (or the audio caster software of your choice) before building your own station. + * For example, be comforable playing and switching tracks, creating playlists, keying your mic, whatever you plan to do. + * This guide recommends Mixxx: install it and mess around! + * If you hate Mixxx good search terms could be "audiocaster software send to icecast2". + * There are some tips for getting started with Mixxx in the next section and elsewhere below. + +# Materials +>>>>>>> Stashed changes From 528fd7f6225608256de8ee13416b6c147af5102c Mon Sep 17 00:00:00 2001 From: Corwin Brust Date: Fri, 16 May 2025 22:57:44 -0500 Subject: [PATCH 06/10] read from playlist.log; avoid making the file empty --- icecast-title-service/icecast-track-title-to-javascript.sh | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 icecast-title-service/icecast-track-title-to-javascript.sh diff --git a/icecast-title-service/icecast-track-title-to-javascript.sh b/icecast-title-service/icecast-track-title-to-javascript.sh new file mode 100644 index 0000000..ee2919f --- /dev/null +++ b/icecast-title-service/icecast-track-title-to-javascript.sh @@ -0,0 +1,3 @@ +#!/usr/bin/bash + +tail -1 /var/log/icecast2/playlist.log | cut -d \| -f 4 | perl -nle 'printf qq({ "title" : "%s" }\n), $_' From 7b3f1768d202c9b2e8bbbe7f4ec6161fc8977212 Mon Sep 17 00:00:00 2001 From: corwin Date: Fri, 18 Jul 2025 23:09:42 +0200 Subject: [PATCH 07/10] Mark duration fix and multi-caster config tasks complete --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4423a00..27cf7ad 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ Stuff to install on a (nominally) Ubuntu 24 host to create (e.g.) shred.ing to c # TODO - - [ ] fix issue where streams HTML player disconnects after an hour - - [ ] create fallback streams to support switching casters + - [X] fix issue where streams HTML player disconnects after an hour + - [X] create fallback streams to support switching casters - [ ] write a tutoral explaining how to use the files in this repo to create a streaming radio station From 8f8bb57fd1ccaf8f70143fbadb3da979bcfd82c7 Mon Sep 17 00:00:00 2001 From: Corwin Brust Date: Sat, 19 Jul 2025 18:59:40 -0500 Subject: [PATCH 08/10] add Makefile to guide configuration and perform installation This change replaces icecast.xml with icecast.xml.template. A complete icecast.xml is no-longer provided. Instead, to create icecast.xml run: make You can generate icecast.xml and then install it: make install This doesn't currently do any aspectss of making the system ready to run icecast (e.g. performing `sudo apt install icecast2`, or similar). --- Makefile | 83 ++++++++++ README.md | 9 +- icecast.xml => icecast.xml.template | 248 +++++++++++++++++----------- 3 files changed, 245 insertions(+), 95 deletions(-) create mode 100644 Makefile rename icecast.xml => icecast.xml.template (53%) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ade15ed --- /dev/null +++ b/Makefile @@ -0,0 +1,83 @@ +# Makefile for shred.ing + +# make (default, or with: make config) +# prompt for settings unless .env file exists +# create ~/icecast.xml +# make install +# backup the live config to ~/icecast.xml +# install ~/icecast.xml to /etc/icecast2 + +# not currently used for anything +## make sure to change these +#source_pass := password_to_share_with_casters +#relay_pass := password_for_icecast2_relays +#admin_user := admin_web_and_api_username +#admin_pass := password_for_admin_access +## probably want to change this +#hostname := shred.ing + +# the "prompt" port can be left blank so +# this can be left at default +icecast2_port := 8000 + +## +## More or less internal stuffs +## +default_config_template := icecast.xml.template +ICECAST_CONFIG_TEMPLATE := $(ICECAST_CONFIG_TEMPLATE) +#ICECAST_CONFIG_TEMPLATE != [ -z "$(ICECAST_CONFIG_TEMPLATE)" ] || echo "$(default_config_template)" + +#ICECAST_CONFIG_TEMPLATE := icecast.xml.template.foo + +## generate configuration files for icecast2 + +# these targets aren't associated with files +.PHONEY: config backup-live-config install + +## main "entry point" makefile targets +config: icecast.xml .env + +backup-live-config: + sudo test -r /etc/icecast2/icecast.xml && sudo cp /etc/icecast2/icecast.xml icecast.xml~~ + +install: config backup-live-config + sudo cp icecast.xml /etc/icecast2/icecast.xml.new + +# this will prompt to build a .env file when none exists +.env: + @echo "You will receive a series of prompts to create a .env file." + @echo + @printf "Enter your icecast hostname (or IP): " + @printf "hostname=%s\n" `read i; echo $$i` >.env + @printf "Enter the port for your icecast server ($(icecast2_port)): " + @printf "icecast2_port=%s\n" "$$( i=`read i; echo $$i`; printf "%s" $$( if test -z "$$i" ; then echo "$(icecast2_port)"; else echo "$$i" ; fi ) )" >>.env + @echo "Icecast requires, potentially, several passwords." + @echo "Passwords entered now are echoed to the screen." + @echo "You can pick bogus values and then edit the .env file." + @printf "Enter a source password: " + @printf "source_pass=%s\n" `read i; echo $$i` >>.env + @printf "Enter a relay password: " + @printf "relay_pass=%s\n" `read i; echo $$i` >>.env + @printf "Enter an admin password: " + @printf "admin_pass=%s\n" `read i; echo $$i` >>.env + @echo "Finally, select a username for the admin account:" + @printf "Enter the icecast admin username: " + @printf "admin_user=%s\n" `read i; echo $$i` >>.env + +# this ensures the template icecast config exists +$(ICECAST_CONFIG_TEMPLATE): + @printf "The icecast2 configuration file template "'"'"%s"'"'"\n" "$(ICECAST_CONFIG_TEMPLATE)" + @printf "is missing or cannot be read.\n" + @echo "This can be caused by an incomplete or corrupted checkout or" + @echo "an invalid value for the ICECAST_CONFIG_TEMPLATE env variable." + false + + +### given we have a template and a .env, create the icecast config +icecast.xml: $(ICECAST_CONFIG_TEMPLATE) .env + perl -e 'BEGIN{open my$$FH,q(<),q(.env) or die $$!; for(<$$FH>){ chomp; my($$k,$$v) = split q(=); next unless $$k; $$k =~ s/^\s+|\s+$$//g; next unless $$k; $$v =~ s/^\s+|\s+//g; $$h{lc $$k} = $$v; }}' -pe 's/\@\@([^@]+)\@\@/$$h{lc $$1}/eig;' >icecast.xml <$(ICECAST_CONFIG_TEMPLATE) + +# this seems to work, too! +# cat icecast.xml.template | perl -pe 's/\@\@source_pass\@\@/$(source_pass)/ig; s/\@\@relay_pass\@\@/$(relay_pass)/ig; s/\@\@admin_user\@\@/$(admin_user)/ig; s/\@\@admin_pass\@\@/$(admin_pass)/ig; s/\@\@hostname\@\@/$(hostname)/ig; s/\@\@icecast2_port\@\@/$(icecast2_port)/ig;' > icecast.xml +# probably, so does this? +# cat icecast.xml.template | perl -e 'BEGIN{open my$FH,q(<),q(.env) or die $!; for(<$FH>){ chomp; my($k,$v) = split q(=); next unless $k; $k =~ s/^\s+|\s+$//g; next unless $k; $v =~ s/^\s+|\s+//g; $h{lc $k} = $v; }}' -pe 's/\@\@([^@]+)\@\@/$h{lc $1}/eig;' -e 'END { use Data::Dumper; warn Dumper( \%h ) } ' > foo.xml diff --git a/README.md b/README.md index 27cf7ad..a098826 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,15 @@ Stuff to install on a (nominally) Ubuntu 24 host to create (e.g.) shred.ing to c - [X] fix issue where streams HTML player disconnects after an hour - [X] create fallback streams to support switching casters - - [ ] write a tutoral explaining how to use the files in this repo to create a streaming radio station + - [-] build guided installer + - [ ] write a tutoral +# Quick Start + + git clone https://code.bru.st/corwin/shred.ing-server.git + apt-get install icecast2 + make install + links localhost:8000 # ABSTRACT diff --git a/icecast.xml b/icecast.xml.template similarity index 53% rename from icecast.xml rename to icecast.xml.template index a7be6b2..a2d0939 100644 --- a/icecast.xml +++ b/icecast.xml.template @@ -1,55 +1,36 @@ - - Earth - icemaster@localhost - - - + The Island of Misfit Toys + yo@mammy - 100 - 2 + 17q000 + 17 524288 30 15 17 - - 1 + - 65535 + - $shredsourcepassword$ + @@Source_Pass@@ - $shredrelaypassword$ - + @@Relay_Pass@@ - admin - $shredadminpassword$ + @@Admin_User@@ + @@Admin_Pass@@ - - - - - shred.ing - - + @@hostname@@ - 8000 - - + @@icecast2_port@@ - - - -
+
@@ -103,12 +57,10 @@ - - - - - 0 - 3600 + live - $shredlivepassword$ - - - -
- + @@Source_Pass@@ + 1 + /live - - - - - + + 0 + /live.ogg + live + @@Source_Pass@@ + 1 + /gold.ogg + + + 0 + /gold.ogg + 1 + /purple.ogg + live + @@Source_Pass@@ + + + 0 + /purple.ogg + 1 + /black.ogg + live + @@Source_Pass@@ + + + 0 + /black.ogg + 1 + /silver.ogg + live + @@Source_Pass@@ + + + 0 + + + /silver.ogg + 1 + /live.ogg + live + @@Source_Pass@@ + - - - - - + + 0 + 1 + /live + live + @@Source_Pass@@ + 1 + /live.mp3 + + + 0 + /live.mp3 + live + @@Source_Pass@@ + 1 + /gold + + + + 0 + /gold + 1 + /gold.mp3 + live + @@Source_Pass@@ + + + 0 + /gold.mp3 + 1 + /gold.ogg + live + @@Source_Pass@@ + + + + 0 + /purple + 1 + /purple.mp3 + live + @@Source_Pass@@ + + + 0 + /purple.mp3 + 1 + /black + live + @@Source_Pass@@ + + + + 0 + + + /black + 1 + /black.mp3 + live + @@Source_Pass@@ + + + 0 + /black.mp3 + 1 + /silver + live + @@Source_Pass@@ + + + + 0 + + + /silver + 1 + /silver.mp3 + live + @@Source_Pass@@ + + + 0 + /silver.mp3 + 1 + /live + live + @@Source_Pass@@ + - /usr/share/icecast2 - - /var/log/icecast2 /usr/share/icecast2/web /usr/share/icecast2/admin - + playlist.log 3 10000