mirror of
https://github.com/fergalmoran/dss.radio.git
synced 2025-12-22 01:37:58 +00:00
214 lines
7.1 KiB
Python
214 lines
7.1 KiB
Python
import logging
|
|
from threading import Thread
|
|
import time
|
|
import urllib
|
|
import shout
|
|
import urllib2
|
|
import requests
|
|
from util.social import Twitter
|
|
|
|
BUF_LEN = 4096
|
|
|
|
|
|
class IceRelay(Thread):
|
|
server_ping = False
|
|
|
|
def __init__(self, options, mountpoint='dss', title='DeepSouthSounds Radio'):
|
|
super(IceRelay, self).__init__()
|
|
self.title = title
|
|
self._ended = True
|
|
self.isOpen = True
|
|
self.audio_queue = []
|
|
self.audio_index = 0
|
|
|
|
self.channelIsOpen = False
|
|
|
|
self.options = options
|
|
self.mountpoint = mountpoint
|
|
self.title = title
|
|
|
|
self.api_host = options['api_host']
|
|
self.api_callback_url = options['api_callback_url']
|
|
|
|
self.twitter_consumer_key = options['twitter_consumer_key']
|
|
self.twitter_consumer_secret = options['twitter_consumer_secret']
|
|
self.twitter_access_token = options['twitter_access_token']
|
|
self.twitter_access_token_secret = options['twitter_access_token_secret']
|
|
|
|
self._channel_mutex = False
|
|
|
|
self._open_channel()
|
|
self.server_url = 'http://' + self.channel.host + ':' + str(self.channel.port) + self.channel.mount
|
|
print(self.server_url)
|
|
|
|
def _open_channel(self):
|
|
self.channel = shout.Shout()
|
|
self.channel.mount = '/' + self.mountpoint
|
|
self.channel.url = 'http://deepsouthsounds.com/'
|
|
self.channel.name = self.title
|
|
self.channel.genre = 'Deep House Music'
|
|
self.channel.description = 'Deep sounds from the deep south'
|
|
self.channel.format = self.options['ice_format']
|
|
self.channel.host = self.options['ice_host']
|
|
self.channel.port = int(self.options['ice_port'])
|
|
self.channel.user = self.options['ice_user']
|
|
self.channel.password = self.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),
|
|
}
|
|
|
|
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
|
|
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):
|
|
ret = []
|
|
try:
|
|
found = False
|
|
while not found:
|
|
r = requests.get('http://{}/_radio?rmix=z'.format(self.api_host))
|
|
v = r.json()
|
|
import urllib2
|
|
try:
|
|
ret = urllib2.urlopen(v['url'])
|
|
if ret.code == 200:
|
|
found = True
|
|
ret = [v]
|
|
except urllib2.HTTPError as ex:
|
|
pass
|
|
except Exception as ex:
|
|
logging.error(ex)
|
|
ret = [{
|
|
'url': 'https://dsscdn.blob.core.windows.net/mixes/52df41af-5f81-4f00-a9a8-9ffb5dc3185f.mp3',
|
|
'title': 'Default song',
|
|
'slug': '/'
|
|
}]
|
|
|
|
for p in ret:
|
|
print("Playing {}".format(p))
|
|
|
|
return ret
|
|
|
|
def shuffle_queue(self):
|
|
self._ended = True
|
|
time.sleep(10)
|
|
|
|
def set_audio_queue(self, queue):
|
|
self.audio_queue = queue
|
|
self._ended = True
|
|
time.sleep(10)
|
|
|
|
def get_next_play_item(self):
|
|
try:
|
|
logging.debug("Finding next item")
|
|
|
|
# get random item from DSS api
|
|
if len(self.audio_queue) > self.audio_index:
|
|
item = self.audio_queue[self.audio_index]
|
|
else:
|
|
item = self.default_queue()[0]
|
|
|
|
self.channel.set_metadata({'song': str(item['title']), 'charset': 'utf-8'})
|
|
logging.debug("Playing: {}".format(item['title']))
|
|
self.stream = self.file_read_remote(item['url'])
|
|
|
|
self.post_callback(item['title'], item['slug'])
|
|
|
|
if self.twitter_access_token and self.twitter_access_token_secret and \
|
|
self.twitter_consumer_secret and self.twitter_consumer_key:
|
|
try:
|
|
tw = Twitter(key=self.twitter_consumer_key, secret=self.twitter_consumer_secret,
|
|
access_key=self.twitter_access_token, access_secret=self.twitter_access_token_secret)
|
|
tw.post("Now playing on DSS Radio - {}\nhttp://deepsouthsounds.com/".format(
|
|
item['title'][0:90]))
|
|
except Exception as ex:
|
|
logging.debug("Unable to post to twitter: {}".format(ex))
|
|
|
|
self._ended = False
|
|
return True
|
|
except Exception as ex:
|
|
logging.error('Error getting next play item: {}'.format(ex))
|
|
|
|
return False
|
|
|
|
def run(self):
|
|
self.ping_server()
|
|
while True:
|
|
now_playing = self.get_next_play_item()
|
|
if now_playing is not None:
|
|
|
|
for self.chunk in self.stream:
|
|
try:
|
|
self.channel.send(self.chunk)
|
|
self.channel.sync()
|
|
except shout.ShoutException as sex: #(snigger)
|
|
if not self._channel_mutex:
|
|
self.channelIsOpen = False
|
|
self._channel_mutex = True
|
|
self.channel_open()
|
|
else:
|
|
self._channel_mutex = False
|
|
except Exception as ex:
|
|
logging.error("Error sending chunk: {0}".format(ex))
|
|
self.channel_close()
|
|
if self._ended:
|
|
break
|
|
else:
|
|
logging.debug("No audio, waiting")
|
|
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()
|
|
|
|
def post_callback(self, title, slug):
|
|
if self.api_callback_url:
|
|
url = "http://{}{}".format(self.api_host, self.api_callback_url.format(title, slug))
|
|
r = requests.post(url)
|
|
print (r)
|