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