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