diff options
Diffstat (limited to '')
-rw-r--r-- | roles/stream/defaults/main.yml | 2 | ||||
-rw-r--r-- | roles/stream/tasks/main.yml | 52 | ||||
-rw-r--r-- | roles/stream/templates/emacsconf.nginx.conf | 18 | ||||
-rwxr-xr-x | roles/stream/templates/icecast-emacsconf.init.d | 78 | ||||
-rw-r--r-- | roles/stream/templates/icecast-emacsconf.service | 17 | ||||
-rw-r--r-- | roles/stream/templates/icecast.xml | 300 |
6 files changed, 467 insertions, 0 deletions
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 <miquels@cistron.nl>. +# Modified for Debian +# by Ian Murdock <imurdock@gnu.ai.mit.edu>. +# +# Further modified by Keegan Quinn <ice@thebasement.org> +# 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 @@ +<!-- {{ ansible_managed }} --> +<icecast> + <!-- location and admin are two arbitrary strings that are e.g. visible + on the server info page of the icecast web interface + (server_version.xsl). --> + <location>Earth</location> + <admin>{{ icecast_admin_email }}</admin> + + <!-- IMPORTANT! + Especially for inexperienced users: + Start out by ONLY changing all passwords and restarting Icecast. + For detailed setup instructions please refer to the documentation. + It's also available here: http://icecast.org/docs/ + --> + + <limits> + <clients>10000</clients> + <sources>10</sources> + <queue-size>524288</queue-size> + <client-timeout>30</client-timeout> + <header-timeout>15</header-timeout> + <source-timeout>10</source-timeout> + <!-- If enabled, this will provide a burst of data when a client + first connects, thereby significantly reducing the startup + time for listeners that do substantial buffering. However, + it also significantly increases latency between the source + client and listening client. For low-latency setups, you + might want to disable this. --> + <burst-on-connect>1</burst-on-connect> + <!-- same as burst-on-connect, but this allows for being more + specific on how much to burst. Most people won't need to + change from the default 64k. Applies to all mountpoints --> + <burst-size>65535</burst-size> + </limits> + + <authentication> + <!-- Sources log in with username 'source' --> + <source-password>{{ icecast_source_password }}</source-password> + <!-- Relays log in with username 'relay' --> + <relay-password>{{ icecast_relay_password }}</relay-password> + + <!-- Admin logs in with the username given below --> + <admin-user>admin</admin-user> + <admin-password>{{ icecast_admin_password }}</admin-password> + </authentication> + + <!-- set the mountpoint for a shoutcast source to use, the default if not + specified is /stream but you can change it here if an alternative is + wanted or an extension is required + <shoutcast-mount>/live.nsv</shoutcast-mount> + --> + + <!-- Uncomment this if you want directory listings --> + <!-- + <directory> + <yp-url-timeout>15</yp-url-timeout> + <yp-url>http://dir.xiph.org/cgi-bin/yp-cgi</yp-url> + </directory> + --> + + <!-- This is the hostname other people will use to connect to your server. + It affects mainly the urls generated by Icecast for playlists and yp + listings. You MUST configure it properly for YP listings to work! + --> + <hostname>{{ icecast_hostname }}</hostname> + + <!-- You may have multiple <listen-socket> elements --> + <listen-socket> + <port>{{ icecast_port }}</port> + <!-- <bind-address>127.0.0.1</bind-address> --> + <!-- <shoutcast-mount>/stream</shoutcast-mount> --> + </listen-socket> + <!-- + <listen-socket> + <port>8080</port> + </listen-socket> + --> + <!-- + <listen-socket> + <port>8443</port> + <ssl>1</ssl> + </listen-socket> + --> + + + <!-- Global header settings + Headers defined here will be returned for every HTTP request to Icecast. + + The ACAO header makes Icecast public content/API by default + This will make streams easier embeddable (some HTML5 functionality needs it). + Also it allows direct access to e.g. /status-json.xsl from other sites. + If you don't want this, comment out the following line or read up on CORS. + --> + <http-headers> + <header name="Access-Control-Allow-Origin" value="*" /> + </http-headers> + + + <!-- Relaying + You don't need this if you only have one server. + Please refer to the documentation for a detailed explanation. + --> + <!--<master-server>127.0.0.1</master-server>--> + <!--<master-server-port>8001</master-server-port>--> + <!--<master-update-interval>120</master-update-interval>--> + <!--<master-password>hackme</master-password>--> + + <!-- setting this makes all relays on-demand unless overridden, this is + useful for master relays which do not have <relay> definitions here. + The default is 0 --> + <!--<relays-on-demand>1</relays-on-demand>--> + + <!-- + <relay> + <server>127.0.0.1</server> + <port>8080</port> + <mount>/example.ogg</mount> + <local-mount>/different.ogg</local-mount> + <on-demand>0</on-demand> + + <relay-shoutcast-metadata>0</relay-shoutcast-metadata> + </relay> + --> + + + <!-- Mountpoints + Only define <mount> sections if you want to use advanced options, + like alternative usernames or passwords + --> + + <!-- Default settings for all mounts that don't have a specific <mount type="normal">. + --> + <!-- + <mount type="default"> + <public>0</public> + <intro>/server-wide-intro.ogg</intro> + <max-listener-duration>3600</max-listener-duration> + <authentication type="url"> + <option name="mount_add" value="http://auth.example.org/stream_start.php"/> + </authentication> + <http-headers> + <header name="foo" value="bar" /> + </http-headers> + </mount> + --> + + <!-- Normal mounts --> + <!-- + <mount type="normal"> + <mount-name>/example-complex.ogg</mount-name> + + <username>othersource</username> + <password>hackmemore</password> + + <max-listeners>1</max-listeners> + <dump-file>/tmp/dump-example1.ogg</dump-file> + <burst-size>65536</burst-size> + <fallback-mount>/example2.ogg</fallback-mount> + <fallback-override>1</fallback-override> + <fallback-when-full>1</fallback-when-full> + <intro>/example_intro.ogg</intro> + <hidden>1</hidden> + <public>1</public> + <authentication type="htpasswd"> + <option name="filename" value="myauth"/> + <option name="allow_duplicate_users" value="0"/> + </authentication> + <http-headers> + <header name="Access-Control-Allow-Origin" value="http://webplayer.example.org" /> + <header name="baz" value="quux" /> + </http-headers> + <on-connect>/home/icecast/bin/stream-start</on-connect> + <on-disconnect>/home/icecast/bin/stream-stop</on-disconnect> + </mount> + --> + + <!-- + <mount type="normal"> + <mount-name>/auth_example.ogg</mount-name> + <authentication type="url"> + <option name="mount_add" value="http://myauthserver.net/notify_mount.php"/> + <option name="mount_remove" value="http://myauthserver.net/notify_mount.php"/> + <option name="listener_add" value="http://myauthserver.net/notify_listener.php"/> + <option name="listener_remove" value="http://myauthserver.net/notify_listener.php"/> + <option name="headers" value="x-pragma,x-token"/> + <option name="header_prefix" value="ClientHeader."/> + </authentication> + </mount> + --> + {% for track in emacsconf_tracks %} + <mount type="normal"> + <mount-name>/emacsconf/{{ track.id }}.webm</mount-name> + <username>emacsconf</username> + <password>{{ icecast_emacsconf_password }}</password> + <dump-file>/data/emacsconf-{{ emacsconf_year }}-{{ track.id }}_%Y-%m-%d_%H-%M-%S.webm</dump-file> + <stream-name>EmacsConf {{ emacsconf_year }} - {{ track.name }} track</stream-name> + <stream-description>The livestream for the {{ track.name }} track of EmacsConf {{ emacsconf_year }}</stream-description> + <stream-url>https://emacsconf.org/{{ emacsconf_year }}/watch/{{ track.id }}/</stream-url> + <type>video/webm</type> + <public>1</public> + </mount> + <mount type="normal"> + <mount-name>/emacsconf/{{ track.id }}-host.webm</mount-name> + <username>emacsconf</username> + <password>{{ icecast_emacsconf_password }}</password> + <stream-name>EmacsConf {{ emacsconf_year }} - {{ track.name }} track</stream-name> + <stream-description>The host stream for the {{ track.name }} track of EmacsConf {{ emacsconf_year }}</stream-description> + <stream-url>https://emacsconf.org/{{ emacsconf_year }}/watch/{{ track.id }}/</stream-url> + <type>video/webm</type> + <public>1</public> + <hidden>1</hidden> + </mount> + <mount type="normal"> + <mount-name>/emacsconf/{{ track.id }}-480p.webm</mount-name> + <username>emacsconf</username> + <password>{{ icecast_emacsconf_password }}</password> + <stream-name>EmacsConf {{ emacsconf_year }} - {{ track.name }} track (480p)</stream-name> + <stream-description>The 480p livestream for the {{ track.name }} track of EmacsConf {{ emacsconf_year }}</stream-description> + <stream-url>https://emacsconf.org/{{ emacsconf_year }}/watch/{{ track.id }}/</stream-url> + <type>video/webm</type> + <public>1</public> + </mount> + {% endfor %} + {% if icecast_mounts is defined %} + {% for mount in icecast_mounts %} + <mount type="normal"> + <mount-name>{{ mount.name }}</mount-name> + <username>{{ mount.username }}</username> + <password>{{ mount.password }}</password> + {% if mount.dump_file is defined %} + <dump-file>{{ mount.dump_file }}</dump-file> + {% endif %} + <stream-name>{{ mount.stream_name }}</stream-name> + <stream-description>{{ mount.stream_description }}</stream-description> + {% if mount.stream_url is defined %} + <stream-url>{{ mount.stream_url }}</stream-url> + {% endif %} + <type>{{ mount.type }}</type> + {% if mount.public is defined %} + <public>{{ mount.public }}</public> + {% endif %} + {% if mount.hidden is defined %} + <hidden>{{ mount.hidden }}</hidden> + {% endif %} + </mount> + {% endfor %} + {% endif %} + <fileserve>1</fileserve> + + <paths> + <!-- basedir is only used if chroot is enabled --> + <basedir>/usr/share/icecast2</basedir> + + <!-- Note that if <chroot> is turned on below, these paths must both + be relative to the new root, not the original root --> + <logdir>/var/log/icecast2</logdir> + <webroot>/usr/share/icecast2/web</webroot> + <adminroot>/usr/share/icecast2/admin</adminroot> + <!-- <pidfile>/usr/share/icecast2/icecast.pid</pidfile> --> + + <!-- Aliases: treat requests for 'source' path as being for 'dest' path + May be made specific to a port or bound address using the "port" + and "bind-address" attributes. + --> + <!-- + <alias source="/foo" destination="/bar"/> + --> + <!-- Aliases: can also be used for simple redirections as well, + this example will redirect all requests for http://server:port/ to + the status page + --> + <alias source="/" destination="/status.xsl"/> + <!-- The certificate file needs to contain both public and private part. + Both should be PEM encoded. + <ssl-certificate>/usr/share/icecast2/icecast.pem</ssl-certificate> + --> + </paths> + + <logging> + <accesslog>access.log</accesslog> + <errorlog>error.log</errorlog> + <!-- <playlistlog>playlist.log</playlistlog> --> + <loglevel>3</loglevel> <!-- 4 Debug, 3 Info, 2 Warn, 1 Error --> + <logsize>10000</logsize> <!-- Max size of a logfile --> + <!-- If logarchive is enabled (1), then when logsize is reached + the logfile will be moved to [error|access|playlist].log.DATESTAMP, + otherwise it will be moved to [error|access|playlist].log.old. + Default is non-archive mode (i.e. overwrite) + --> + <!-- <logarchive>1</logarchive> --> + </logging> + + <security> + <chroot>0</chroot> + <changeowner> + <user>icecast2</user> + <group>icecast</group> + </changeowner> + </security> +</icecast> |