mirror of
https://github.com/fergalmoran/dss.radio.git
synced 2025-12-22 01:37:58 +00:00
Initial deploy
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -91,3 +91,5 @@ docs/_build/
|
|||||||
|
|
||||||
# PyBuilder
|
# PyBuilder
|
||||||
target/
|
target/
|
||||||
|
|
||||||
|
config.ini
|
||||||
32
Dockerfile
32
Dockerfile
@@ -1,24 +1,24 @@
|
|||||||
FROM ubuntu:wily
|
FROM ubuntu:latest
|
||||||
MAINTAINER Fergal Moran "Ferg@lMoran.me"
|
MAINTAINER Fergal Moran <Ferg@lMoran.me>
|
||||||
ENV DEBIAN_FRONTEND noninteractive
|
|
||||||
|
|
||||||
RUN mkdir /code
|
RUN apt-get update -y
|
||||||
|
RUN apt-get upgrade -y
|
||||||
|
|
||||||
RUN apt-get -qq -y update && \
|
RUN apt-get install -y python-setuptools python-pip git pkg-config libshout3 libshout3-dev python-dev
|
||||||
apt-get -qq -y install icecast2 python-setuptools python-pip pkg-config git \
|
|
||||||
libcurl4-openssl-dev libshout3 libshout3-dev && \
|
|
||||||
apt-get clean
|
|
||||||
|
|
||||||
RUN easy_install supervisor && \
|
|
||||||
easy_install supervisor-stdout
|
|
||||||
|
|
||||||
|
RUN mkdir /code/
|
||||||
WORKDIR /code
|
WORKDIR /code
|
||||||
|
|
||||||
ADD requirements.txt /code/
|
ADD requirements.txt /code/
|
||||||
|
ADD server.py /code/
|
||||||
|
ADD ice_relay.py /code/
|
||||||
|
ADD static /code/static/
|
||||||
|
ADD templates /code/templates/
|
||||||
|
ADD dss.radio.conf /code/
|
||||||
|
|
||||||
ADD icecast2/icecast.xml /etc/icecast2/
|
# Install tornado
|
||||||
ADD default/icecast2 /etc/default/
|
|
||||||
ADD supervisord.conf /etc/supervisord.conf
|
|
||||||
|
|
||||||
RUN pip install -r requirements.txt
|
RUN pip install -r requirements.txt
|
||||||
RUN pip install git+https://github.com/fergalmoran/python-shout.git#python-shout --upgrade
|
|
||||||
|
|
||||||
|
EXPOSE 8888
|
||||||
|
|
||||||
|
CMD ["python", "server.py"]
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# Defaults for icecast2 initscript
|
|
||||||
# sourced by /etc/init.d/icecast2
|
|
||||||
# installed at /etc/default/icecast2 by the maintainer scripts
|
|
||||||
|
|
||||||
#
|
|
||||||
# This is a POSIX shell fragment
|
|
||||||
#
|
|
||||||
|
|
||||||
# Full path to the server configuration file
|
|
||||||
CONFIGFILE="/etc/icecast2/icecast.xml"
|
|
||||||
|
|
||||||
# Name or ID of the user and group the daemon should run under
|
|
||||||
USERID=icecast2
|
|
||||||
GROUPID=icecast
|
|
||||||
|
|
||||||
# Edit /etc/icecast2/icecast.xml and change at least the passwords.
|
|
||||||
# Change this to true when done to enable the init.d script
|
|
||||||
ENABLE=true
|
|
||||||
|
|
||||||
4
dss.radio.conf
Normal file
4
dss.radio.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
ice_password="RDzNlgqmj67vk"
|
||||||
|
ice_host="radio.deepsouthsounds.com"
|
||||||
|
ice_mount="/dss"
|
||||||
|
api_host="api.deepsouthsounds.com"
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
import shout
|
|
||||||
|
|
||||||
|
|
||||||
class IceClient(object):
|
|
||||||
def __init__(self, host, port, user, password, mount, format, protocol):
|
|
||||||
|
|
||||||
self.s = shout.Shout()
|
|
||||||
print "Using libshout version {}".format(shout.version())
|
|
||||||
|
|
||||||
self.s.host = host
|
|
||||||
self.s.port = port
|
|
||||||
self.s.user = user
|
|
||||||
self.s.password = password
|
|
||||||
self.s.mount = mount
|
|
||||||
self.s.format = format
|
|
||||||
self.s.protocol = protocol
|
|
||||||
self.s.open()
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
self.s.close()
|
|
||||||
|
|
||||||
"""
|
|
||||||
if __name__ == '__main__':
|
|
||||||
streamer = IceClient(
|
|
||||||
host='niles',
|
|
||||||
port=8999,
|
|
||||||
user='source',
|
|
||||||
password='hackme',
|
|
||||||
mount="/pyshout",
|
|
||||||
format='mp3',
|
|
||||||
protocol='http'
|
|
||||||
)
|
|
||||||
streamer.play_audio(['/home/fergalm/Dropbox/BT_The_Moment_of_Truth.mp3'])
|
|
||||||
"""
|
|
||||||
146
ice_relay.py
146
ice_relay.py
@@ -1,61 +1,155 @@
|
|||||||
|
import logging
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import time
|
import time
|
||||||
from deefuzzer import Player
|
import urllib
|
||||||
|
import shout
|
||||||
|
import urllib2
|
||||||
|
import requests
|
||||||
|
|
||||||
BUF_LEN = 4096
|
BUF_LEN = 4096
|
||||||
|
|
||||||
|
|
||||||
class IceRelay(Thread):
|
class IceRelay(Thread):
|
||||||
def __init__(self, client, title='DeepSouthSounds Radio'):
|
server_ping = False
|
||||||
|
|
||||||
|
def __init__(self, options, mountpoint='dss', title='DeepSouthSounds Radio'):
|
||||||
super(IceRelay, self).__init__()
|
super(IceRelay, self).__init__()
|
||||||
self.title = title
|
self.title = title
|
||||||
self.s = client
|
|
||||||
self._ended = True
|
self._ended = True
|
||||||
self.player = Player("icecast")
|
|
||||||
self.isOpen = True
|
self.isOpen = True
|
||||||
self.audio_queue = []
|
self.audio_queue = []
|
||||||
self.audio_index = 0
|
self.audio_index = 0
|
||||||
|
|
||||||
self.default_queue = [
|
self.channelIsOpen = False
|
||||||
'https://dsscdn.blob.core.windows.net/mixes/7568d3a4-9a9f-4f0f-a900-f84231c26c47.mp3'
|
|
||||||
]
|
|
||||||
|
|
||||||
def stop(self):
|
self.options = options
|
||||||
|
|
||||||
|
self.channel = shout.Shout()
|
||||||
|
self.channel.mount = '/' + mountpoint
|
||||||
|
|
||||||
|
self.api_host = options['api_host']
|
||||||
|
self.channel.url = 'http://deepsouthsounds.com/'
|
||||||
|
self.channel.name = title
|
||||||
|
self.channel.genre = 'Deep House Music'
|
||||||
|
self.channel.description = 'Deep sounds from the deep south'
|
||||||
|
self.channel.format = options['ice_format']
|
||||||
|
self.channel.host = options['ice_host']
|
||||||
|
self.channel.port = int(options['ice_port'])
|
||||||
|
self.channel.user = options['ice_user']
|
||||||
|
self.channel.password = options['ice_password']
|
||||||
|
self.channel.public = 1
|
||||||
|
if self.channel.format == 'mp3':
|
||||||
|
self.channel.audio_info = {
|
||||||
|
'bitrate': str(320),
|
||||||
|
'samplerate': str(48000),
|
||||||
|
'channels': str(2),
|
||||||
|
}
|
||||||
|
|
||||||
|
self.server_url = 'http://' + self.channel.host + ':' + str(self.channel.port) + self.channel.mount
|
||||||
|
print(self.server_url)
|
||||||
|
|
||||||
|
def channel_open(self):
|
||||||
|
if self.channelIsOpen:
|
||||||
|
return True
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.channel.open()
|
||||||
|
self.channelIsOpen = True
|
||||||
|
return True
|
||||||
|
except Exception as ex:
|
||||||
|
logging.error('channel could not be opened: {}'.format(ex))
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def channel_close(self):
|
||||||
|
self.channelIsOpen = False
|
||||||
self._ended = True
|
self._ended = True
|
||||||
|
try:
|
||||||
|
self.channel.close()
|
||||||
|
logging.info('channel closed')
|
||||||
|
except Exception as ex:
|
||||||
|
logging.error('channel could not be closed: {}'.format(ex))
|
||||||
|
|
||||||
|
def ping_server(self):
|
||||||
|
log = True
|
||||||
|
|
||||||
|
while not self.server_ping:
|
||||||
|
try:
|
||||||
|
server = urllib.urlopen(self.server_url)
|
||||||
|
self.server_ping = True
|
||||||
|
logging.info('Channel available.')
|
||||||
|
except:
|
||||||
|
time.sleep(1)
|
||||||
|
if log:
|
||||||
|
logging.error('Could not connect the channel. Waiting for channel to become available.')
|
||||||
|
log = False
|
||||||
|
|
||||||
|
def default_queue(self):
|
||||||
|
try:
|
||||||
|
r = requests.get('http://{}/mix/?random=True&limit=1'.format(self.api_host)) \
|
||||||
|
.json().get('results')[0].get('slug')
|
||||||
|
r = requests.get('http://{}/mix/{}/stream_url'.format(self.api_host, r))
|
||||||
|
url = r.json()['url']
|
||||||
|
return [
|
||||||
|
url
|
||||||
|
]
|
||||||
|
except Exception as ex:
|
||||||
|
logging.error(ex)
|
||||||
|
return [
|
||||||
|
'https://dsscdn.blob.core.windows.net/mixes/52df41af-5f81-4f00-a9a8-9ffb5dc3185f.mp3'
|
||||||
|
]
|
||||||
|
|
||||||
def set_audio_queue(self, queue):
|
def set_audio_queue(self, queue):
|
||||||
self.audio_queue = queue
|
self.audio_queue = queue
|
||||||
|
self._ended = True
|
||||||
|
|
||||||
def get_next_play_item(self):
|
def get_next_play_item(self):
|
||||||
print "Finding next item"
|
try:
|
||||||
self._ended = False
|
logging.debug("Finding next item")
|
||||||
|
|
||||||
# get random item from DSS api
|
# get random item from DSS api
|
||||||
if len(self.audio_queue) > self.audio_index:
|
if len(self.audio_queue) > self.audio_index:
|
||||||
item = self.audio_queue[self.audio_index]
|
item = self.audio_queue[self.audio_index]
|
||||||
else:
|
else:
|
||||||
item = self.default_queue[0]
|
item = self.default_queue()[0]
|
||||||
|
|
||||||
self.player.set_media(item)
|
logging.debug("Playing: {}".format(item))
|
||||||
print "Playing: {}".format(item)
|
self.stream = self.file_read_remote(item)
|
||||||
return self.player.file_read_remote()
|
|
||||||
|
|
||||||
def close_channel(self):
|
self._ended = False
|
||||||
self.isOpen = False
|
return True
|
||||||
|
except Exception as ex:
|
||||||
|
logging.error('Error getting next play item: {}'.format(ex))
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
self.ping_server()
|
||||||
while True:
|
while True:
|
||||||
now_playing = self.get_next_play_item()
|
now_playing = self.get_next_play_item()
|
||||||
if now_playing is not None:
|
if now_playing is not None:
|
||||||
for chunk in now_playing:
|
for self.chunk in self.stream:
|
||||||
try:
|
try:
|
||||||
self.s.s.send(chunk)
|
self.channel.send(self.chunk)
|
||||||
self.s.s.sync()
|
self.channel.sync()
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
print ("Error sending chunk: {0}".format(ex))
|
logging.error("Error sending chunk: {0}".format(ex))
|
||||||
self.close_channel()
|
self.channel_close()
|
||||||
if self._ended:
|
if self._ended:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
print("No audio, waiting")
|
logging.debug("No audio, waiting")
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
|
||||||
|
print "Outta here........"
|
||||||
|
|
||||||
|
def file_read_remote(self, item):
|
||||||
|
"""Read remote file and stream data through a generator."""
|
||||||
|
main_buffer_size = 0x10000
|
||||||
|
m = urllib2.urlopen(item)
|
||||||
|
while True:
|
||||||
|
__main_chunk = m.read(main_buffer_size)
|
||||||
|
if not __main_chunk:
|
||||||
|
break
|
||||||
|
yield __main_chunk
|
||||||
|
m.close()
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
<icecast>
|
|
||||||
<location>Cork Like</location>
|
|
||||||
<admin>icemaster@deepsouthsounds.com</admin>
|
|
||||||
|
|
||||||
<limits>
|
|
||||||
<clients>100</clients>
|
|
||||||
<sources>2</sources>
|
|
||||||
<threadpool>5</threadpool>
|
|
||||||
<queue-size>524288</queue-size>
|
|
||||||
<client-timeout>30</client-timeout>
|
|
||||||
<header-timeout>15</header-timeout>
|
|
||||||
<source-timeout>10</source-timeout>
|
|
||||||
<burst-on-connect>1</burst-on-connect>
|
|
||||||
<burst-size>65535</burst-size>
|
|
||||||
</limits>
|
|
||||||
|
|
||||||
<authentication>
|
|
||||||
<source-password>RDzNlgqmj67vk</source-password>
|
|
||||||
<relay-password>9PmUbI1mLne9o</relay-password>
|
|
||||||
|
|
||||||
<admin-user>admin</admin-user>
|
|
||||||
<admin-password>CrVuP5evoJZ0.</admin-password>
|
|
||||||
</authentication>
|
|
||||||
|
|
||||||
<hostname>radio.deepsouthsounds.com</hostname>
|
|
||||||
|
|
||||||
<listen-socket>
|
|
||||||
<port>8351</port>
|
|
||||||
<shoutcast-mount>/dss</shoutcast-mount>
|
|
||||||
</listen-socket>
|
|
||||||
<fileserve>1</fileserve>
|
|
||||||
|
|
||||||
<paths>
|
|
||||||
<basedir>/usr/share/icecast2</basedir>
|
|
||||||
<logdir>/var/log/icecast2</logdir>
|
|
||||||
<webroot>/usr/share/icecast2/web</webroot>
|
|
||||||
<adminroot>/usr/share/icecast2/admin</adminroot>
|
|
||||||
<alias source="/" destination="/status.xsl"/>
|
|
||||||
</paths>
|
|
||||||
|
|
||||||
<logging>
|
|
||||||
<accesslog>access.log</accesslog>
|
|
||||||
<errorlog>error.log</errorlog>
|
|
||||||
<loglevel>3</loglevel>
|
|
||||||
<logsize>10000</logsize>
|
|
||||||
</logging>
|
|
||||||
|
|
||||||
<security>
|
|
||||||
<chroot>0</chroot>
|
|
||||||
</security>
|
|
||||||
</icecast>
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
|
twisted
|
||||||
cython
|
cython
|
||||||
requests
|
requests
|
||||||
tornado==4.2.1
|
tornado==4.2.1
|
||||||
python-shout==0.2.1
|
|
||||||
|
|
||||||
git+https://github.com/fergalmoran/DeeFuzzer.git
|
|
||||||
git+https://github.com/fergalmoran/python-shout.git#python-shout
|
git+https://github.com/fergalmoran/python-shout.git#python-shout
|
||||||
71
server.py
71
server.py
@@ -1,28 +1,16 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
from shout import ShoutException
|
import signal
|
||||||
import time
|
import time
|
||||||
import tornado
|
import tornado
|
||||||
import tornado.ioloop
|
import tornado.ioloop
|
||||||
import tornado.web
|
import tornado.web
|
||||||
import tornado.escape
|
import tornado.escape
|
||||||
from tornado.options import define, options, parse_command_line
|
from tornado.options import define, options, parse_command_line
|
||||||
import os
|
|
||||||
import signal
|
|
||||||
from ice_client import IceClient
|
|
||||||
from ice_relay import IceRelay
|
from ice_relay import IceRelay
|
||||||
|
|
||||||
define("port", default=8888, help="run on the given port", type=int)
|
is_closing = False
|
||||||
define("debug", default=True, help="run in debug mode")
|
|
||||||
|
|
||||||
define("ice_host", default='localhost', help="Icecast server host")
|
|
||||||
define("ice_port", default=8999, help="Icecast server port")
|
|
||||||
define("ice_user", default='source', help="Icecast user")
|
|
||||||
define("ice_password", default='hackme', help="Icecast password")
|
|
||||||
define("ice_mount", default='/mp3', help="Default icecast mount point")
|
|
||||||
define("ice_format", default='mp3', help="Format of the icecast server (mp3, vorbis, flac)")
|
|
||||||
define("ice_protocol", default='http', help="Protocol (currently only http)")
|
|
||||||
|
|
||||||
|
|
||||||
class MainHandler(tornado.web.RequestHandler):
|
class MainHandler(tornado.web.RequestHandler):
|
||||||
@@ -37,7 +25,6 @@ class PlayAudioHandler(tornado.web.RequestHandler):
|
|||||||
in_file = data.get('audio_file')
|
in_file = data.get('audio_file')
|
||||||
if in_file is not None:
|
if in_file is not None:
|
||||||
relay.set_audio_queue([in_file])
|
relay.set_audio_queue([in_file])
|
||||||
relay.stop()
|
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
raise tornado.web.HTTPError(500, ex.message)
|
raise tornado.web.HTTPError(500, ex.message)
|
||||||
@@ -46,12 +33,10 @@ class PlayAudioHandler(tornado.web.RequestHandler):
|
|||||||
class StopAudioHandler(tornado.web.RequestHandler):
|
class StopAudioHandler(tornado.web.RequestHandler):
|
||||||
def post(self, *args, **kwargs):
|
def post(self, *args, **kwargs):
|
||||||
try:
|
try:
|
||||||
relay.stop()
|
relay.channel_close()
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
raise tornado.web.HTTPError(500, ex.message)
|
raise tornado.web.HTTPError(500, ex.message)
|
||||||
|
|
||||||
is_closing = False
|
|
||||||
|
|
||||||
|
|
||||||
def signal_handler(signum, frame):
|
def signal_handler(signum, frame):
|
||||||
global is_closing
|
global is_closing
|
||||||
@@ -63,14 +48,35 @@ def try_exit():
|
|||||||
global is_closing
|
global is_closing
|
||||||
if is_closing:
|
if is_closing:
|
||||||
# clean up here
|
# clean up here
|
||||||
streamer.stop()
|
relay.channel_close()
|
||||||
relay.stop()
|
|
||||||
|
|
||||||
tornado.ioloop.IOLoop.instance().stop()
|
tornado.ioloop.IOLoop.instance().stop()
|
||||||
logging.info('exit success')
|
logging.info('exit success')
|
||||||
|
|
||||||
|
define("port", default=8888, help="run on the given port", type=int)
|
||||||
|
define("debug", default=True, help="run in debug mode")
|
||||||
|
|
||||||
|
define("ice_host", default='localhost', help="Icecast server host")
|
||||||
|
define("ice_port", default=8000, help="Icecast server port")
|
||||||
|
define("ice_user", default='source', help="Icecast user")
|
||||||
|
define("ice_password", default='hackme', help="Icecast password")
|
||||||
|
define("ice_mount", default='/mp3', help="Default icecast mount point")
|
||||||
|
define("ice_format", default='mp3', help="Format of the icecast server (mp3, vorbis, flac)")
|
||||||
|
define("ice_protocol", default='http', help="Protocol (currently only http)")
|
||||||
|
define("api_host", default='api.deepsouthsounds.com', help="API Host for serving audio")
|
||||||
|
|
||||||
|
#tornado.options.parse_command_line()
|
||||||
|
tornado.options.parse_config_file("dss.radio.conf")
|
||||||
|
relay = IceRelay(options=options)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
if relay.channel_open():
|
||||||
|
relay.start()
|
||||||
|
else:
|
||||||
|
logging.error("IceCast relay failed to start")
|
||||||
|
exit()
|
||||||
|
|
||||||
app = tornado.web.Application(
|
app = tornado.web.Application(
|
||||||
[
|
[
|
||||||
(r"/", MainHandler),
|
(r"/", MainHandler),
|
||||||
@@ -81,30 +87,13 @@ def main():
|
|||||||
template_path=os.path.join(os.path.dirname(__file__), "templates"),
|
template_path=os.path.join(os.path.dirname(__file__), "templates"),
|
||||||
static_path=os.path.join(os.path.dirname(__file__), "static"),
|
static_path=os.path.join(os.path.dirname(__file__), "static"),
|
||||||
# xsrf_cookies=True,
|
# xsrf_cookies=True,
|
||||||
debug=options.debug
|
debug=options['debug']
|
||||||
)
|
)
|
||||||
signal.signal(signal.SIGINT, signal_handler)
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
app.listen(options.port)
|
app.listen(options['port'])
|
||||||
tornado.ioloop.PeriodicCallback(try_exit, 100).start()
|
tornado.ioloop.PeriodicCallback(try_exit, 100).start()
|
||||||
tornado.ioloop.IOLoop.current().start()
|
tornado.ioloop.IOLoop.current().start()
|
||||||
|
|
||||||
parse_command_line()
|
|
||||||
try:
|
|
||||||
streamer = IceClient(
|
|
||||||
host=options['ice_host'],
|
|
||||||
port=options['ice_port'],
|
|
||||||
user=options['ice_user'],
|
|
||||||
password=options['ice_password'],
|
|
||||||
mount=options['ice_mount'],
|
|
||||||
format=options['ice_format'],
|
|
||||||
protocol=options['ice_protocol']
|
|
||||||
)
|
|
||||||
relay = IceRelay(client=streamer)
|
|
||||||
relay.start()
|
|
||||||
|
|
||||||
except ShoutException as ex:
|
|
||||||
logging.info("Unable to connect to shout server {}:{} - {}".format(options['ice_host'], options['ice_port'], ex))
|
|
||||||
exit()
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ function getCookie(name) {
|
|||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
var xsrf = getCookie("_xsrf");
|
var xsrf = getCookie("_xsrf");
|
||||||
$('#play_audio').click(function () {
|
$('#play_audio').click(function () {
|
||||||
$.post("/a/play", {
|
$.post("/a/play", JSON.stringify({
|
||||||
_xsrf: xsrf,
|
_xsrf: xsrf,
|
||||||
audio_file: $('#audio_file').val()
|
audio_file: $('#audio_file').val()
|
||||||
});
|
}), 'json');
|
||||||
});
|
});
|
||||||
$('#stop_audio').click(function () {
|
$('#stop_audio').click(function () {
|
||||||
$.post("/a/stop", {
|
$.post("/a/stop", {
|
||||||
_xsrf: xsrf
|
_xsrf: xsrf
|
||||||
});
|
}, 'json');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -18,16 +18,12 @@ supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface
|
|||||||
[supervisorctl]
|
[supervisorctl]
|
||||||
serverurl=unix:///tmp/supervisor.sock
|
serverurl=unix:///tmp/supervisor.sock
|
||||||
|
|
||||||
[program:icecast2]
|
|
||||||
user=icecast2
|
|
||||||
command=icecast2 -n -c /etc/icecast2/icecast.xml
|
|
||||||
stopsignal=6
|
|
||||||
stdout_events_enabled=true
|
|
||||||
stderr_events_enabled=true
|
|
||||||
autorestart=true
|
|
||||||
|
|
||||||
[program:server]
|
[program:server]
|
||||||
command=server.py --ice_host=radio.deepsouthsounds.com --ice_port=8351 --ice_user=source --ice_password=RDzNlgqmj67vk --ice_mount=/dss
|
command=server.py --ice_host=radio.deepsouthsounds.com \
|
||||||
|
--ice_port=8351 \
|
||||||
|
--ice_user=source \
|
||||||
|
--ice_password=RDzNlgqmj67vk \
|
||||||
|
--ice_mount=/dss
|
||||||
stopsignal=6
|
stopsignal=6
|
||||||
stdout_events_enabled=true
|
stdout_events_enabled=true
|
||||||
stderr_events_enabled=true
|
stderr_events_enabled=true
|
||||||
|
|||||||
Reference in New Issue
Block a user