Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Apr 27th, 2008  |  syntax: Python  |  size: 4.05 KB  |  hits: 485  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. import socket
  2. import gst
  3. import gobject
  4. import thread
  5. import threading
  6. import time
  7.  
  8. PORT=3333
  9. STATIONS={'fm4':'mms://stream1.orf.at/fm4_live',
  10.           'bayern2':'mms://gffstream-w3a.wm.llnwd.net/gffstream_w3a',
  11.           'bayern5':'mms://gffstream-w9b.wm.llnwd.net/gffstream_w9b'}
  12. SOURCES={'mms://': 'mmssrc location={X}',
  13.          'http://': 'gnomevfssrc location={x}'}
  14. ENCODERS={'mp3': { 'gst': 'lame', 'mime': 'audio/mpeg'}}
  15.  
  16. def close_pipe():
  17.     global gst_pipe
  18.     if gst_pipe:
  19.         gst_pipe.set_state(gst.STATE_NULL)
  20.         gst_pipe=None
  21.        
  22. def create_pipe(request, sock):
  23.     #request looks like
  24.     #/stationame.encoder, currently only encoders with 3 letters are supported
  25.     close_pipe()
  26.     global gst_pipe
  27.     source=None
  28.     encoder=None
  29.     # find station souce
  30.     if request[1:-4] in STATIONS:
  31.         for src_prefix in SOURCES:
  32.             if STATIONS[request[1:-4]][0:len(src_prefix)] == src_prefix:
  33.                 source = SOURCES[src_prefix].replace('{X}', STATIONS[request[1:-4]])
  34.                 break
  35.     # find encoder
  36.     if request[-3:] in ENCODERS:
  37.         encoder=ENCODERS[request[-3:]]['gst']
  38.    
  39.     if encoder and source:
  40.         gst_pipe = gst.parse_launch(source + " ! decodebin ! " + encoder + " ! fdsink name=fd_sink")
  41.         gst_pipe.get_by_name('fd_sink').set_property('fd', sock.makefile('wb').fileno())
  42.         bus = gst_pipe.get_bus()
  43.         bus.add_signal_watch()
  44.         bus.connect('message', gstreamer_message)
  45.         return ENCODERS[request[-3:]]['mime']
  46.    
  47. def handle_request(client_sock):
  48.     req = ""
  49.     while True:
  50.         data = client_sock.recv(1)
  51.         if data == "":
  52.             break
  53.         req = req + data
  54.         if req[-4:] == "\r\n\r\n":
  55.             break
  56.     req = req.split('\r\n')
  57.     mime = create_pipe(req[0].split()[1], client_sock)
  58.  
  59.     if mime:
  60.         client_sock.sendall("HTTP/1.1 200 OK\r\n");
  61.         client_sock.sendall("Content-Type: "+ mime +"\r\n")
  62.         client_sock.sendall("Cache-Control: no-cache, must-revalidate\r\n");
  63.         client_sock.sendall("\r\n\r\n")
  64.        
  65.         #start playing till eos or client close
  66.         global transfer_event, gst_pipe
  67.         gst_pipe.set_state(gst.STATE_PLAYING)
  68.         transfer_event.clear()
  69.         transfer_event.wait()
  70.         close_pipe()    
  71.     else:
  72.         #create playlist
  73.         # Try to find host
  74.         host = None
  75.         for line in req:
  76.             if line[0:4].lower() == 'host':
  77.                 host = line[6:]
  78.         if not host:
  79.             host = 'localhost:' + PORT
  80.            
  81.         playlist = ''
  82.         for station in STATIONS:
  83.             for encoder in ENCODERS:
  84.                 playlist += 'http://' + host + '/' + station + '.' + encoder + '\r\n'
  85.                
  86.        
  87.         client_sock.sendall("HTTP/1.1 200 OK\r\n");
  88.         client_sock.sendall("Content-Type: audio/x-mpegurl\r\n")
  89.         client_sock.sendall("Content-Length: " + str(len(playlist)) + "\r\n")
  90.         client_sock.sendall('Content-Disposition: attachment; filename="playlist.m3u"\r\n')
  91.         client_sock.sendall("Cache-Control: no-cache, must-revalidate\r\n");
  92.         client_sock.sendall("\r\n\r\n")                
  93.        
  94.         client_sock.sendall(playlist)
  95.        
  96.    
  97. def gstreamer_message(bus, message):
  98.     if message.type == gst.MESSAGE_ERROR or message.type == gst.MESSAGE_EOS:
  99.         global transfer_event
  100.         transfer_event.set()
  101.    
  102.    
  103. def run_webserver():
  104.     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
  105.     sock.bind(('', PORT))
  106.     sock.listen(1)
  107.     try:
  108.         while 1:
  109.             ( clientsock, client ) = sock.accept()
  110.             handle_request ( clientsock )
  111.             clientsock.close()
  112.     finally:
  113.         sock.close()
  114.  
  115.            
  116. if __name__=='__main__':
  117.     gobject.threads_init()
  118.     ws = thread.start_new_thread(run_webserver, ())
  119.     gst_pipe=None
  120.     transfer_event=threading.Event()
  121.     try:
  122.         gobject.MainLoop().run()
  123.     except KeyboardInterrupt:
  124.         close_pipe()
  125.         print "bye"