]> git.parisson.com Git - deefuzzer.git/commitdiff
* Create Station, Channel and Stream classes
authorGuillaume Pellerin <yomguy@parisson.com>
Sun, 16 Sep 2007 01:35:11 +0000 (01:35 +0000)
committerGuillaume Pellerin <yomguy@parisson.com>
Sun, 16 Sep 2007 01:35:11 +0000 (01:35 +0000)
* Make it multi-threaded
* Doesn't work now for 2 channels per station...

d-fuzz.py
example/myfuzz.xml

index 7d0c282ab725e966c832d894e9f785d399923a50..2a57e98b2e454688f9e8f4c83670ae63f73a3084 100755 (executable)
--- a/d-fuzz.py
+++ b/d-fuzz.py
 
 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()
index 2e0ff4328b1005679a694bcfc85fb2e9ea870b80..332d98f5e9a42e94b07a83a6d8fd6fe981dffb7c 100644 (file)
@@ -1,3 +1,4 @@
+<d-fuzz>
 <station>
     <infos>
         <short_name>Cellar_Playlist</short_name>
@@ -5,7 +6,7 @@
         <description>The Best Techno, House and Groove Stuff from Paris - 100% Mix !</description>
         <url>http://cellar.parisson.com</url>
         <genre>Techno/House</genre>
-        <channels>2</channels>
+        <channels>1</channels>
     </infos>
     <server>
         <host>localhost</host>
@@ -15,7 +16,7 @@
         <public>1</public>
     </server>
     <media>
-        <dir>/home/momo/music/mp3/groovemaster_drums</dir>
+        <dir>/home/pub/samples/samples2/groovemasters/Groovemasters Drums/mp3</dir>
         <format>mp3</format>
         <bitrate>192</bitrate>
         <ogg_quality>7</ogg_quality>
@@ -24,5 +25,5 @@
         <shuffle>1</shuffle>
     </media>
 </station>
-
+</d-fuzz>