gmyth-stream/server/0.1/main.py
author morphbr
Wed Apr 18 15:59:10 2007 +0100 (2007-04-18)
branchtrunk
changeset 565 ed34b1dab103
permissions -rwxr-xr-x
[svn r570] - Included new core for GMyth-Streamer (0.2)
- New core based on code by Gustavo Barbieri
     1 #!/usr/bin/python
     2 
     3 import os
     4 import lib
     5 import sys
     6 import imp
     7 import ConfigParser
     8 import logging as log
     9 
    10 log.basicConfig(level=log.DEBUG,
    11                 format="%(asctime)s %(levelname)-8s %(message)s",
    12                 datefmt='%Y-%m-%d %H:%M:%S')
    13 
    14 config = ConfigParser.ConfigParser()
    15 config.read("stream.conf")
    16 
    17 def load_module(pathlist, name):
    18     fp, path, desc = imp.find_module(name, pathlist)
    19     try:
    20         module = imp.load_module(name, fp, path, desc)
    21         return module
    22     finally:
    23         if fp:
    24             fp.close()
    25 
    26 
    27 media_plugin = config.get("Media", "engine")
    28 media_plugin_module = load_module(["./plugins/media"], media_plugin)
    29 media = media_plugin_module.Media(config)
    30 
    31 comm_plugin = config.get("Comm", "engine")
    32 comm_plugin_module = load_module(["./plugins/comm"], comm_plugin)
    33 server = comm_plugin_module.Server(config)
    34 
    35 log.info("Starting GMyth-Stream server")
    36 
    37 
    38 '''
    39 PROTOCOL DESCRIPTION
    40 =====================
    41 
    42 COMMAND OPTIONS
    43 
    44 -> SETUP DESCRIPTION
    45 |-> used to setup transcoding and streaming parameters
    46 |-> must be used before any "PLAY" command
    47 |-> e.g:
    48 
    49 file://file_name mux vcodec vbitrate fps acodec abitrate width height options
    50 dvd://title_number mux vcodec vbitrate fps acodec abitrate width height options
    51 
    52 -> PLAY DESCRIPTION
    53  |-> used to start transcoding and streaming of file
    54  |-> must be used just if SETUP was used before
    55  |-> after it, _must_ send STOP
    56 
    57 -> STOP DESCRIPTION
    58  |-> used to stop transcoding and streaming process
    59  |-> must be used just if PLAY was used before
    60  |-> must be used after PLAY
    61 
    62 -> QUIT DESCRIPTION
    63  |-> used to quit the main loop (quit program)
    64 
    65 '''
    66 nextport = 0
    67 setup = (False, "STOPPED")
    68 
    69 def do_setup(server, filename, mux, vcodec, vbitrate, fps, acodec, abitrate,
    70              width, height, *options):
    71     global nextport
    72     global setup
    73 
    74     if setup[1] != "PLAYING":
    75         nextport += 1
    76         ret = media.setup(filename, mux, vcodec, vbitrate, fps, acodec,
    77                           abitrate, width, height, nextport, options)
    78         if ret[0]:
    79             server.sendOk()
    80         else:
    81             server.sendNotOk(ret[1])
    82 
    83         setup = (True, setup[1])
    84 
    85     else: server.sendNotOk("You must STOP before SETingUP again")
    86 
    87     return True
    88 
    89 def do_play(server):
    90     global setup
    91 
    92     if setup[0] and setup[1] == "STOPPED":
    93         setup = (setup[0], "PLAYING")
    94         ret = media.play()
    95         if ret[0]:
    96             server.sendOk("%d" % nextport)
    97         else:
    98             server.sendNotOk(ret[1])
    99 
   100     else:
   101         if setup[1] == "STOPPED":
   102             server.sendNotOk("You must SETUP before PLAYing")
   103         else:
   104             server.sendNotOk("You must STOP before PLAYing again")
   105 
   106     return True
   107 
   108 def do_stop(server):
   109     global setup
   110 
   111     media.stop()
   112     setup = (False, "STOPPED")
   113     server.sendOk()
   114     return True
   115 
   116 def do_list(server, *directory):
   117     file_list = []
   118     for j in directory:
   119         lib.list_media_files(j, file_list)
   120 
   121     server.sendOk(file_list)
   122     return True
   123 
   124 def do_quit(server):
   125     server.finish = 1
   126     media.stop()
   127     server.sendOk()
   128     return True
   129 
   130 
   131 mapping = {
   132     "SETUP": do_setup,
   133     "PLAY": do_play,
   134     "STOP": do_stop,
   135     "LIST": do_list,
   136     "QUIT": do_quit,
   137     }
   138 
   139 
   140 def dispatch(server, msg):
   141     pieces = msg.split()
   142     if len(pieces) < 1:
   143         log.error("Invalid client command format: %r" % msg)
   144         server.sendNotOk("Invalid Format")
   145         return False
   146 
   147     cmd = pieces[0]
   148     f = mapping.get(cmd, None)
   149     if not f:
   150         log.error("Unknow command: %r" % msg)
   151         server.sendNotOk("Unknow Command")
   152         return False
   153 
   154     try:
   155         return f(server, *pieces[1:])
   156     except Exception, e:
   157         log.error("Could not execute %r: %s" % (msg, e))
   158         server.sendNotOk(str(e))
   159         return False
   160 
   161 
   162 
   163 while not server.finish:
   164     conn, client, port = server.getRequest()
   165     if nextport == 0:
   166         nextport = port
   167 
   168     while not server.finish:
   169         msg = server.getMsg()
   170         if not msg:
   171             break
   172 
   173         log.info("Client %s sent command: %r" % (client, msg))
   174         dispatch(server, msg)
   175 
   176     log.info("Closing connection with %s" % (client,))
   177     server.disconnect_client(conn)
   178     try:
   179         os.wait()
   180     except Exception, e:
   181         log.error(e)
   182 
   183 server.stop()
   184 log.info("Server stopped. Closing...")
   185