From 21b051177dc5897d239e6532f5f245a32f7dfb36 Mon Sep 17 00:00:00 2001 From: Sacha Chua Date: Thu, 20 Oct 2022 14:52:23 -0400 Subject: Starting point for icecast config --- README.org | 13 + common-playbook.yml | 6 + group_vars/all.yml | 6 + inventory.yml | 6 + roles/stream/defaults/main.yml | 2 + roles/stream/tasks/main.yml | 52 ++++ roles/stream/templates/emacsconf.nginx.conf | 18 ++ roles/stream/templates/icecast-emacsconf.init.d | 78 ++++++ roles/stream/templates/icecast-emacsconf.service | 17 ++ roles/stream/templates/icecast.xml | 300 +++++++++++++++++++++++ 10 files changed, 498 insertions(+) create mode 100644 group_vars/all.yml create mode 100644 roles/stream/defaults/main.yml create mode 100644 roles/stream/tasks/main.yml create mode 100644 roles/stream/templates/emacsconf.nginx.conf create mode 100755 roles/stream/templates/icecast-emacsconf.init.d create mode 100644 roles/stream/templates/icecast-emacsconf.service create mode 100644 roles/stream/templates/icecast.xml diff --git a/README.org b/README.org index 31c926b..3645b04 100644 --- a/README.org +++ b/README.org @@ -142,3 +142,16 @@ ansible-playbook -i inventory.yml prod-playbook.yml --tags proxy --extra-vars='{ /ssh:media|sudo:upload@media:~upload /ssh:media|sudo::/etc/nginx/sites-available +* Stream + +Setting up icecast: + +ansible-playbook -i inventory.yml prod-playbook.yml --tags stream + +Test with a file: + +ansible-playbook -i inventory.yml prod-playbook.yml --tags test-stream-file -e icecast_test=~/code/emacsconf-2021-emacs-news-highlights/full.webm -e icecast_test_track=dev + +Play the stream with MPV: + +ansible-playbook -i inventory.yml prod-playbook.yml --tags test-stream-mpv -e icecast_test_track=dev diff --git a/common-playbook.yml b/common-playbook.yml index 815aac4..819db36 100644 --- a/common-playbook.yml +++ b/common-playbook.yml @@ -29,3 +29,9 @@ roles: - upload +- name: Set up icecast server for streaming + hosts: stream + tags: stream + roles: + - stream + diff --git a/group_vars/all.yml b/group_vars/all.yml new file mode 100644 index 0000000..bc8f39a --- /dev/null +++ b/group_vars/all.yml @@ -0,0 +1,6 @@ +docker: false +emacsconf_tracks: + - name: General + id: gen + - name: Development + id: dev diff --git a/inventory.yml b/inventory.yml index 7f80dae..8dfee04 100644 --- a/inventory.yml +++ b/inventory.yml @@ -24,6 +24,12 @@ prod: ansible_ssh_user: orga ansible_python_interpreter: /usr/bin/python3 ansible_become: true + stream: + ansible_host: live0.emacsconf.org + remote_user: orga + ansible_ssh_user: orga + ansible_python_interpreter: /usr/bin/python3 + ansible_become: true all: hosts: localhost: diff --git a/roles/stream/defaults/main.yml b/roles/stream/defaults/main.yml new file mode 100644 index 0000000..cd8984f --- /dev/null +++ b/roles/stream/defaults/main.yml @@ -0,0 +1,2 @@ +icecast_admin_email: emacsconf-org@gnu.org +icecast_port: 8001 diff --git a/roles/stream/tasks/main.yml b/roles/stream/tasks/main.yml new file mode 100644 index 0000000..73040d6 --- /dev/null +++ b/roles/stream/tasks/main.yml @@ -0,0 +1,52 @@ +- name: Install Icecast + become: true + package: + name: icecast2 + state: present +- name: Set up config + become: true + template: + src: icecast.xml + dest: /etc/icecast2/icecast-emacsconf.xml +- name: Set up init file + become: true + template: + src: icecast-emacsconf.init.d + dest: /etc/init.d/emacsconf + mode: 0755 +- name: Set up nginx config + become: true + template: + src: emacsconf.nginx.conf + dest: /etc/nginx/emacsconf.nginx.conf + mode: 0644 +- name: Enable icecast + become: true + sysvinit: + name: emacsconf + enabled: yes + state: started +- name: Check if icecast is listening + wait_for: + port: "{{ icecast_port }}" + delay: 5 + timeout: 10 + msg: "Timeout waiting for {{ icecast_port }} to respond" + register: port_check + ignore_errors: yes +- name: Try to restart icecast if not started + service: name=emacsconf state=started enabled=yes + when: port_check.failed == true +- name: Test by streaming from a file + tags: test-stream-file, never + local_action: shell ffmpeg -loglevel 32 -i {{ icecast_test }} -cluster_size_limit 2M -cluster_time_limit 5100 -content_type video/webm -c:v libvpx -b:v 1M -crf 30 -g 125 -deadline good -threads 4 -f webm icecast://emacsconf:{{ icecast_emacsconf_password }}@live0.emacsconf.org:{{ icecast_port }}/emacsconf/{{ icecast_test_track|d("gen") }}.webm + when: icecast_test is defined +- name: Test by displaying the stream in mpv + tags: test-stream-mpv, never + local_action: shell mpv http://live0.emacsconf.org:{{ icecast_port }}/emacsconf/{{ icecast_test_track|d(gen) }}.webm +# - name: Set up restream script +# template: +# src: restream-yt.sh +# dest: /home/orga/restream-yt.sh +# owner: orga +# mode: 0755 diff --git a/roles/stream/templates/emacsconf.nginx.conf b/roles/stream/templates/emacsconf.nginx.conf new file mode 100644 index 0000000..235a661 --- /dev/null +++ b/roles/stream/templates/emacsconf.nginx.conf @@ -0,0 +1,18 @@ +location /emacsconf { + try_files $uri $uri/ @emacsconf_upstream; + } + location @emacsconf_upstream { + proxy_pass http://localhost:{{ icecast_port }}; + proxy_http_version 1.1; + proxy_buffering off; + proxy_request_buffering off; + proxy_set_header Host $http_host; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Real-IP $remote_addr; + } + \ No newline at end of file diff --git a/roles/stream/templates/icecast-emacsconf.init.d b/roles/stream/templates/icecast-emacsconf.init.d new file mode 100755 index 0000000..b3ad491 --- /dev/null +++ b/roles/stream/templates/icecast-emacsconf.init.d @@ -0,0 +1,78 @@ +#! /bin/sh +### BEGIN INIT INFO +# Provides: icecast2 +# Required-Start: $remote_fs $network +# Required-Stop: $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Icecast2 streaming media server +# Description: Starts the icecast audio streaming server daemon +### END INIT INFO +# +# icecast2 +# +# Written by Miquel van Smoorenburg . +# Modified for Debian +# by Ian Murdock . +# +# Further modified by Keegan Quinn +# for use with Icecast 2 +# + +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin +DAEMON=/usr/bin/icecast2 +NAME=icecast2-emacsconf +DESC="streaming media server" + +test -x $DAEMON || exit 0 + +. /lib/lsb/init-functions + +# Defaults +CONFIGFILE="/etc/icecast2/icecast-emacsconf.xml" +CONFIGDEFAULTFILE="/etc/default/icecast2" +USERID=icecast2 +GROUPID=icecast +PIDFILE=/var/run/icecast-emacsconf + +# Reads config file (will override defaults above) +[ -r "$CONFIGDEFAULTFILE" ] && . $CONFIGDEFAULTFILE + +set -e + +case "$1" in + start) + log_daemon_msg "Starting $DESC" "$NAME" + start-stop-daemon --start --quiet --chuid $USERID:$GROUPID \ + --exec $DAEMON --pidfile $PIDFILE -- -b -c $CONFIGFILE > /dev/null + log_end_msg $? + ;; + stop) + log_daemon_msg "Stopping $DESC" "$NAME" + # Send TERM after 5 seconds, wait at most 30 seconds. + start-stop-daemon --stop --oknodo --retry TERM/5/0/30 --quiet --pidfile $PIDFILE --exec $DAEMON + log_end_msg $? + ;; + reload|force-reload) + log_daemon_msg "Reloading $DESC configuration" "$NAME" + start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --exec $DAEMON + log_end_msg $? + ;; + restart) + log_daemon_msg "Restarting $DESC" "$NAME" + # Send TERM after 5 seconds, wait at most 30 seconds. + start-stop-daemon --stop --oknodo --pidfile $PIDFILE --retry TERM/5/0/30 --quiet --exec $DAEMON + start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $USERID:$GROUPID \ + --exec $DAEMON -- -b -c $CONFIGFILE > /dev/null + log_end_msg $? + ;; + status) + status_of_proc -p $PID_FILE "$DAEMON" "$NAME" && exit 0 || exit $? + ;; + *) + echo "Usage: $0 {start|stop|restart|reload|force-reload}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/roles/stream/templates/icecast-emacsconf.service b/roles/stream/templates/icecast-emacsconf.service new file mode 100644 index 0000000..a78f69b --- /dev/null +++ b/roles/stream/templates/icecast-emacsconf.service @@ -0,0 +1,17 @@ +# {{ ansible_managed }} + +[Unit] +Description=Icecast with EmacsConf config +After=syslog.target network.target + +[Service] +Type=simple +User={{ icecast_user }} +Group={{ icecast_group }} +WorkingDirectory={{ etherpad_path }} +ExecStart=node {{ etherpad_path }}/node_modules/ep_etherpad-lite/node/server.js +Environment=NODE_ENV=production +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/roles/stream/templates/icecast.xml b/roles/stream/templates/icecast.xml new file mode 100644 index 0000000..d2bb89c --- /dev/null +++ b/roles/stream/templates/icecast.xml @@ -0,0 +1,300 @@ + + + + Earth + {{ icecast_admin_email }} + + + + + 10000 + 10 + 524288 + 30 + 15 + 10 + + 1 + + 65535 + + + + + {{ icecast_source_password }} + + {{ icecast_relay_password }} + + + admin + {{ icecast_admin_password }} + + + + + + + + + {{ icecast_hostname }} + + + + {{ icecast_port }} + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + {% for track in emacsconf_tracks %} + + /emacsconf/{{ track.id }}.webm + emacsconf + {{ icecast_emacsconf_password }} + /data/emacsconf-{{ emacsconf_year }}-{{ track.id }}_%Y-%m-%d_%H-%M-%S.webm + EmacsConf {{ emacsconf_year }} - {{ track.name }} track + The livestream for the {{ track.name }} track of EmacsConf {{ emacsconf_year }} + https://emacsconf.org/{{ emacsconf_year }}/watch/{{ track.id }}/ + video/webm + 1 + + + /emacsconf/{{ track.id }}-host.webm + emacsconf + {{ icecast_emacsconf_password }} + EmacsConf {{ emacsconf_year }} - {{ track.name }} track + The host stream for the {{ track.name }} track of EmacsConf {{ emacsconf_year }} + https://emacsconf.org/{{ emacsconf_year }}/watch/{{ track.id }}/ + video/webm + 1 + 1 + + + /emacsconf/{{ track.id }}-480p.webm + emacsconf + {{ icecast_emacsconf_password }} + EmacsConf {{ emacsconf_year }} - {{ track.name }} track (480p) + The 480p livestream for the {{ track.name }} track of EmacsConf {{ emacsconf_year }} + https://emacsconf.org/{{ emacsconf_year }}/watch/{{ track.id }}/ + video/webm + 1 + + {% endfor %} + {% if icecast_mounts is defined %} + {% for mount in icecast_mounts %} + + {{ mount.name }} + {{ mount.username }} + {{ mount.password }} + {% if mount.dump_file is defined %} + {{ mount.dump_file }} + {% endif %} + {{ mount.stream_name }} + {{ mount.stream_description }} + {% if mount.stream_url is defined %} + {{ mount.stream_url }} + {% endif %} + {{ mount.type }} + {% if mount.public is defined %} + {{ mount.public }} + {% endif %} + {% if mount.hidden is defined %} + {{ mount.hidden }} + {% endif %} + + {% endfor %} + {% endif %} + 1 + + + + /usr/share/icecast2 + + + /var/log/icecast2 + /usr/share/icecast2/web + /usr/share/icecast2/admin + + + + + + + + + + + access.log + error.log + + 3 + 10000 + + + + + + 0 + + icecast2 + icecast + + + -- cgit v1.2.3