From: Guillaume Pellerin Date: Sun, 16 Sep 2007 01:35:11 +0000 (+0000) Subject: * Create Station, Channel and Stream classes X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=69713e1911afc203e702735176aad61eae1bfd6b;p=deefuzzer.git * Create Station, Channel and Stream classes * Make it multi-threaded * Doesn't work now for 2 channels per station... --- diff --git a/d-fuzz.py b/d-fuzz.py index 7d0c282..2a57e98 100755 --- a/d-fuzz.py +++ b/d-fuzz.py @@ -12,40 +12,25 @@ import os import sys -import shout import string import random import subprocess +import shout +from shout import Shout from xmltodict import * +from threading import Thread from mutagen.oggvorbis import OggVorbis -class ExportProcessError: - - def __init__(self, message, command, subprocess): - self.message = message - self.command = str(command) - self.subprocess = subprocess - - def __str__(self): - if self.subprocess.stderr != None: - error = self.subprocess.stderr.read() - else: - error = '' - return "%s ; command: %s; error: %s" % (self.message, - self.command, - error) - -class DFuzz: +class DFuzz(Thread): """A D-Fuzz station""" - def __init__(self): + def __init__(self, conf_file): + Thread.__init__(self) + self.status = -1 self.version = '0.1' - self.conf = [] - self.id = 999999 - self.buffer_size = 0xFFFF - self.rand_list = [] - + self.conf_file = conf_file + def prog_info(self): desc = '\n d-fuzz : easy and light streaming tool\n' version = ' version : ' + self.version +'\n\n' @@ -72,12 +57,87 @@ class DFuzz: def get_conf_dict(self): confile = open(self.conf_file,'r') conf_xml = confile.read() - self.conf = xmltodict(conf_xml,'utf-8') confile.close() + return xmltodict(conf_xml,'utf-8') + def get_station_names(self): return self.conf['station']['name'] + + def run(self): + print "D-fuzz v"+self.version + self.conf = self.get_conf_dict() + print self.conf + nb_stations = len(self.conf['d-fuzz']) + print str(nb_stations) + + for i in range(0,nb_stations): + print str(i) + station = self.conf['d-fuzz']['station'] + print station + station_thread = Station(station) + station_thread.start() + + +class Station(DFuzz): + """A web station""" + def __init__ (self, station): + Thread.__init__(self) + self.station = station + print self.station + self.channels = int(self.station['infos']['channels']) + + def run(self): + for channel_id in range(0,self.channels): + channel = Channel(self.station, channel_id) + channel.start() + + + +class Channel(Thread): + """A channel shout thread""" + + def __init__(self, station, channel_id): + Thread.__init__(self) + self.channel_id = channel_id + self.channel = shout.Shout() + #self.station = station + self.id = 999999 + self.rand_list = [] + # Media + self.media_dir = station['media']['dir'] + + self.channel.format = station['media']['format'] + self.mode_shuffle = int(station['media']['shuffle']) + + # Server + self.channel.protocol = 'http' # | 'xaudiocast' | 'icy' + self.channel.host = station['server']['host'] + self.channel.port = int(station['server']['port']) + self.channel.user = 'source' + self.channel.password = station['server']['sourcepassword'] + self.channel.mount = '/' + station['infos']['short_name'] + '_' + \ + str(self.id) + '.' + self.channel.format + print self.channel.mount + self.channel.public = int(station['server']['public']) + + # Infos + self.channel.name = station['infos']['name'] + self.channel.genre = station['infos']['genre'] + self.channel.description = station['infos']['description'] + self.channel.url = station['infos']['url'] + # s.audio_info = { 'key': 'val', ... } + # (keys are shout.SHOUT_AI_BITRATE, shout.SHOUT_AI_SAMPLERATE, + # shout.SHOUT_AI_CHANNELS, shout.SHOUT_AI_QUALITY) + + # Playlist + self.playlist = self.get_playlist() + self.lp = len(self.playlist) + self.rand_list = range(0,self.lp) + random.shuffle(self.rand_list) + + def get_playlist(self): file_list = [] for root, dirs, files in os.walk(self.media_dir): @@ -110,18 +170,53 @@ class DFuzz: print str(self.id) +':'+ str(index) return playlist, playlist[index] + + def run(self): + print "Using libshout version %s" % shout.version() + print 'Playlist :' + print self.playlist + + self.channel.open() + while 1: + if self.lp == 0: + break + if self.mode_shuffle == 1: + self.playlist, media = self.get_next_media_rand(self.playlist) + else: + self.playlist, media = self.get_next_media_lin(self.playlist) + print media + file_name = string.replace(media, self.media_dir + os.sep, '') + self.channel.set_metadata({'song': file_name}) + stream = Stream(self.media_dir, media) + print 'D-fuzz file : %s' % file_name + for chunk in stream.run(): + self.channel.send(chunk) + self.channel.sync() + self.channel.close() + + +class Stream: + """Streaming class""" + + def __init__(self, media_dir, media): + #Thread.__init__(self) + self.media = media + self.media_dir = media_dir + self.command = 'cat' + self.buffer_size = 0xFFFF + def core_process(self, command, buffer_size): """Apply command and stream data through a generator. - From Telemeta...""" + Taken from Telemeta...""" __chunk = 0 try: proc = subprocess.Popen(command, - shell = True, - bufsize = buffer_size, - stdin = subprocess.PIPE, - stdout = subprocess.PIPE, - close_fds = True) + shell = True, + bufsize = buffer_size, + stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + close_fds = True) except: raise IOError('Command failure:', command, proc) @@ -134,83 +229,38 @@ class DFuzz: if len(__chunk) == 0: break yield __chunk + + def run(self): + command = self.command + ' "%s"' % self.media + stream = self.core_process(command, self.buffer_size) + for chunk in stream: + yield chunk - def stream(self, conf_file): - print "D-fuzz v"+self.version - self.conf_file = conf_file - self.get_conf_dict() - - #for station in conf_dict['station']: - - station = self.conf['station'] - #print station - - s = shout.Shout() - print "Using libshout version %s" % shout.version() - - # Media - self.media_dir = station['media']['dir'] - format = station['media']['format'] - mode_shuffle = int(station['media']['shuffle']) - s.format = format - # Server - s.protocol = 'http' # | 'xaudiocast' | 'icy' - s.host = station['server']['host'] - s.port = int(station['server']['port']) - s.user = 'source' - s.password = station['server']['sourcepassword'] - s.mount = '/' + station['infos']['short_name'] + '.' + format - s.public = int(station['server']['public']) - # Infos - s.name = station['infos']['name'] - s.genre = station['infos']['genre'] - s.description = station['infos']['description'] - s.url = station['infos']['url'] - - # s.audio_info = { 'key': 'val', ... } - # (keys are shout.SHOUT_AI_BITRATE, shout.SHOUT_AI_SAMPLERATE, - # shout.SHOUT_AI_CHANNELS, shout.SHOUT_AI_QUALITY) - - playlist = self.get_playlist() - lp = len(playlist) - self.rand_list = range(0,lp) - random.shuffle(self.rand_list) - print 'Playlist :' - print playlist - - s.open() - - while True: - if lp == 0: - break - - if mode_shuffle == 1: - playlist, media = self.get_next_media_rand(playlist) - else: - playlist, media = self.get_next_media_lin(playlist) - - file_name = string.replace(media, self.media_dir + os.sep, '') - print 'D-fuzz file : %s' % file_name - s.set_metadata({'song': file_name}) - command = 'cat "%s"' % media - stream = self.core_process(command, self.buffer_size) +class DFuzzError: - for chunk in stream: - s.send(chunk) - s.sync() - - s.close() + def __init__(self, message, command, subprocess): + self.message = message + self.command = str(command) + self.subprocess = subprocess + def __str__(self): + if self.subprocess.stderr != None: + error = self.subprocess.stderr.read() + else: + error = '' + return "%s ; command: %s; error: %s" % (self.message, + self.command, + error) + def main(): - station = DFuzz() if len(sys.argv) == 2: - station.stream(sys.argv[1]) + dfuzz_main = DFuzz(sys.argv[1]) + dfuzz_main.run() else: - text = station.prog_info() - sys.exit(text) + sys.exit('NO WAY !') if __name__ == '__main__': main() diff --git a/example/myfuzz.xml b/example/myfuzz.xml index 2e0ff43..332d98f 100644 --- a/example/myfuzz.xml +++ b/example/myfuzz.xml @@ -1,3 +1,4 @@ + Cellar_Playlist @@ -5,7 +6,7 @@ The Best Techno, House and Groove Stuff from Paris - 100% Mix ! http://cellar.parisson.com Techno/House - 2 + 1 localhost @@ -15,7 +16,7 @@ 1 - /home/momo/music/mp3/groovemaster_drums + /home/pub/samples/samples2/groovemasters/Groovemasters Drums/mp3 mp3 192 7 @@ -24,5 +25,5 @@ 1 - +