[svn r570] - Included new core for GMyth-Streamer (0.2) trunk
authormorphbr
Wed Apr 18 15:59:10 2007 +0100 (2007-04-18)
branchtrunk
changeset 565ed34b1dab103
parent 564 1b897f699097
child 566 25f194cfa60b
[svn r570] - Included new core for GMyth-Streamer (0.2)
- New core based on code by Gustavo Barbieri
gmyth-stream/server/0.1/lib.py
gmyth-stream/server/0.1/main.py
gmyth-stream/server/0.1/plugins/__init__.py
gmyth-stream/server/0.1/plugins/comm/__init__.py
gmyth-stream/server/0.1/plugins/comm/tcp.py
gmyth-stream/server/0.1/plugins/comm/xmlrpc.py
gmyth-stream/server/0.1/plugins/media/__init__.py
gmyth-stream/server/0.1/plugins/media/ffmpeg.py
gmyth-stream/server/0.1/plugins/media/gstreamer-rtp.py
gmyth-stream/server/0.1/plugins/media/gstreamer.py
gmyth-stream/server/0.1/plugins/media/mencoder.py
gmyth-stream/server/0.1/plugins/media/vlc.py
gmyth-stream/server/0.1/stream.conf
gmyth-stream/server/0.1/tests/client.py
gmyth-stream/server/0.2/gms.py
gmyth-stream/server/0.2/lib/__init__.py
gmyth-stream/server/0.2/lib/server.py
gmyth-stream/server/0.2/lib/utils.py
gmyth-stream/server/0.2/plugins/__init__.py
gmyth-stream/server/0.2/plugins/transcoders/__init__.py
gmyth-stream/server/0.2/plugins/transcoders/gstreamer.py
gmyth-stream/server/0.2/plugins/transcoders/mencoder.py
gmyth-stream/server/lib.py
gmyth-stream/server/main.py
gmyth-stream/server/plugins/__init__.py
gmyth-stream/server/plugins/comm/__init__.py
gmyth-stream/server/plugins/comm/tcp.py
gmyth-stream/server/plugins/comm/xmlrpc.py
gmyth-stream/server/plugins/media/__init__.py
gmyth-stream/server/plugins/media/ffmpeg.py
gmyth-stream/server/plugins/media/gstreamer-rtp.py
gmyth-stream/server/plugins/media/gstreamer.py
gmyth-stream/server/plugins/media/mencoder.py
gmyth-stream/server/plugins/media/vlc.py
gmyth-stream/server/stream.conf
gmyth-stream/server/tests/client.py
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gmyth-stream/server/0.1/lib.py	Wed Apr 18 15:59:10 2007 +0100
     1.3 @@ -0,0 +1,36 @@
     1.4 +import time
     1.5 +import logging
     1.6 +import os
     1.7 +import stat
     1.8 +
     1.9 +ext = ['mpg', 'avi', 'mp4', 'nuv', 'mpeg', 'mov']
    1.10 +
    1.11 +def now():
    1.12 +    return time.strftime("%Y-%m-%d %H:%M:%S");
    1.13 +
    1.14 +def log(msg):
    1.15 +    logging.log(logging.DEBUG, msg)
    1.16 +    new_msg = "[%s] %s" % (now(), msg)
    1.17 +    return new_msg
    1.18 +
    1.19 +
    1.20 +bin_path_list = os.environ["PATH"].split(os.pathsep)
    1.21 +def which(prg):
    1.22 +    for d in bin_path_list:
    1.23 +        path = os.path.join(d, prg)
    1.24 +        if os.path.exists(path):
    1.25 +            st = os.stat(path)
    1.26 +            if st[stat.ST_MODE] & 0111:
    1.27 +                return path
    1.28 +    return ""
    1.29 +
    1.30 +def list_media_files(directory, file_list):
    1.31 +    for root, dirs, files in os.walk(directory):
    1.32 +        for name in files:
    1.33 +            if os.path.splitext(name)[1].strip(".") in ext:
    1.34 +                media = os.path.join(root,name)
    1.35 +                if media not in file_list:
    1.36 +                    file_list.append(os.path.join(root,name))
    1.37 +
    1.38 +    return True
    1.39 +
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/gmyth-stream/server/0.1/main.py	Wed Apr 18 15:59:10 2007 +0100
     2.3 @@ -0,0 +1,185 @@
     2.4 +#!/usr/bin/python
     2.5 +
     2.6 +import os
     2.7 +import lib
     2.8 +import sys
     2.9 +import imp
    2.10 +import ConfigParser
    2.11 +import logging as log
    2.12 +
    2.13 +log.basicConfig(level=log.DEBUG,
    2.14 +                format="%(asctime)s %(levelname)-8s %(message)s",
    2.15 +                datefmt='%Y-%m-%d %H:%M:%S')
    2.16 +
    2.17 +config = ConfigParser.ConfigParser()
    2.18 +config.read("stream.conf")
    2.19 +
    2.20 +def load_module(pathlist, name):
    2.21 +    fp, path, desc = imp.find_module(name, pathlist)
    2.22 +    try:
    2.23 +        module = imp.load_module(name, fp, path, desc)
    2.24 +        return module
    2.25 +    finally:
    2.26 +        if fp:
    2.27 +            fp.close()
    2.28 +
    2.29 +
    2.30 +media_plugin = config.get("Media", "engine")
    2.31 +media_plugin_module = load_module(["./plugins/media"], media_plugin)
    2.32 +media = media_plugin_module.Media(config)
    2.33 +
    2.34 +comm_plugin = config.get("Comm", "engine")
    2.35 +comm_plugin_module = load_module(["./plugins/comm"], comm_plugin)
    2.36 +server = comm_plugin_module.Server(config)
    2.37 +
    2.38 +log.info("Starting GMyth-Stream server")
    2.39 +
    2.40 +
    2.41 +'''
    2.42 +PROTOCOL DESCRIPTION
    2.43 +=====================
    2.44 +
    2.45 +COMMAND OPTIONS
    2.46 +
    2.47 +-> SETUP DESCRIPTION
    2.48 +|-> used to setup transcoding and streaming parameters
    2.49 +|-> must be used before any "PLAY" command
    2.50 +|-> e.g:
    2.51 +
    2.52 +file://file_name mux vcodec vbitrate fps acodec abitrate width height options
    2.53 +dvd://title_number mux vcodec vbitrate fps acodec abitrate width height options
    2.54 +
    2.55 +-> PLAY DESCRIPTION
    2.56 + |-> used to start transcoding and streaming of file
    2.57 + |-> must be used just if SETUP was used before
    2.58 + |-> after it, _must_ send STOP
    2.59 +
    2.60 +-> STOP DESCRIPTION
    2.61 + |-> used to stop transcoding and streaming process
    2.62 + |-> must be used just if PLAY was used before
    2.63 + |-> must be used after PLAY
    2.64 +
    2.65 +-> QUIT DESCRIPTION
    2.66 + |-> used to quit the main loop (quit program)
    2.67 +
    2.68 +'''
    2.69 +nextport = 0
    2.70 +setup = (False, "STOPPED")
    2.71 +
    2.72 +def do_setup(server, filename, mux, vcodec, vbitrate, fps, acodec, abitrate,
    2.73 +             width, height, *options):
    2.74 +    global nextport
    2.75 +    global setup
    2.76 +
    2.77 +    if setup[1] != "PLAYING":
    2.78 +        nextport += 1
    2.79 +        ret = media.setup(filename, mux, vcodec, vbitrate, fps, acodec,
    2.80 +                          abitrate, width, height, nextport, options)
    2.81 +        if ret[0]:
    2.82 +            server.sendOk()
    2.83 +        else:
    2.84 +            server.sendNotOk(ret[1])
    2.85 +
    2.86 +        setup = (True, setup[1])
    2.87 +
    2.88 +    else: server.sendNotOk("You must STOP before SETingUP again")
    2.89 +
    2.90 +    return True
    2.91 +
    2.92 +def do_play(server):
    2.93 +    global setup
    2.94 +
    2.95 +    if setup[0] and setup[1] == "STOPPED":
    2.96 +        setup = (setup[0], "PLAYING")
    2.97 +        ret = media.play()
    2.98 +        if ret[0]:
    2.99 +            server.sendOk("%d" % nextport)
   2.100 +        else:
   2.101 +            server.sendNotOk(ret[1])
   2.102 +
   2.103 +    else:
   2.104 +        if setup[1] == "STOPPED":
   2.105 +            server.sendNotOk("You must SETUP before PLAYing")
   2.106 +        else:
   2.107 +            server.sendNotOk("You must STOP before PLAYing again")
   2.108 +
   2.109 +    return True
   2.110 +
   2.111 +def do_stop(server):
   2.112 +    global setup
   2.113 +
   2.114 +    media.stop()
   2.115 +    setup = (False, "STOPPED")
   2.116 +    server.sendOk()
   2.117 +    return True
   2.118 +
   2.119 +def do_list(server, *directory):
   2.120 +    file_list = []
   2.121 +    for j in directory:
   2.122 +        lib.list_media_files(j, file_list)
   2.123 +
   2.124 +    server.sendOk(file_list)
   2.125 +    return True
   2.126 +
   2.127 +def do_quit(server):
   2.128 +    server.finish = 1
   2.129 +    media.stop()
   2.130 +    server.sendOk()
   2.131 +    return True
   2.132 +
   2.133 +
   2.134 +mapping = {
   2.135 +    "SETUP": do_setup,
   2.136 +    "PLAY": do_play,
   2.137 +    "STOP": do_stop,
   2.138 +    "LIST": do_list,
   2.139 +    "QUIT": do_quit,
   2.140 +    }
   2.141 +
   2.142 +
   2.143 +def dispatch(server, msg):
   2.144 +    pieces = msg.split()
   2.145 +    if len(pieces) < 1:
   2.146 +        log.error("Invalid client command format: %r" % msg)
   2.147 +        server.sendNotOk("Invalid Format")
   2.148 +        return False
   2.149 +
   2.150 +    cmd = pieces[0]
   2.151 +    f = mapping.get(cmd, None)
   2.152 +    if not f:
   2.153 +        log.error("Unknow command: %r" % msg)
   2.154 +        server.sendNotOk("Unknow Command")
   2.155 +        return False
   2.156 +
   2.157 +    try:
   2.158 +        return f(server, *pieces[1:])
   2.159 +    except Exception, e:
   2.160 +        log.error("Could not execute %r: %s" % (msg, e))
   2.161 +        server.sendNotOk(str(e))
   2.162 +        return False
   2.163 +
   2.164 +
   2.165 +
   2.166 +while not server.finish:
   2.167 +    conn, client, port = server.getRequest()
   2.168 +    if nextport == 0:
   2.169 +        nextport = port
   2.170 +
   2.171 +    while not server.finish:
   2.172 +        msg = server.getMsg()
   2.173 +        if not msg:
   2.174 +            break
   2.175 +
   2.176 +        log.info("Client %s sent command: %r" % (client, msg))
   2.177 +        dispatch(server, msg)
   2.178 +
   2.179 +    log.info("Closing connection with %s" % (client,))
   2.180 +    server.disconnect_client(conn)
   2.181 +    try:
   2.182 +        os.wait()
   2.183 +    except Exception, e:
   2.184 +        log.error(e)
   2.185 +
   2.186 +server.stop()
   2.187 +log.info("Server stopped. Closing...")
   2.188 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/gmyth-stream/server/0.1/plugins/comm/tcp.py	Wed Apr 18 15:59:10 2007 +0100
     3.3 @@ -0,0 +1,79 @@
     3.4 +import lib
     3.5 +import time
     3.6 +import socket
     3.7 +import logging as log
     3.8 +
     3.9 +class Server(object):
    3.10 +
    3.11 +    def __init__(self, config):
    3.12 +        self.host = '0.0.0.0'
    3.13 +        self.port = int(config.get("Comm", "port"))
    3.14 +        self.finish = 0
    3.15 +
    3.16 +        addr = (self.host, self.port)
    3.17 +        log.debug("Setup TCP server at %s:%s" % addr)
    3.18 +        self.tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    3.19 +        self.tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    3.20 +        self.tcp.bind(addr)
    3.21 +        self.tcp.listen(1)
    3.22 +        log.info("TCP server listening at %s:%s (sock=%d)" %
    3.23 +                 (self.host, self.port, self.tcp.fileno()))
    3.24 +
    3.25 +    def getMsg(self):
    3.26 +        bytes = []
    3.27 +        try:
    3.28 +            while 1:
    3.29 +                c = self.con.recv(1)
    3.30 +                bytes.append(c)
    3.31 +                if not c or c == "\n":
    3.32 +                    break
    3.33 +        except Exception, e:
    3.34 +            log.error("Error reading message from client: %s" % e)
    3.35 +            return None
    3.36 +
    3.37 +        if not bytes or bytes[-1] != "\n":
    3.38 +            msg = "".join(bytes)
    3.39 +            log.error("Invalid message from client: %r" % msg)
    3.40 +            return None
    3.41 +
    3.42 +        # remove \n and \r
    3.43 +        bytes.pop()
    3.44 +        if bytes[-1] == "\r":
    3.45 +            bytes.pop()
    3.46 +
    3.47 +        msg = "".join(bytes)
    3.48 +        log.debug("RECV: %r" % msg)
    3.49 +        return msg
    3.50 +
    3.51 +    def sendMsg(self, msg):
    3.52 +        log.debug("SEND: %r" % msg)
    3.53 +        self.con.send(msg + "\n")
    3.54 +
    3.55 +    def sendOk(self, payload=None):
    3.56 +        self.sendMsg("OK %d" % bool(payload is not None))
    3.57 +        if payload is not None:
    3.58 +            if not isinstance(payload, (tuple, list)):
    3.59 +                payload = (payload,)
    3.60 +            for e in payload:
    3.61 +                self.sendMsg("+%s" % e)
    3.62 +            self.sendMsg(".")
    3.63 +
    3.64 +    def sendNotOk(self, reason=""):
    3.65 +        self.sendMsg("NOTOK %r" % reason)
    3.66 +
    3.67 +    def getRequest(self):
    3.68 +        log.debug("Wait for client request at %s:%s (sock=%d)" %
    3.69 +                  (self.host, self.port, self.tcp.fileno()))
    3.70 +        self.con, self.client = self.tcp.accept()
    3.71 +        log.info("Incoming request from %s (con=%s)" %
    3.72 +                 (self.client, self.con.fileno()))
    3.73 +        return (self.con, self.client, self.port)
    3.74 +
    3.75 +    def disconnect_client(self, connection):
    3.76 +        log.info("Closed request from %s (con=%s)" %
    3.77 +                 (self.client, self.con.fileno()))
    3.78 +        connection.close()
    3.79 +
    3.80 +    def stop(self):
    3.81 +        log.debug("Stop")
    3.82 +        self.tcp.close()
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/gmyth-stream/server/0.1/plugins/comm/xmlrpc.py	Wed Apr 18 15:59:10 2007 +0100
     4.3 @@ -0,0 +1,102 @@
     4.4 +import lib
     4.5 +import SimpleXMLRPCServer
     4.6 +
     4.7 +
     4.8 +class Handler:
     4.9 +
    4.10 +    def __init__(self, recv_pool, send_pool):
    4.11 +        self.recv_pool = recv_pool
    4.12 +        self.send_pool = send_pool
    4.13 +        self.getMsg = self.sendMsg
    4.14 +
    4.15 +    def _listMethods(self):
    4.16 +        return ['setup', 'play', 'stop', 'close', 'getMsg']
    4.17 +
    4.18 +    def _methodHelp(self, method):
    4.19 +
    4.20 +        if method == 'setup':
    4.21 +            return "Setup the Media: setup( filename, mux, vcodec, vbitrate,"\
    4.22 +                   " fps, acodec, abitrate, width, height, port, options"
    4.23 +        elif method == 'play':
    4.24 +            return "Play the Media: play()"
    4.25 +        elif method == 'stop':
    4.26 +            return "Stop the Media: stop()"
    4.27 +        elif method == 'close':
    4.28 +            return "Close the connection: close()"
    4.29 +        elif method == 'getMsg':
    4.30 +            return "Return the first message in the pool: getMsg()"
    4.31 +        else:
    4.32 +            # By convention, return empty
    4.33 +            # string if no help is available
    4.34 +            return ""
    4.35 +
    4.36 +    def setup(self, filename, mux, vcodec, vbitrate,\
    4.37 +            fps, acodec, abitrate, width, height, port, options):
    4.38 +
    4.39 +        msg = "%s %s %s %s %s %s %s" % (filename, mux, vcodec, vbitrate,\
    4.40 +                                        fps, acodec, abitrate, width, height, port)
    4.41 +
    4.42 +        if len(options) > 0:
    4.43 +            for opt in options:
    4.44 +                msg += " %s" % opt
    4.45 +
    4.46 +        self.recv_pool.append("SETUP")
    4.47 +        self.recv_pool.append(msg)
    4.48 +        return self.sendMsg()
    4.49 +
    4.50 +    def play(self):
    4.51 +        self.recv_pool.append("PLAY")
    4.52 +        return self.sendMsg()
    4.53 +
    4.54 +    def stop(self):
    4.55 +        self.recv_pool.append("STOP")
    4.56 +        return self.sendMsg()
    4.57 +
    4.58 +    def close(self):
    4.59 +        self.recv_pool.append("CLOSE")
    4.60 +        return self.sendMsg()
    4.61 +
    4.62 +    def sendMsg(self):
    4.63 +        if self.send_pool != []:
    4.64 +            return self.send_pool.pop(0)
    4.65 +        else:
    4.66 +            return ""
    4.67 +
    4.68 +
    4.69 +class Server:
    4.70 +
    4.71 +    def __init__(self, config):
    4.72 +        self.host = 'localhost'
    4.73 +        self.port = int(config.get("Comm", "port"))
    4.74 +        self.finish = 0
    4.75 +        self.recv_pool = []
    4.76 +        self.send_pool = []
    4.77 +
    4.78 +        self.handler = Handler(self.recv_pool, self.send_pool)
    4.79 +
    4.80 +        self.xmlrpc = SimpleXMLRPCServer.SimpleXMLRPCServer((self.host, self.port))
    4.81 +        self.xmlrpc.register_instance(self.handler)
    4.82 +
    4.83 +
    4.84 +    def getMsg(self, size):
    4.85 +        if self.recv_pool != []:
    4.86 +            return self.recv_pool.pop(0)
    4.87 +        else:
    4.88 +            return ""
    4.89 +
    4.90 +    def sendMsg(self, msg):
    4.91 +        self.send_pool.append(msg)
    4.92 +
    4.93 +    def Ack(self, command):
    4.94 +        msg = "[%s] Command %s received" % (lib.now(), command)
    4.95 +        self.sendMsg(msg + "\n")
    4.96 +
    4.97 +    def getRequest(self):
    4.98 +        self.xmlrpc.handle_request()
    4.99 +        return (0, "RPC Client")
   4.100 +
   4.101 +    def disconnect_client(self, connection):
   4.102 +        connection = 0
   4.103 +
   4.104 +    def stop(self):
   4.105 +        self.xmlrpc.server_close()
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/gmyth-stream/server/0.1/plugins/media/ffmpeg.py	Wed Apr 18 15:59:10 2007 +0100
     5.3 @@ -0,0 +1,91 @@
     5.4 +import os
     5.5 +import sys
     5.6 +import lib
     5.7 +import time
     5.8 +import socket
     5.9 +import ConfigParser
    5.10 +
    5.11 +class Media:
    5.12 +
    5.13 +    def __init__(self, config):
    5.14 +
    5.15 +        self.config = config
    5.16 +        self.socket = None
    5.17 +        self.child_pid = None
    5.18 +
    5.19 +    def setup(self, filename, mux, vcodec, vbitrate,\
    5.20 +              fps, acodec, abitrate, width, height, port):
    5.21 +
    5.22 +        self.filename = filename
    5.23 +        self.mux = mux
    5.24 +        self.vcodec = vcodec
    5.25 +        self.vbitrate = int(vbitrate)
    5.26 +        self.fps = int(fps)
    5.27 +        self.acodec = acodec
    5.28 +        self.abitrate = int(abitrate)
    5.29 +        self.width = int(width)
    5.30 +        self.height = int(height)
    5.31 +
    5.32 +        self.port = int(port)
    5.33 +
    5.34 +        # good one: /tmp/mpg/cpm.mpg mpeg mpeg1video 400 25 mp2 192 320 240 5000
    5.35 +        self.path = self.config.get("FFmpeg", "path")
    5.36 +        self.path += " -i %s -f %s -vcodec %s -b %d -r %d -acodec %s -ab %d -s %dx%d -" % (
    5.37 +            self.filename, self.mux, self.vcodec, self.vbitrate,\
    5.38 +            self.fps, self.acodec, self.abitrate, self.width, self.height)
    5.39 +
    5.40 +        if (self.socket != None):
    5.41 +            del(self.socket)
    5.42 +
    5.43 +        self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    5.44 +        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    5.45 +        self.socket.bind( ('', self.port) )
    5.46 +        self.socket.settimeout(10)
    5.47 +        self.socket.listen(1)
    5.48 +
    5.49 +    def play(self):
    5.50 +
    5.51 +        lib.log("Starting FFmpeg: %s" % self.path)
    5.52 +
    5.53 +        # exec FFmpeg and get stdout
    5.54 +        child_stdin, child_stdout = os.popen2(self.path)
    5.55 +        child_stdin.close()
    5.56 +
    5.57 +        self.child_pid = os.fork()
    5.58 +        if (self.child_pid == 0):
    5.59 +            #child
    5.60 +
    5.61 +            conn,addr= self.socket.accept()
    5.62 +            lib.log("Sending Data to client: %s" % addr[0])
    5.63 +            data = child_stdout.read(1024)
    5.64 +            conn.settimeout(5)
    5.65 +            retry = 0
    5.66 +
    5.67 +            while( data != "" and retry < 5):
    5.68 +                try:
    5.69 +                    conn.send(data)
    5.70 +                except socket.error:
    5.71 +                    lib.log("Socket error (maybe timeout ?)")
    5.72 +                    retry = retry + 1
    5.73 +
    5.74 +                data = child_stdout.read(1024)
    5.75 +
    5.76 +            if (retry < 5):
    5.77 +                lib.log("Finished sending Data to client: %s" % addr[0])
    5.78 +            else:
    5.79 +                lib.log("Client timed out")
    5.80 +
    5.81 +            child_stdout.close()
    5.82 +            #conn.close()
    5.83 +            #sys.exit()
    5.84 +
    5.85 +
    5.86 +    def stop(self):
    5.87 +
    5.88 +        if (self.socket != None):
    5.89 +            lib.log("Closing socket")
    5.90 +            self.socket.close()
    5.91 +
    5.92 +        lib.log("Trying to stop FFmpeg process")
    5.93 +        if (self.child_pid != None):
    5.94 +            os.kill(self.child_pid, 9)
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/gmyth-stream/server/0.1/plugins/media/gstreamer-rtp.py	Wed Apr 18 15:59:10 2007 +0100
     6.3 @@ -0,0 +1,218 @@
     6.4 +import pygst
     6.5 +pygst.require("0.10")
     6.6 +import gst
     6.7 +import gobject
     6.8 +
     6.9 +class Media:
    6.10 +    class StreamData:
    6.11 +        stream_count = 0
    6.12 +		
    6.13 +        def __init__ (self, pipe, abin, vbin):
    6.14 +
    6.15 +	    self.stream_count += 1
    6.16 +	    self.Id = self.stream_count
    6.17 +	    self.Pipe = pipe
    6.18 +	    self.Abin = abin
    6.19 +	    self.Vbin = vbin
    6.20 +	    self.Loop = gobject.MainLoop()
    6.21 +	    self.ACaps = ""
    6.22 +	    self.VCaps = ""
    6.23 +	    self.Ready = False
    6.24 +
    6.25 +
    6.26 +    def __init__(self, config):
    6.27 +        # set gstreamer basic options
    6.28 +        self.config = config
    6.29 +        self.pipe = None
    6.30 +        self.streams = []
    6.31 +
    6.32 +
    6.33 +    def setup(self, filename, mux, vcodec, vbitrate,
    6.34 +              fps, acodec, abitrate, width, height, port, options):
    6.35 +
    6.36 +        ## Pipelines
    6.37 +        self.pipe = gst.Pipeline ()
    6.38 +        uri = "file://" + filename
    6.39 +        print "Opening Uri:" + uri
    6.40 +        src = gst.element_make_from_uri (gst.URI_SRC, uri, "src")
    6.41 +        if (src is None):
    6.42 +            return None
    6.43 +        
    6.44 +        decode = gst.element_factory_make ("decodebin", "decode")
    6.45 +        if (decode is None):
    6.46 +            return None
    6.47 +        
    6.48 +        
    6.49 +        #video encode 
    6.50 +        #queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! videorate ! ffenc_h263p bitrate=256000 me-method=2 ! rtph263ppay ! udpsink  host=224.0.0.1 port=5000
    6.51 +        vbin = gst.Bin ()
    6.52 +        vqueue = gst.element_factory_make ("queue", "vqueue")
    6.53 +        vscale = gst.element_factory_make ("videoscale", "vscale")
    6.54 +        vrate = gst.element_factory_make ("videorate", "vrate")
    6.55 +        vencode = gst.element_factory_make ("ffenc_mpeg4", "vencode")
    6.56 +        vpay = gst.element_factory_make ("rtpmp4vpay", "vpay")
    6.57 +        vsink = gst.element_factory_make ("udpsink", "vsink")
    6.58 +
    6.59 +        if (None in [vbin, vqueue, vscale, vrate, vencode, vpay, vsink]):
    6.60 +            print "Fail to create video encode elements."
    6.61 +            return None
    6.62 +
    6.63 +        vscale_pad = vscale.get_pad("sink")
    6.64 +        if (vscale_pad is None):
    6.65 +            print "Fail to get vscale sink pad."
    6.66 +            return None
    6.67 +
    6.68 +        vscale_caps = gst.caps_from_string ("video/x-raw-yuv, width=%s, height=%s" % (width, height))
    6.69 +        if (vscale_caps is None):
    6.70 +            print "Fail to create video caps"
    6.71 +            return None
    6.72 +
    6.73 +        if (not vscale_pad.set_caps (vscale_caps)):
    6.74 +            print "Fail to set video output caps"
    6.75 +            return None
    6.76 +        
    6.77 +        vencode.set_property ("bitrate", 256000)
    6.78 +        vencode.set_property ("me-method", 2)
    6.79 +        
    6.80 +        vsink.set_property ("host", "224.0.0.1")
    6.81 +        vsink.set_property ("port", 5000)
    6.82 +        
    6.83 +        vbin.add (vqueue, vscale, vrate, vencode, vpay, vsink)
    6.84 +        if (not gst.element_link_many (vqueue,  vscale, vrate, vencode, vpay, vsink)):
    6.85 +            print "Fail to link video elements"
    6.86 +            return None
    6.87 +        
    6.88 +        vbin.add_pad (gst.GhostPad ("sink", vqueue.get_pad ("sink")))
    6.89 +
    6.90 +        #audio encode
    6.91 +        #audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay !  udpsink name=upd_audio host=224.0.0.1 port=5002
    6.92 +        abin = gst.Bin ()
    6.93 +        aqueue = gst.element_factory_make ("queue", "vqueue")
    6.94 +        aconvert = gst.element_factory_make ("audioconvert", "aconvert")
    6.95 +        aencode = gst.element_factory_make ("faac", "aencode")
    6.96 +        apay = gst.element_factory_make ("rtpmp4gpay", "apay")
    6.97 +        asink = gst.element_factory_make ("udpsink", "asink")
    6.98 +
    6.99 +        if (None in [abin, aqueue, aconvert, aencode, apay, asink]):
   6.100 +            print "Fail to create video encode elements."
   6.101 +            return None
   6.102 +
   6.103 +        asink.set_property ("host", "224.0.0.1")
   6.104 +        asink.set_property ("port", 5002)
   6.105 +        
   6.106 +        abin.add (aqueue, aconvert, aencode, apay, asink)
   6.107 +        if (not gst.element_link_many (aqueue, aconvert, aencode, apay, asink)):
   6.108 +            print "Fail to link video elements"
   6.109 +            return None
   6.110 +        
   6.111 +        abin.add_pad (gst.GhostPad ("sink", aqueue.get_pad ("sink")))
   6.112 +
   6.113 +	self.pipe.add (src, decode, abin, vbin)
   6.114 +	gst.element_link_many (src, decode)
   6.115 +
   6.116 +	stream_data = self.StreamData (self.pipe, abin, vbin)
   6.117 +
   6.118 +	bus = self.pipe.get_bus()
   6.119 +	bus.add_signal_watch()
   6.120 +	bus.connect("message", self.__on_bus_message, stream_data)
   6.121 +	
   6.122 +	decode.connect("new-decoded-pad", self.__on_decode_new_pad, stream_data)
   6.123 +	decode.connect("unknown-type", self.__on_decode_unknown_type, stream_data)
   6.124 +
   6.125 +	
   6.126 +	self.pipe.set_state (gst.STATE_PAUSED)
   6.127 +        print "Running Pipe"
   6.128 +	stream_data.Loop.run ()
   6.129 +        print "End run"
   6.130 +
   6.131 +	a_caps = stream_data.ACaps
   6.132 +	v_caps = stream_data.VCaps
   6.133 +	stream_id = stream_data.Id
   6.134 +
   6.135 +        self.streams.append (stream_data)
   6.136 +
   6.137 +    def play(self):
   6.138 +
   6.139 +        print "Trying to play pipeline: %s" % self.pipe
   6.140 +        try:
   6.141 +            if (self.pipe):
   6.142 +                self.pipe.set_state(gst.STATE_PLAYING)
   6.143 +        except gobject.GError, e:
   6.144 +            print "Error: " + str(e)
   6.145 +
   6.146 +
   6.147 +    def stop(self):
   6.148 +
   6.149 +        print "Trying to stop pipeline: %s" % self.pipe
   6.150 +        try:
   6.151 +            if (self.pipeline):
   6.152 +                self.pipeline.set_state(gst.STATE_NULL)
   6.153 +        except gobject.GError, e:
   6.154 +            print "Error: " + str(e)
   6.155 +
   6.156 +    def __on_bus_message (self, bus, message, stream_data):
   6.157 +
   6.158 +        t = message.type
   6.159 +        if (t == gst.MESSAGE_STATE_CHANGED):
   6.160 +            oldstate = -1
   6.161 +            newstate = -1
   6.162 +            pending = -1
   6.163 +            oldstate, newstate, pending = message.parse_state_changed ()
   6.164 +            if ((oldstate == gst.STATE_READY) and \
   6.165 +                (newstate == gst.STATE_PAUSED) and \
   6.166 +                (pending == gst.STATE_VOID_PENDING) and \
   6.167 +                (stream_data.Ready == False)):
   6.168 +                state_changed_status, current_state, pending_state = stream_data.Pipe.get_state () 
   6.169 +		if ((current_state == gst.STATE_PAUSED) and \
   6.170 +                    (pending_state == gst.STATE_VOID_PENDING)):
   6.171 +                    print "Pipe paused"
   6.172 +                    self.__fill_sink_pads (stream_data)
   6.173 +                    stream_data.Loop.quit ()
   6.174 +                    stream_data.Ready = True
   6.175 +        elif (t == gst.MESSAGE_ERROR):
   6.176 +            err, debug = message.parse_error()
   6.177 +	    print "Error: %s" % err, debug
   6.178 +            stream_data.Loop.quit ()
   6.179 +            stream_data.Ready = False
   6.180 +
   6.181 +        return True
   6.182 + 
   6.183 +
   6.184 +    def __fill_sink_pads (self, stream_data):
   6.185 +        
   6.186 +        asink = stream_data.Abin.get_by_name ("asink")
   6.187 +        vsink = stream_data.Vbin.get_by_name ("vsink")
   6.188 +
   6.189 +        asink_pad = asink.get_pad ("sink")
   6.190 +        stream_data.ACaps = asink_pad.get_negotiated_caps().to_string()
   6.191 +        print "ACAPS " + stream_data.ACaps
   6.192 +
   6.193 +        vsink_pad = vsink.get_pad ("sink")
   6.194 +        stream_data.VCaps = vsink_pad.get_negotiated_caps().to_string()
   6.195 +        print "ACAPS " + stream_data.VCaps
   6.196 + 
   6.197 + 
   6.198 +
   6.199 +    def __on_decode_unknown_type (self, decode, pad, caps, stream_data):
   6.200 +
   6.201 +        print "Unknown Type"
   6.202 +        return None
   6.203 +
   6.204 +    def __on_decode_new_pad (self, decode, pad, arg1, stream_data):
   6.205 +        
   6.206 +        caps = pad.get_caps().to_string()
   6.207 +        print "New pad " + caps
   6.208 +	if (caps.rfind ("audio") != -1):
   6.209 +            apad = stream_data.Abin.get_pad ("sink")
   6.210 +            if (pad.link (apad) != gst.PAD_LINK_OK):
   6.211 +                print "Error on link audio pad"
   6.212 +                return None
   6.213 +        elif (caps.rfind ("video") != -1):
   6.214 +            vpad = stream_data.Vbin.get_pad ("sink")
   6.215 +            if (pad.link (vpad) != gst.PAD_LINK_OK):
   6.216 +                print "Error on link video pad"
   6.217 +                return None
   6.218 +        else:
   6.219 +            print "Invalid caps"
   6.220 +
   6.221 +            
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/gmyth-stream/server/0.1/plugins/media/gstreamer.py	Wed Apr 18 15:59:10 2007 +0100
     7.3 @@ -0,0 +1,290 @@
     7.4 +#vim:ts=4:sw=4:et
     7.5 +import pygst
     7.6 +pygst.require("0.10")
     7.7 +import gst
     7.8 +import gobject
     7.9 +import socket
    7.10 +import time
    7.11 +from threading import Thread
    7.12 +
    7.13 +class Media:
    7.14 +    class StreamListener(Thread):
    7.15 +        def __init__ (self, stream_data):
    7.16 +            Thread.__init__(self)
    7.17 +            self.stream = stream_data
    7.18 +            print "Thread Created"
    7.19 +
    7.20 +        def run (self):
    7.21 +            #Create socket
    7.22 +            print "Waiting connection"
    7.23 +            self.stream.Socket.listen(1)
    7.24 +            self.stream.Connection, self.stream.Addr = self.stream.Socket.accept ()
    7.25 +            print "Connection requested"
    7.26 +            self.stream.Sink.set_property ("fd", self.stream.Connection.fileno())
    7.27 +            self.stream.Pipe.set_state(gst.STATE_PLAYING)
    7.28 +            print "PLAYING"
    7.29 +
    7.30 +
    7.31 +    class StreamData:
    7.32 +        stream_count = 0
    7.33 +
    7.34 +        def __init__ (self, pipe, abin, vbin, sink):
    7.35 +            self.stream_count += 1
    7.36 +            self.Id = self.stream_count
    7.37 +            self.Pipe = pipe
    7.38 +            self.Abin = abin
    7.39 +            self.Vbin = vbin
    7.40 +            self.Sink = sink
    7.41 +            self.Loop = gobject.MainLoop()
    7.42 +            self.ACaps = ""
    7.43 +            self.VCaps = ""
    7.44 +            self.Ready = False
    7.45 +            self.Socket = None
    7.46 +            self.Connection = None
    7.47 +            self.Addr = None
    7.48 +
    7.49 +    def __init__(self, config):
    7.50 +        # set gstreamer basic options
    7.51 +        self.config = config
    7.52 +        self.streams = []
    7.53 +        self.socket = None
    7.54 +        self.connection = None
    7.55 +        self.addr = None
    7.56 +        self.ready = False
    7.57 +		self.current = None
    7.58 +
    7.59 +
    7.60 +    def setup(self, uri, mux, vcodec, vbitrate,
    7.61 +              fps, acodec, abitrate, width, height, port, options):
    7.62 +
    7.63 +        ## Pipelines
    7.64 +        pipe = gst.Pipeline ()
    7.65 +        print "Opening Uri:" + uri
    7.66 +        src = gst.element_make_from_uri (gst.URI_SRC, uri, "src")
    7.67 +        #src = gst.element_factory_make ("gnomevfssrc", "src")
    7.68 +        src.set_property ("location", uri)
    7.69 +        if (src is None):
    7.70 +            print "Fail to create src element"
    7.71 +            return None
    7.72 +
    7.73 +        print ("Create source")
    7.74 +        decode = gst.element_factory_make ("decodebin", "decode")
    7.75 +        if (decode is None):
    7.76 +            print "Fail to create decodebin"
    7.77 +            return None
    7.78 +
    7.79 +        print ("Create source")
    7.80 +        mux = gst.element_factory_make ("avimux", "mux")
    7.81 +        if (mux is None):
    7.82 +            print "Fail to create mux"
    7.83 +            return None
    7.84 +
    7.85 +        sink = gst.element_factory_make ("fdsink", "sink")
    7.86 +        if (sink is None):
    7.87 +            print "Fail to create fdsink"
    7.88 +            return None
    7.89 +
    7.90 +        print ("Create source")
    7.91 +
    7.92 +        #video encode
    7.93 +        #queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! videorate ! ffenc_h263p bitrate=256000 me-method=2 ! rtph263ppay ! udpsink  host=224.0.0.1 port=5000
    7.94 +        vbin = gst.Bin ()
    7.95 +        vqueue = gst.element_factory_make ("queue", "vqueue")
    7.96 +        colorspace = gst.element_factory_make ("ffmpegcolorspace", "")
    7.97 +        vrate = gst.element_factory_make ("videorate", "vrate")
    7.98 +        vencode = gst.element_factory_make ("ffenc_mpeg4", "vencode")
    7.99 +        #vencode = gst.element_factory_make ("ffenc_msmpeg4v1", "vencode")
   7.100 +        vqueue_src = gst.element_factory_make ("queue", "vqueue_src")
   7.101 +
   7.102 +        #if (int(vbitrate) > 0):
   7.103 +        vencode.set_property ("bitrate", 200)
   7.104 +        #vencode.set_property ("quant-type", 1)
   7.105 +        vencode.set_property ("pass", 2)
   7.106 +        vencode.set_property ("quantizer", 5)
   7.107 +        #vencode.set_property ("me-method", 1)
   7.108 +
   7.109 +
   7.110 +        if (None in [vbin, vqueue, vrate, vencode, vqueue_src]):
   7.111 +            print "Fail to create video encode elements."
   7.112 +            return None
   7.113 +
   7.114 +        vbin.add (vqueue)
   7.115 +        if ((int(width) > 0) and (int(height) > 0)):
   7.116 +            print ("formating output to %d / %d" % (int(width), int(height)))
   7.117 +  
   7.118 +            vscale = gst.element_factory_make ("ffvideoscale", "vscale")
   7.119 +
   7.120 +            vbin.add (vscale);
   7.121 +            if (not vqueue.link (vscale)):
   7.122 +                print "Fail to link video elements"
   7.123 +                return None
   7.124 +
   7.125 +            vbin.add (colorspace)
   7.126 +
   7.127 +            if (not vscale.link (colorspace, \
   7.128 +                gst.caps_from_string ("video/x-raw-yuv,width=(int)%d,height=(int)%d" % (int(width), int(height))))):
   7.129 +                print "Fail to link video elements"
   7.130 +                return None
   7.131 +        else:                
   7.132 +            vbin.add (colorspace)
   7.133 +            vqueue.link (colorspace)
   7.134 +        
   7.135 +        vbin.add (vrate, vencode, vqueue_src)
   7.136 +        if (not colorspace.link (vrate)):
   7.137 +            print "Fail to colorspace with vrate"
   7.138 +            return None
   7.139 +
   7.140 +
   7.141 +        if (not vrate.link (vencode, \
   7.142 +            gst.caps_from_string ("video/x-raw-yuv,framerate=(fraction)10/1"))):
   7.143 +            print "Fail to link vrate element"
   7.144 +            return None
   7.145 +
   7.146 +        if (not vencode.link (vqueue_src)):
   7.147 +            print "Fail to link video encode with queue"
   7.148 +            return None
   7.149 +
   7.150 +        vbin.add_pad (gst.GhostPad ("sink", vqueue.get_pad ("sink")))
   7.151 +        vbin.add_pad (gst.GhostPad ("src", vqueue_src.get_pad ("src")))
   7.152 +
   7.153 +        #audio encode
   7.154 +        #audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay !  udpsink name=upd_audio host=224.0.0.1 port=5002
   7.155 +        abin = gst.Bin ()
   7.156 +        aqueue = gst.element_factory_make ("queue", "aqueue")
   7.157 +        aconvert = gst.element_factory_make ("audioconvert", "aconvert")
   7.158 +        arate = gst.element_factory_make ("audioresample", "arate")
   7.159 +        #aencode = gst.element_factory_make ("ffenc_ac3", "aencode")
   7.160 +        aencode = gst.element_factory_make ("queue", "aencode")
   7.161 +        #aencode = gst.element_factory_make ("lame", "aencode")
   7.162 +        #aencode = gst.element_factory_make ("ffenc_mp2", "aencode")
   7.163 +        aqueue_src = gst.element_factory_make ("queue", "aqueue_src")
   7.164 +
   7.165 +        if (None in [abin, aqueue, arate, aencode, aqueue_src]):
   7.166 +            print "Fail to create video encode elements."
   7.167 +            return None
   7.168 +
   7.169 +        abin.add (aqueue, aconvert, arate, aencode, aqueue_src)
   7.170 +        if (not gst.element_link_many (aqueue,  aconvert, arate, aencode, aqueue_src)):
   7.171 +            print "Fail to link video elements"
   7.172 +            return None
   7.173 +
   7.174 +        abin.add_pad (gst.GhostPad ("sink", aqueue.get_pad ("sink")))
   7.175 +        abin.add_pad (gst.GhostPad ("src", aqueue_src.get_pad ("src")))
   7.176 +
   7.177 +        #Finish Pipeline
   7.178 +        pipe.add (src, decode, abin, vbin, mux, sink)
   7.179 +        gst.element_link_many (src, decode)
   7.180 +        gst.element_link_many (mux, sink)
   7.181 +
   7.182 +        #Linking decode with mux
   7.183 +        mux_audio = mux.get_pad ("audio_0")
   7.184 +        mux_video = mux.get_pad ("video_0")
   7.185 +
   7.186 +        audio_pad = abin.get_pad ("src")
   7.187 +        video_pad = vbin.get_pad ("src")
   7.188 +
   7.189 +        if (audio_pad.link (mux_audio) != gst.PAD_LINK_OK):
   7.190 +            print "Fail to link audio with mux"
   7.191 +            return None
   7.192 +
   7.193 +        if (video_pad.link (mux_video) != gst.PAD_LINK_OK):
   7.194 +            print "Fail to link audio with mux"
   7.195 +            return None
   7.196 +
   7.197 +        stream_data = self.StreamData (pipe, abin, vbin, sink)
   7.198 +        bus = pipe.get_bus()
   7.199 +        bus.add_signal_watch()
   7.200 +        bus.connect ("message", self.__on_bus_message, stream_data)
   7.201 +
   7.202 +        decode.connect("new-decoded-pad", self.__on_decode_new_pad, stream_data)
   7.203 +        decode.connect("unknown-type", self.__on_decode_unknown_type, stream_data)
   7.204 +
   7.205 +        print ("Create source")
   7.206 +        pipe.set_state (gst.STATE_PAUSED)
   7.207 +        print "Running Pipe"
   7.208 +        stream_data.Loop.run ()
   7.209 +        print "End run"
   7.210 +
   7.211 +
   7.212 +        #Create socket
   7.213 +        stream_data.Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   7.214 +        print "Bind on port %d" % port
   7.215 +        stream_data.Socket.bind(('', int (port)))
   7.216 +        self.streams.append (stream_data)
   7.217 +        return (True, "")
   7.218 +
   7.219 +    def play(self):
   7.220 +        print "Play"
   7.221 +        stream = self.streams[0]
   7.222 +        self.current = self.StreamListener(stream)
   7.223 +        self.current.start ()
   7.224 +        time.sleep (1)
   7.225 +        return (True, "")
   7.226 +
   7.227 +    def stop(self):
   7.228 +		self.current.join ()
   7.229 +        self.current = None
   7.230 +        stream = self.streams[0]
   7.231 +        stream.Pipe.set_state(gst.STATE_NULL)
   7.232 +        del (stream.Pipe)
   7.233 +        stream.Pipe = None
   7.234 +        stream.Abin = None
   7.235 +        stream.Vbin = None
   7.236 +        stream.Sink = None
   7.237 +		if (stream.Connection != None):
   7.238 +	        stream.Connection.close ()
   7.239 +
   7.240 +        self.streams = []
   7.241 +        time.sleep (5)             
   7.242 +        return (True, "")
   7.243 +
   7.244 +
   7.245 +    def __on_bus_message (self, bus, message, stream_data):
   7.246 +
   7.247 +        t = message.type
   7.248 +        if (t == gst.MESSAGE_STATE_CHANGED):
   7.249 +            oldstate = -1
   7.250 +            newstate = -1
   7.251 +            pending = -1
   7.252 +            oldstate, newstate, pending = message.parse_state_changed ()
   7.253 +            if ((oldstate == gst.STATE_READY) and \
   7.254 +                (newstate == gst.STATE_PAUSED) and \
   7.255 +                (pending == gst.STATE_VOID_PENDING) and \
   7.256 +                (stream_data.Ready == False)):
   7.257 +                state_changed_status, current_state, pending_state = stream_data.Pipe.get_state ()
   7.258 +                if ((current_state == gst.STATE_PAUSED) and \
   7.259 +                    (pending_state == gst.STATE_VOID_PENDING)):
   7.260 +                    print "Pipe paused"
   7.261 +                    stream_data.Loop.quit ()
   7.262 +                    stream_data.Ready = True
   7.263 +        elif (t == gst.MESSAGE_ERROR):
   7.264 +            err, debug = message.parse_error()
   7.265 +            print "Error: %s" % err, debug
   7.266 +            stream_data.Loop.quit ()
   7.267 +            stream_data.Ready = False
   7.268 +
   7.269 +        return True
   7.270 +
   7.271 +    def __on_decode_unknown_type (self, decode, pad, caps, stream_data):
   7.272 +
   7.273 +        print "Unknown Type"
   7.274 +        return None
   7.275 +
   7.276 +    def __on_decode_new_pad (self, decode, pad, arg1, stream_data):
   7.277 +
   7.278 +        caps = pad.get_caps().to_string()
   7.279 +        print "New pad " + caps
   7.280 +        if (caps.rfind ("audio") != -1):
   7.281 +            apad = stream_data.Abin.get_pad ("sink")
   7.282 +            if (pad.link (apad) != gst.PAD_LINK_OK):
   7.283 +                print "Error on link audio pad"
   7.284 +                return None
   7.285 +        elif (caps.rfind ("video") != -1):
   7.286 +            vpad = stream_data.Vbin.get_pad ("sink")
   7.287 +            if (pad.link (vpad) != gst.PAD_LINK_OK):
   7.288 +                print "Error on link video pad"
   7.289 +                return None
   7.290 +        else:
   7.291 +            print "Invalid caps"
   7.292 +        print "Linked"            
   7.293 +
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/gmyth-stream/server/0.1/plugins/media/mencoder.py	Wed Apr 18 15:59:10 2007 +0100
     8.3 @@ -0,0 +1,411 @@
     8.4 +from __future__ import division
     8.5 +
     8.6 +import os
     8.7 +import sys
     8.8 +import lib
     8.9 +import time
    8.10 +import shlex
    8.11 +import signal
    8.12 +import socket
    8.13 +import ConfigParser
    8.14 +import logging as log
    8.15 +
    8.16 +from select import *
    8.17 +from subprocess import *
    8.18 +
    8.19 +class Media(object):
    8.20 +
    8.21 +    def __init__(self, config):
    8.22 +
    8.23 +        self.config = config
    8.24 +        self.do_cleanup()
    8.25 +
    8.26 +    # __init__()
    8.27 +
    8.28 +
    8.29 +    def do_cleanup(self):
    8.30 +        self.path = ""
    8.31 +        self.args = []
    8.32 +        self.language = None
    8.33 +        self.subtitle = None
    8.34 +        self.mpegopts = None
    8.35 +        self.socket = None
    8.36 +        self.child_pid = None
    8.37 +        self.mplayer = None
    8.38 +        self.mencoder_pid = None
    8.39 +        self.mplayer_pid = None
    8.40 +        self.audio_opts = None
    8.41 +        self.video_opts = None
    8.42 +        self.gst_pipe = None
    8.43 +        self.gst_pid = None
    8.44 +        self.transcode_local = None
    8.45 +
    8.46 +    # do_cleanup()
    8.47 +
    8.48 +
    8.49 +    def setup_opts(self, options):
    8.50 +
    8.51 +        for opt in options:
    8.52 +
    8.53 +            if opt == "local":
    8.54 +                self.mplayer = lib.which("mplayer")
    8.55 +
    8.56 +            elif opt.find("language=") >= 0:
    8.57 +                try:
    8.58 +                    lan = opt.split("=")[1]
    8.59 +                    if len(lan) < 2:
    8.60 +                        self.language = lan
    8.61 +                except Exception, e:
    8.62 +                    log.error("Bad language option: %s" % opt)
    8.63 +
    8.64 +            elif opt.find("subtitle=") >= 0:
    8.65 +                try:
    8.66 +                    sub = opt.split("=")[1]
    8.67 +                    if len(sub) < 2:
    8.68 +                        self.language = sub
    8.69 +                except Exception, e:
    8.70 +                    log.error("Bad subtitle option: %s" % opt)
    8.71 +
    8.72 +            elif opt.find("format=") >= 0:
    8.73 +                try:
    8.74 +                    self.mpegopts = opt.split("=")[1]
    8.75 +                except Exception, e:
    8.76 +                    log.error("Bad format option: %s" % opt)
    8.77 +
    8.78 +            elif opt.find("outfile=") >= 0:
    8.79 +                try:
    8.80 +                    self.transcode_local = opt.split("=")[1]
    8.81 +                except Exception, e:
    8.82 +                    log.error("Bad outfile option: %s" % opt)
    8.83 +
    8.84 +    # setup_opts()
    8.85 +
    8.86 +
    8.87 +    def run_mplayer(self):
    8.88 +        msg = self.filename
    8.89 +
    8.90 +        if self.kind == "dvd":
    8.91 +            msg = "dvd://" + msg
    8.92 +
    8.93 +        self.mplayer_pid = Popen([self.mplayer, self.filename, "1> %s" % os.devnull,\
    8.94 +                                  "2> %s" % os.devnull], stdout=PIPE, close_fds=True)
    8.95 +
    8.96 +    # run_mplayer()
    8.97 +
    8.98 +
    8.99 +    def setup_mencoder(self):
   8.100 +        self.path = self.config.get("Mencoder", "path")
   8.101 +        mp = Popen([self.path], stdout=PIPE, close_fds=True)
   8.102 +
   8.103 +        version = mp.stdout.read().split("MEncoder ")[1].split(" (C)")[0].split("-")[-1]
   8.104 +
   8.105 +        if version > "4.1.1": self.mencoder_old = False
   8.106 +        else: self.mencoder_old = True
   8.107 +
   8.108 +        os.kill(mp.pid, signal.SIGKILL)
   8.109 +        log.info("Mencoder version: %s" % version)
   8.110 +
   8.111 +        if self.mencoder_old:
   8.112 +            try:
   8.113 +                self.fifo = self.config.get("Mencoder", "fifo_path")
   8.114 +                os.mkfifo(self.fifo)
   8.115 +            except Exception, e:
   8.116 +                log.info("Fifo: %s" % e)
   8.117 +        else:
   8.118 +            self.fifo = "-"
   8.119 +
   8.120 +    # setup_mencoder()
   8.121 +
   8.122 +
   8.123 +    def setup_audio(self):
   8.124 +
   8.125 +        if self.acodec == "mp3lame":
   8.126 +            return "-oac mp3lame -lameopts cbr:br=%s vol=5" % self.abitrate
   8.127 +        else:
   8.128 +            return "-oac lavc -lavcopts acodec=%s:abitrate=%s" % (\
   8.129 +                self.acodec, self.abitrate)
   8.130 +
   8.131 +    # setup_audio()
   8.132 +
   8.133 +
   8.134 +    def setup_video(self):
   8.135 +
   8.136 +        video = ""
   8.137 +
   8.138 +        video += " -of %s" % self.mux
   8.139 +        video += " -ofps %s" % self.fps
   8.140 +
   8.141 +        if self.vcodec == "nuv" or self.vcodec == "xvid"\
   8.142 +               or self.vcodec == "qtvideo" or self.vcodec == "copy":
   8.143 +            video += " -ovc %s" % self.vcodec
   8.144 +        else:
   8.145 +            video += " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s" % (
   8.146 +                self.vcodec, self.vbitrate)
   8.147 +
   8.148 +        if self.mux == "mpeg" and self.mpegopts is not None:
   8.149 +            video += " -mpegopts format=%s" % self.mpegopts
   8.150 +
   8.151 +        video += " -vf scale=%s:%s" % (self.width, self.height)
   8.152 +
   8.153 +        return video
   8.154 +
   8.155 +    # setup_video()
   8.156 +
   8.157 +
   8.158 +    def arg_append(self, args, options):
   8.159 +        l = shlex.split(options)
   8.160 +        for i in l:
   8.161 +            args.append(i)
   8.162 +
   8.163 +    # arg_append()
   8.164 +
   8.165 +
   8.166 +    def setup_args(self, args):
   8.167 +
   8.168 +        args.append(self.path)
   8.169 +
   8.170 +        #args.append(self.filename)
   8.171 +        args.append("-")
   8.172 +
   8.173 +        if self.language != None:
   8.174 +            self.arg_append(args, "-alang %s" % self.language)
   8.175 +
   8.176 +        if self.subtitle != None:
   8.177 +            self.arg_append(args, "-slang %s" % self.subtitle)
   8.178 +            self.arg_append(args, "-subfps %s" % self.fps)
   8.179 +
   8.180 +        self.arg_append(args, "-idx")
   8.181 +        self.arg_append(args, self.audio_opts)
   8.182 +        self.arg_append(args, self.video_opts)
   8.183 +
   8.184 +        self.arg_append(args, "-really-quiet")
   8.185 +        self.arg_append(args, "-o %s" % self.fifo)
   8.186 +        self.arg_append(args, "2> %s" % os.devnull)
   8.187 +
   8.188 +    # setup_args()
   8.189 +
   8.190 +
   8.191 +    def setup_filename(self, filename):
   8.192 +        try:
   8.193 +            self.kind, self.filename = filename.split("://")
   8.194 +        except:
   8.195 +            return (False, "Wrong filename protocol")
   8.196 +
   8.197 +        if self.kind == "file":
   8.198 +            if not os.path.exists(self.filename):
   8.199 +                msg = "File requested does not exist. SETUP failed."
   8.200 +                log.error(msg)
   8.201 +                return (False, msg)
   8.202 +
   8.203 +        elif self.kind == "dvd":
   8.204 +            self.filename = "dvd://" + filename
   8.205 +
   8.206 +        elif self.kind == "myth":
   8.207 +            self.filename = filename
   8.208 +            self.gst_pipe = os.pipe()
   8.209 +            print self.gst_pipe[0]
   8.210 +            print self.gst_pipe[1]
   8.211 +
   8.212 +        return (True, "")
   8.213 +
   8.214 +    # setup_filename()
   8.215 +
   8.216 +
   8.217 +    def setup_socket(self):
   8.218 +        if self.socket != None:
   8.219 +            self.socket = None
   8.220 +
   8.221 +        self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
   8.222 +        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
   8.223 +
   8.224 +        try:
   8.225 +            self.socket.bind( ('', self.port) )
   8.226 +            self.socket.listen(1)
   8.227 +        except Exception, e:
   8.228 +            log.error("Could not create socket: %s" % e)
   8.229 +            return (False, e)
   8.230 +
   8.231 +        return (True, "")
   8.232 +
   8.233 +    # setup_socket()
   8.234 +
   8.235 +
   8.236 +    '''
   8.237 +    MENCODER SETUP DESCRIPTION
   8.238 +    ===========================
   8.239 +
   8.240 +    -> mux, vcodecs and acodecs
   8.241 +     |-> mencoder (-of | -ovc | -oac) help
   8.242 +
   8.243 +    -> if used mpeg as mux:
   8.244 +     |-> to setup format: format=%s as an option at the end
   8.245 +
   8.246 +    '''
   8.247 +
   8.248 +
   8.249 +    # good one: /tmp/dvb.mpg avi mpeg4 400 25 mp3lame 192 320 240
   8.250 +    # file:///tmp/dvb.mpg mpeg mpeg1video 400 25 mp2 192 320 240 format=mpeg1
   8.251 +    # dvd://4 mpeg mpeg1video 400 25 mp3lame 192 400 240 language=en local
   8.252 +    # file:///tmp/mpg/bad_day.mpg avi mpeg4 400 25 mp3 192 320 240
   8.253 +
   8.254 +    def setup(self, filename, mux, vcodec, vbitrate,\
   8.255 +              fps, acodec, abitrate, width, height, port, options):
   8.256 +
   8.257 +        if self.args != []:
   8.258 +            self.do_cleanup()
   8.259 +
   8.260 +        self.mux = mux
   8.261 +        self.vcodec = vcodec
   8.262 +        self.vbitrate = vbitrate
   8.263 +        self.fps = fps
   8.264 +        self.acodec = acodec
   8.265 +        self.abitrate = abitrate
   8.266 +        self.width = width
   8.267 +        self.height = height
   8.268 +        self.port = int(port)
   8.269 +
   8.270 +        self.setup_mencoder()
   8.271 +
   8.272 +        ret_val = self.setup_filename(filename)
   8.273 +
   8.274 +        if not ret_val[0]:
   8.275 +            return ret_val
   8.276 +
   8.277 +        self.setup_opts(options)
   8.278 +        self.audio_opts = self.setup_audio()
   8.279 +        self.video_opts = self.setup_video()
   8.280 +        self.setup_args(self.args)
   8.281 +
   8.282 +        ret_val = self.setup_socket()
   8.283 +        return ret_val
   8.284 +
   8.285 +    # setup()
   8.286 +
   8.287 +    def play_loop(self, conn):
   8.288 +        data = self.pout.read(4096)
   8.289 +
   8.290 +        conn.settimeout(5)
   8.291 +        retry = 0
   8.292 +
   8.293 +        if not self.transcode_local:
   8.294 +            while data != "" and retry < 5:
   8.295 +                try:
   8.296 +                    conn.send(data)
   8.297 +                    r, w, x = select([conn], [], [], 0)
   8.298 +                    if conn in r:
   8.299 +                        back = conn.recv(1024)
   8.300 +                        if back == "OK" and self.mplayer and not self.mplayer_pid:
   8.301 +                            self.run_mplayer()
   8.302 +
   8.303 +                except socket.error, e:
   8.304 +                    log.error("Socket error: %s" % e)
   8.305 +                    retry += 1
   8.306 +
   8.307 +                data = self.pout.read(4096)
   8.308 +
   8.309 +        else:
   8.310 +            local = open(self.transcode_local, "w")
   8.311 +            total = os.path.getsize(self.filename)
   8.312 +            partial = 4096
   8.313 +
   8.314 +            while data != "":
   8.315 +                try:
   8.316 +                    local.write(data)
   8.317 +                except Exception, e:
   8.318 +                    log.error("Write error: %s" % e)
   8.319 +
   8.320 +                data = self.pout.read(4096)
   8.321 +                partial += len(data)
   8.322 +                conn.send("%.2f\n" % (partial * 100 / total) )
   8.323 +
   8.324 +            local.close()
   8.325 +            conn.send("DONE\n")
   8.326 +
   8.327 +        return retry
   8.328 +
   8.329 +    # play_loop()
   8.330 +
   8.331 +
   8.332 +    def play(self):
   8.333 +
   8.334 +        if self.gst_pipe:
   8.335 +            try:
   8.336 +                gst = [ lib.which("gst-launch-0.10"), "--gst-debug-level=0" ]
   8.337 +                self.arg_append(gst, "mythtvsrc location=%s" % self.filename)
   8.338 +                self.arg_append(gst, "! fdsink fd=2")
   8.339 +                self.gst_pid = Popen(gst, close_fds=True)
   8.340 +                log.info("Running Gstreamer: %s" % gst);
   8.341 +            except Exception, e:
   8.342 +                msg = "Could not init Gstreamer: %s" % e
   8.343 +                log.error(msg)
   8.344 +                return (False, msg)
   8.345 +
   8.346 +
   8.347 +        log.info("Starting Mencoder: %s" % self.args )
   8.348 +        try:
   8.349 +            if not self.gst_pipe:
   8.350 +                self.stdin = open(self.filename)
   8.351 +            else:
   8.352 +                self.stdin = self.gst_pid.stdout
   8.353 +
   8.354 +            self.mencoder_pid = Popen(self.args, stdin=self.stdin, stdout=PIPE, close_fds=True)
   8.355 +        except Exception, e:
   8.356 +            msg = "Could not init Mencoder: %s" % e
   8.357 +            log.error(msg)
   8.358 +            return (False, msg)
   8.359 +
   8.360 +        if self.mencoder_old: self.pout = open(self.fifo)
   8.361 +        else: self.pout = self.mencoder_pid.stdout
   8.362 +
   8.363 +        self.child_pid = os.fork()
   8.364 +
   8.365 +        if self.child_pid == 0:
   8.366 +            conn, addr = self.socket.accept()
   8.367 +
   8.368 +            log.info("Sending Data to client: %s" % addr[0])
   8.369 +            retry = self.play_loop(conn)
   8.370 +
   8.371 +            if retry < 5:
   8.372 +                log.info("Finished sending Data to client: %s" % addr[0])
   8.373 +            else:
   8.374 +                log.error("Client timed out, retried more than %s times" % retry)
   8.375 +
   8.376 +            os.kill(self.mencoder_pid.pid, signal.SIGKILL)
   8.377 +            sys.exit(0)
   8.378 +
   8.379 +        return (True, "")
   8.380 +
   8.381 +    # play()
   8.382 +
   8.383 +
   8.384 +    def stop(self):
   8.385 +        try:
   8.386 +
   8.387 +            if self.mencoder_pid:
   8.388 +                os.kill(self.mencoder_pid.pid, signal.SIGTERM)
   8.389 +                self.mencoder_pid = None
   8.390 +
   8.391 +            if self.mplayer_pid:
   8.392 +                os.kill(self.mplayer_pid.pid, signal.SIGTERM)
   8.393 +                self.mplayer_pid = None
   8.394 +
   8.395 +            if self.socket:
   8.396 +                self.socket.close()
   8.397 +                self.socket = None
   8.398 +
   8.399 +            if self.child_pid:
   8.400 +                os.kill(self.child_pid, signal.SIGTERM)
   8.401 +                self.child_pid = None
   8.402 +
   8.403 +            if self.gst_pid:
   8.404 +                os.kill(self.gst_pid.pid, signal.SIGTERM)
   8.405 +                self.gst_pid = None
   8.406 +
   8.407 +            self.do_cleanup()
   8.408 +
   8.409 +            os.wait()
   8.410 +
   8.411 +        except Exception, e:
   8.412 +            log.error("Stop error: %s" % e)
   8.413 +
   8.414 +    # stop()
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/gmyth-stream/server/0.1/plugins/media/vlc.py	Wed Apr 18 15:59:10 2007 +0100
     9.3 @@ -0,0 +1,80 @@
     9.4 +import os
     9.5 +import sys
     9.6 +import time
     9.7 +import socket
     9.8 +import ConfigParser
     9.9 +
    9.10 +class Media:
    9.11 +
    9.12 +    def __init__(self, config):
    9.13 +
    9.14 +        self.config = config
    9.15 +        self.pipe = ""
    9.16 +        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    9.17 +
    9.18 +        self.path = config.get("Vlc", "path")
    9.19 +        self.host = config.get("Vlc", "host")
    9.20 +        self.port = int(config.get("Vlc", "port"))
    9.21 +        self.pwd = config.get("Vlc", "pwd")
    9.22 +
    9.23 +        # exec VLC
    9.24 +        pid = os.fork()
    9.25 +        if (pid == 0):
    9.26 +            #child
    9.27 +            print "ESTOU EM CHILD"
    9.28 +            self.path += " -I telnet -d 1> /dev/null 2> /dev/null &"
    9.29 +            os.system(self.path)
    9.30 +            sys.exit(0)
    9.31 +        else:
    9.32 +            print "ESTOU EM PARENT 1"
    9.33 +            time.sleep(3)
    9.34 +            print "ESTOU EM PARENT 2"
    9.35 +            self.sock.connect( (self.host, self.port) )
    9.36 +            self.sock.send("%s\n" % self.pwd)
    9.37 +
    9.38 +
    9.39 +    def insert_file(self, filename):
    9.40 +
    9.41 +        self.sock.send("setup output0 input %s\n" % filename)
    9.42 +
    9.43 +
    9.44 +
    9.45 +    def setup(self, filename, mux, vcodec, vbitrate,\
    9.46 +              fps, acodec, abitrate, width, height, port):
    9.47 +
    9.48 +        self.filename = filename
    9.49 +        self.mux = mux
    9.50 +        self.vcodec = vcodec
    9.51 +        self.vbitrate = int(vbitrate)
    9.52 +        self.fps = int(fps)
    9.53 +        self.acodec = acodec
    9.54 +        self.abitrate = int(abitrate)
    9.55 +        self.width = int(width)
    9.56 +        self.height = int(height)
    9.57 +
    9.58 +        self.port = int(port)
    9.59 +
    9.60 +
    9.61 +        self.pipe = "#transcode{vcodec=%s,vb=%d,"\
    9.62 +                    "fps=25.0,scale=1,acodec=mpga,"\
    9.63 +                    "ab=64,channels=1,width=%d,height=%d}"\
    9.64 +                    ":duplicate{dst=std{access=http,"\
    9.65 +                    "mux=mpeg1,dst=:%d}}" % (self.vcodec, self.vbitrate,\
    9.66 +                                             self.widht, self.height,\
    9.67 +                                             self.port)
    9.68 +
    9.69 +        self.sock.send("setup output0 broadcast %s\n" % self.pipe)
    9.70 +        self.insert_file(self.filename)
    9.71 +
    9.72 +    def play(self):
    9.73 +
    9.74 +        print "Trying to play: %s" % self.pipe
    9.75 +        self.sock.send("control output0 play\n")
    9.76 +
    9.77 +
    9.78 +    def stop(self):
    9.79 +
    9.80 +        print "Trying to stop: %s" % self.pipe
    9.81 +        self.sock.send("control output0 stop\n")
    9.82 +
    9.83 +
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/gmyth-stream/server/0.1/stream.conf	Wed Apr 18 15:59:10 2007 +0100
    10.3 @@ -0,0 +1,23 @@
    10.4 +[Comm]
    10.5 +engine = tcp
    10.6 +port = 50000
    10.7 +
    10.8 +
    10.9 +[Media]
   10.10 +engine = mencoder
   10.11 +
   10.12 +
   10.13 +[Vlc]
   10.14 +path = /usr/local/bin/vlc
   10.15 +host = 127.0.0.1
   10.16 +port = 4212
   10.17 +pwd = admin
   10.18 +
   10.19 +
   10.20 +[FFmpeg]
   10.21 +path = /usr/local/bin/ffmpeg
   10.22 +
   10.23 +
   10.24 +[Mencoder]
   10.25 +path = /usr/local/bin/mencoder
   10.26 +fifo_path = /tmp/teste
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/gmyth-stream/server/0.1/tests/client.py	Wed Apr 18 15:59:10 2007 +0100
    11.3 @@ -0,0 +1,51 @@
    11.4 +import os
    11.5 +import sys
    11.6 +import time
    11.7 +import socket
    11.8 +
    11.9 +
   11.10 +if len(sys.argv) < 2:
   11.11 +    HOST = 'localhost'
   11.12 +    PORT = 50000
   11.13 +elif len(sys.argv) == 2:
   11.14 +    HOST = sys.argv[1]
   11.15 +    PORT = 50000
   11.16 +else:
   11.17 +    HOST = sys.argv[1]
   11.18 +    PORT = int(sys.argv[2])
   11.19 +
   11.20 +socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
   11.21 +socket.settimeout(10)
   11.22 +
   11.23 +try:
   11.24 +    socket.connect( (HOST,PORT) )
   11.25 +except:
   11.26 +    print "\n--> Could not connect to ('%s':'%d')\n" % (HOST,PORT)
   11.27 +    sys.exit(-1)
   11.28 +
   11.29 +
   11.30 +mplayer = os.popen("which mplayer").read().strip()
   11.31 +mplayer += " -idx - -vo x11 1> /dev/null"
   11.32 +pin, pout = os.popen2(mplayer)
   11.33 +
   11.34 +#teste = open("teste.avi", "w")
   11.35 +
   11.36 +data = socket.recv(4096)
   11.37 +i = 0
   11.38 +
   11.39 +while (data != ""):
   11.40 +    pin.write(data)
   11.41 +    #teste.write(data)
   11.42 +    data = socket.recv(4096)
   11.43 +    #if (i == 500):
   11.44 +    #    socket.send("OK")
   11.45 +    i += 1
   11.46 +
   11.47 +pin.close()
   11.48 +socket.close()
   11.49 +#teste.close()
   11.50 +
   11.51 +# from select import select
   11.52 +# r, w, x = select([pout], []. [], 0)
   11.53 +# if pout in r:
   11.54 +#     pout.read(32)
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/gmyth-stream/server/0.2/gms.py	Wed Apr 18 15:59:10 2007 +0100
    12.3 @@ -0,0 +1,20 @@
    12.4 +#!/usr/bin/env python
    12.5 +
    12.6 +import sys
    12.7 +import os
    12.8 +import logging as log
    12.9 +from lib.server import serve_forever, load_plugins_transcoders
   12.10 +
   12.11 +log_level = log.INFO
   12.12 +for p in sys.argv[1:]:
   12.13 +    if p == "-v" or p == "--verbose":
   12.14 +        log_level -= 10
   12.15 +
   12.16 +log.basicConfig(level=log_level,
   12.17 +                format=("### %(asctime)s %(name)-18s %(levelname)-8s "
   12.18 +                        "\t%(message)s"),
   12.19 +                datefmt="%Y-%m-%d %H:%M:%S")
   12.20 +
   12.21 +pd = os.path.join("plugins", "transcoders")
   12.22 +load_plugins_transcoders(pd)
   12.23 +serve_forever()
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/gmyth-stream/server/0.2/lib/server.py	Wed Apr 18 15:59:10 2007 +0100
    13.3 @@ -0,0 +1,464 @@
    13.4 +#!/usr/bin/env python
    13.5 +
    13.6 +__author__ = "Gustavo Sverzut Barbieri / Artur Duque de Souza"
    13.7 +__author_email__ = "barbieri@gmail.com / artur.souza@indt.org.br"
    13.8 +__license__ = "GPL"
    13.9 +__version__ = "0.3"
   13.10 +
   13.11 +import os
   13.12 +import threading
   13.13 +import SocketServer
   13.14 +import BaseHTTPServer
   13.15 +import socket
   13.16 +import urlparse
   13.17 +import cgi
   13.18 +import lib.utils as utils
   13.19 +import logging as log
   13.20 +
   13.21 +__all__ = ("Transcoder", "RequestHandler", "Server", "serve_forever",
   13.22 +           "load_plugins_transcoders")
   13.23 +
   13.24 +class Transcoder(object):
   13.25 +    log = log.getLogger("gmyth-stream.transcoder")
   13.26 +    priority = 0   # negative values have higher priorities
   13.27 +    name = None # to be used in requests
   13.28 +
   13.29 +    def __init__(self, params):
   13.30 +        self.params = params
   13.31 +    # __init__()
   13.32 +
   13.33 +
   13.34 +    def params_first(self, key, default=None):
   13.35 +        if default is None:
   13.36 +            return self.params[key][0]
   13.37 +        else:
   13.38 +            try:
   13.39 +                return self.params[key][0]
   13.40 +            except:
   13.41 +                return default
   13.42 +    # params_first()
   13.43 +
   13.44 +
   13.45 +    def get_mimetype(self):
   13.46 +        mux = self.params_first("mux", "mpg")
   13.47 +
   13.48 +        if mux == "mpeg":
   13.49 +            return "video/mpeg"
   13.50 +        elif mux == "avi":
   13.51 +            return "video/x-msvideo"
   13.52 +        else:
   13.53 +            return "application/octet-stream"
   13.54 +    # get_mimetype()
   13.55 +
   13.56 +
   13.57 +    def start(self, outfile):
   13.58 +        return True
   13.59 +    # start()
   13.60 +
   13.61 +
   13.62 +    def stop(self):
   13.63 +        return Tru
   13.64 +    # stop()
   13.65 +
   13.66 +
   13.67 +    def __str__(self):
   13.68 +        return '%s("%s", mux="%s", params=%s)' % \
   13.69 +               (self.__class__.__name__,
   13.70 +                self.params_first("uri", "None"),
   13.71 +                self.params_first("mux", "mpg"),
   13.72 +                self.params)
   13.73 +    # __str__()
   13.74 +# Transcoder
   13.75 +
   13.76 +
   13.77 +
   13.78 +class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
   13.79 +    log = log.getLogger("gmyth-stream.request")
   13.80 +    def_transcoder = None
   13.81 +    transcoders = utils.PluginSet(Transcoder)
   13.82 +
   13.83 +    @classmethod
   13.84 +    def load_plugins_transcoders(cls, directory):
   13.85 +        cls.transcoders.load_from_directory(directory)
   13.86 +
   13.87 +        if cls.def_transcoder is None and cls.transcoders:
   13.88 +            cls.def_transcoder = cls.transcoders[0].name
   13.89 +    # load_plugins_transcoders()
   13.90 +
   13.91 +
   13.92 +    def do_dispatch(self, body):
   13.93 +        self.url = self.path
   13.94 +
   13.95 +        pieces = urlparse.urlparse(self.path)
   13.96 +        self.path = pieces[2]
   13.97 +        self.query = cgi.parse_qs(pieces[4])
   13.98 +
   13.99 +        if self.path == "/":
  13.100 +            self.serve_main(body)
  13.101 +        elif self.path == "/shutdown.do":
  13.102 +            self.serve_shutdown(body)
  13.103 +        elif self.path == "/stop-transcoder.do":
  13.104 +            self.serve_stop_transcoder(body)
  13.105 +        elif self.path == "/status.do":
  13.106 +            self.serve_status(body)
  13.107 +        elif self.path == "/play.do":
  13.108 +            self.serve_play(body)
  13.109 +        elif self.path == "/stream.do":
  13.110 +            self.serve_stream(body)
  13.111 +        else:
  13.112 +            self.send_error(404, "File not found")
  13.113 +    # do_dispatch()
  13.114 +
  13.115 +
  13.116 +    def do_GET(self):
  13.117 +        self.do_dispatch(True)
  13.118 +    # do_GET()
  13.119 +
  13.120 +
  13.121 +    def do_HEAD(self):
  13.122 +        self.do_dispatch(False)
  13.123 +    # do_HEAD()
  13.124 +
  13.125 +
  13.126 +    def _nav_items(self):
  13.127 +        self.wfile.write("""\
  13.128 +   <li><a href="/play.do">Play</a></li>
  13.129 +   <li><a href="/status.do">Status</a></li>
  13.130 +   <li><a href="/stop-transcoder.do">Stop transcoders</a></li>
  13.131 +   <li><a href="/shutdown.do">Shutdown Server</a></li>
  13.132 +""")
  13.133 +    # _nav_items()
  13.134 +
  13.135 +
  13.136 +    def serve_main(self, body):
  13.137 +        self.send_response(200)
  13.138 +        self.send_header("Content-Type", "text/html")
  13.139 +        self.send_header('Connection', 'close')
  13.140 +        self.end_headers()
  13.141 +        if body:
  13.142 +            self.wfile.write("""\
  13.143 +<html>
  13.144 +   <head><title>Catota Server</title></head>
  13.145 +   <body>
  13.146 +<h1>Welcome to Catota Server</h1>
  13.147 +<ul>
  13.148 +""")
  13.149 +            self._nav_items()
  13.150 +            self.wfile.write("""\
  13.151 +</ul>
  13.152 +   </body>
  13.153 +</html>
  13.154 +""")
  13.155 +    # serve_main()
  13.156 +
  13.157 +
  13.158 +    def serve_play(self, body):
  13.159 +        self.send_response(200)
  13.160 +        self.send_header("Content-Type", "text/html")
  13.161 +        self.send_header('Connection', 'close')
  13.162 +        self.end_headers()
  13.163 +        if body:
  13.164 +            self.wfile.write("""\
  13.165 +<html>
  13.166 +   <head><title>Catota Server</title></head>
  13.167 +   <body>
  13.168 +   <h1>Play</h1>
  13.169 +   <form action="/stream.do" method="GET">
  13.170 +      <input type="text" name="type" value="file" />://<input type="text" name="location" value=""/>
  13.171 +      <input type="submit" />
  13.172 +   </form>
  13.173 +   <ul>
  13.174 +""")
  13.175 +            self._nav_items()
  13.176 +            self.wfile.write("""\
  13.177 +   </ul>
  13.178 +   </body>
  13.179 +</html>
  13.180 +""")
  13.181 +    # serve_play()
  13.182 +
  13.183 +
  13.184 +    def serve_shutdown(self, body):
  13.185 +        self.send_response(200)
  13.186 +        self.send_header("Content-Type", "text/html")
  13.187 +        self.send_header('Connection', 'close')
  13.188 +        self.end_headers()
  13.189 +        if body:
  13.190 +            self.wfile.write("""\
  13.191 +<html>
  13.192 +   <head><title>Catota Server Exited</title></head>
  13.193 +   <body>
  13.194 +      <h1>Catota is not running anymore</h1>
  13.195 +   </body>
  13.196 +</html>
  13.197 +""")
  13.198 +        self.server.server_close()
  13.199 +    # serve_shutdown()
  13.200 +
  13.201 +
  13.202 +    def serve_stop_all_transcoders(self, body):
  13.203 +        self.send_response(200)
  13.204 +        self.send_header("Content-Type", "text/html")
  13.205 +        self.send_header('Connection', 'close')
  13.206 +        self.end_headers()
  13.207 +        if body:
  13.208 +            self.server.stop_transcoders()
  13.209 +            self.wfile.write("""\
  13.210 +<html>
  13.211 +   <head><title>Catota Server Stopped Transcoders</title></head>
  13.212 +   <body>
  13.213 +      <h1>Catota stopped running transcoders</h1>
  13.214 +      <ul>
  13.215 +""")
  13.216 +            self._nav_items()
  13.217 +            self.wfile.write("""\
  13.218 +      </ul>
  13.219 +   </body>
  13.220 +</html>
  13.221 +    """)
  13.222 +    # serve_stop_all_transcoders()
  13.223 +
  13.224 +
  13.225 +    def serve_stop_selected_transcoders(self, body, requests):
  13.226 +        self.send_response(200)
  13.227 +        self.send_header("Content-Type", "text/html")
  13.228 +        self.send_header('Connection', 'close')
  13.229 +        self.end_headers()
  13.230 +        if body:
  13.231 +            self.wfile.write("""\
  13.232 +<html>
  13.233 +   <head><title>Catota Server Stopped Transcoders</title></head>
  13.234 +   <body>
  13.235 +      <h1>Catota stopped running transcoders:</h1>
  13.236 +      <ul>
  13.237 +    """)
  13.238 +            transcoders = self.server.get_transcoders()
  13.239 +
  13.240 +            for req in requests:
  13.241 +                try:
  13.242 +                    host, port = req.split(":")
  13.243 +                except IndexError:
  13.244 +                    continue
  13.245 +
  13.246 +                port = int(port)
  13.247 +                addr = (host, port)
  13.248 +
  13.249 +                for t, r in transcoders:
  13.250 +                    if r.client_address == addr:
  13.251 +                        t.stop()
  13.252 +                        self.server.del_transcoders(self, t)
  13.253 +                        self.wfile.write("""\
  13.254 +         <li>%s: %s:%s</li>
  13.255 +""" % (t, addr[0], addr[1]))
  13.256 +                        t.stop()
  13.257 +                        break
  13.258 +            self.wfile.write("""\
  13.259 +      </ul>
  13.260 +      <ul>
  13.261 +""")
  13.262 +            self._nav_items()
  13.263 +            self.wfile.write("""\
  13.264 +      </ul>
  13.265 +   </body>
  13.266 +</html>
  13.267 +""")
  13.268 +    # serve_stop_selected_transcoders()
  13.269 +
  13.270 +
  13.271 +    def serve_stop_transcoder(self, body):
  13.272 +        req = self.query.get("request", None)
  13.273 +        if req and "all" in req:
  13.274 +            self.serve_stop_all_transcoders(body)
  13.275 +        elif req:
  13.276 +            self.serve_stop_selected_transcoders(body, req)
  13.277 +        else:
  13.278 +            self.serve_status(body)
  13.279 +    # serve_stop_transcoder()
  13.280 +
  13.281 +
  13.282 +    def serve_status(self, body):
  13.283 +        self.send_response(200)
  13.284 +        self.send_header("Content-Type", "text/html")
  13.285 +        self.send_header('Connection', 'close')
  13.286 +        self.end_headers()
  13.287 +        if body:
  13.288 +            self.wfile.write("""\
  13.289 +<html>
  13.290 +   <head><title>Catota Server Status</title></head>
  13.291 +   <body>
  13.292 +      <h1>Catota Status</h1>
  13.293 +""")
  13.294 +            tl = self.server.get_transcoders()
  13.295 +            if not tl:
  13.296 +                self.wfile.write("<p>No running transcoder.</p>\n")
  13.297 +            else:
  13.298 +                self.wfile.write("<p>Running transcoders:</p>\n")
  13.299 +                self.wfile.write("""\
  13.300 +      <ul>
  13.301 +         <li><a href="/stop-transcoder.do?request=all">[STOP ALL]</a></li>
  13.302 +""")
  13.303 +                for transcoder, request in tl:
  13.304 +                    self.wfile.write("""\
  13.305 +      <li>%s: %s:%s <a href="/stop-transcoder.do?request=%s:%s">[STOP]</a></li>
  13.306 +""" % (transcoder, request.client_address[0], request.client_address[1],
  13.307 +       request.client_address[0], request.client_address[1]))
  13.308 +
  13.309 +                self.wfile.write("""\
  13.310 +      </ul>
  13.311 +      <ul>
  13.312 +""")
  13.313 +            self._nav_items()
  13.314 +            self.wfile.write("""\
  13.315 +      </ul>
  13.316 +   </body>
  13.317 +</html>
  13.318 +""")
  13.319 +    # serve_status()
  13.320 +
  13.321 +
  13.322 +    def _get_transcoder(self):
  13.323 +        # get transcoder option: mencoder is the default
  13.324 +        request_transcoders = self.query.get("transcoder", ["mencoder"])
  13.325 +
  13.326 +        for t in request_transcoders:
  13.327 +            transcoder = self.transcoders.get(t)
  13.328 +            if transcoder:
  13.329 +                return transcoder
  13.330 +
  13.331 +        if not transcoder:
  13.332 +            return self.transcoders[self.def_transcoder]
  13.333 +    # _get_transcoder()
  13.334 +
  13.335 +
  13.336 +    def serve_stream(self, body):
  13.337 +        transcoder = self._get_transcoder()
  13.338 +        try:
  13.339 +            obj = transcoder(self.query)
  13.340 +        except Exception, e:
  13.341 +            self.send_error(500, str(e))
  13.342 +            return
  13.343 +
  13.344 +        self.send_response(200)
  13.345 +        self.send_header("Content-Type", obj.get_mimetype())
  13.346 +        self.send_header('Connection', 'close')
  13.347 +        self.end_headers()
  13.348 +
  13.349 +        if body:
  13.350 +            self.server.add_transcoders(self, obj)
  13.351 +            obj.start(self.wfile)
  13.352 +            self.server.del_transcoders(self, obj)
  13.353 +    # serve_stream()
  13.354 +
  13.355 +
  13.356 +    def log_request(self, code='-', size='-'):
  13.357 +        self.log.info('"%s" %s %s', self.requestline, str(code), str(size))
  13.358 +    # log_request()
  13.359 +
  13.360 +
  13.361 +    def log_error(self, format, *args):
  13.362 +        self.log.error("%s: %s" % (self.address_string(), format % args))
  13.363 +    # log_error()
  13.364 +
  13.365 +
  13.366 +    def log_message(self, format, *args):
  13.367 +        self.log.info("%s: %s" % (self.address_string(), format % args))
  13.368 +    # log_message()
  13.369 +# RequestHandler
  13.370 +
  13.371 +
  13.372 +
  13.373 +class Server(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
  13.374 +    log = log.getLogger("gmyth-streamer.server")
  13.375 +    run = True
  13.376 +    _transcoders = {}
  13.377 +    _lock = threading.RLock()
  13.378 +
  13.379 +    def serve_forever(self):
  13.380 +        self.log.info("GMyth-Streamer serving HTTP on %s:%s" %
  13.381 +                      self.socket.getsockname())
  13.382 +        try:
  13.383 +            while self.run:
  13.384 +                self.handle_request()
  13.385 +        except KeyboardInterrupt, e:
  13.386 +            pass
  13.387 +
  13.388 +        self.log.debug("Stopping all remaining transcoders...")
  13.389 +        self.stop_transcoders()
  13.390 +        self.log.debug("Transcoders stopped!")
  13.391 +    # serve_forever()
  13.392 +
  13.393 +
  13.394 +    def get_request(self):
  13.395 +        skt = self.socket
  13.396 +        old = skt.gettimeout()
  13.397 +        skt.settimeout(0.5)
  13.398 +        while self.run:
  13.399 +            try:
  13.400 +                r = skt.accept()
  13.401 +                skt.settimeout(old)
  13.402 +                return r
  13.403 +            except socket.timeout, e:
  13.404 +                pass
  13.405 +        raise socket.error("Not running")
  13.406 +    # get_request()
  13.407 +
  13.408 +
  13.409 +    def server_close(self):
  13.410 +        self.run = False
  13.411 +        self.stop_transcoders()
  13.412 +
  13.413 +        BaseHTTPServer.HTTPServer.server_close(self)
  13.414 +    # server_close()
  13.415 +
  13.416 +
  13.417 +    def stop_transcoders(self):
  13.418 +        self._lock.acquire()
  13.419 +        for transcoder, request in self._transcoders.iteritems():
  13.420 +            self.log.info("Stop transcoder: %s, client=%s" %
  13.421 +                          (transcoder, request.client_address))
  13.422 +            transcoder.stop()
  13.423 +        self._lock.release()
  13.424 +    # stop_transcoders()
  13.425 +
  13.426 +
  13.427 +    def get_transcoders(self):
  13.428 +        self._lock.acquire()
  13.429 +        try:
  13.430 +            return self._transcoders.items()
  13.431 +        finally:
  13.432 +            self._lock.release()
  13.433 +    # get_transcoders()
  13.434 +
  13.435 +
  13.436 +    def add_transcoders(self, request, transcoder):
  13.437 +        self._lock.acquire()
  13.438 +        try:
  13.439 +            self._transcoders[transcoder] = request
  13.440 +        finally:
  13.441 +            self._lock.release()
  13.442 +    # add_transcoders()
  13.443 +
  13.444 +
  13.445 +    def del_transcoders(self, request, transcoder):
  13.446 +        self._lock.acquire()
  13.447 +        try:
  13.448 +            del self._transcoders[transcoder]
  13.449 +        finally:
  13.450 +            self._lock.release()
  13.451 +    # del_transcoders()
  13.452 +# Server
  13.453 +
  13.454 +
  13.455 +
  13.456 +def serve_forever(host="0.0.0.0", port=40000):
  13.457 +    addr = (host, port)
  13.458 +
  13.459 +    RequestHandler.protocol_version = "HTTP/1.0"
  13.460 +    httpd = Server(addr, RequestHandler)
  13.461 +    httpd.serve_forever()
  13.462 +# serve_forever()
  13.463 +
  13.464 +
  13.465 +def load_plugins_transcoders(directory):
  13.466 +    RequestHandler.load_plugins_transcoders(directory)
  13.467 +# load_plugins_transcoders()
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/gmyth-stream/server/0.2/lib/utils.py	Wed Apr 18 15:59:10 2007 +0100
    14.3 @@ -0,0 +1,148 @@
    14.4 +#!/usr/bin/env
    14.5 +
    14.6 +__author__ = "Gustavo Sverzut Barbieri / Artur Duque de Souza"
    14.7 +__author_email__ = "barbieri@gmail.com / artur.souza@indt.org.br"
    14.8 +__license__ = "GPL"
    14.9 +__version__ = "0.3"
   14.10 +
   14.11 +import os
   14.12 +import stat
   14.13 +import sys
   14.14 +import logging
   14.15 +import urllib
   14.16 +import gobject
   14.17 +import imp
   14.18 +
   14.19 +log = logging.getLogger("gmyth-stream.utils")
   14.20 +
   14.21 +__all__ = ("which", "load_plugins", "PluginSet")
   14.22 +
   14.23 +def which(app):
   14.24 +    """function to implement which(1) unix command"""
   14.25 +    pl = os.environ["PATH"].split(os.pathsep)
   14.26 +    for p in pl:
   14.27 +        path = os.path.join(p, app)
   14.28 +        if os.path.isfile(path):
   14.29 +            st = os.stat(path)
   14.30 +            if st[stat.ST_MODE] & 0111:
   14.31 +                return path
   14.32 +    return ""
   14.33 +# which()
   14.34 +
   14.35 +
   14.36 +def _load_module(pathlist, name):
   14.37 +    fp, path, desc = imp.find_module(name, pathlist)
   14.38 +    try:
   14.39 +        module = imp.load_module(name, fp, path, desc)
   14.40 +        return module
   14.41 +    finally:
   14.42 +        if fp:
   14.43 +            fp.close()
   14.44 +# _load_module()
   14.45 +
   14.46 +
   14.47 +class PluginSet(object):
   14.48 +    def __init__(self, basetype, *items):
   14.49 +        self.basetype = basetype
   14.50 +        self.map = {}
   14.51 +        self.list = []
   14.52 +
   14.53 +        for i in items:
   14.54 +            self._add(i)
   14.55 +        self._sort()
   14.56 +    # __init__()
   14.57 +
   14.58 +
   14.59 +    def _add(self, item):
   14.60 +        self.map[item.name] = item
   14.61 +        self.list.append(item)
   14.62 +    # _add()
   14.63 +
   14.64 +
   14.65 +    def add(self, item):
   14.66 +        self._add()
   14.67 +        self._sort()
   14.68 +    # add()
   14.69 +
   14.70 +
   14.71 +    def __getitem__(self, spec):
   14.72 +        if isinstance(spec, basestring):
   14.73 +            return self.map[spec]
   14.74 +        else:
   14.75 +            return self.list[spec]
   14.76 +    # __getitem__()
   14.77 +
   14.78 +
   14.79 +    def get(self, name, default=None):
   14.80 +        self.map.get(name, default)
   14.81 +    # get()
   14.82 +
   14.83 +
   14.84 +    def __iter__(self):
   14.85 +        return self.list.__iter__()
   14.86 +    # __iter__()
   14.87 +
   14.88 +
   14.89 +    def __len__(self):
   14.90 +        return len(self.list)
   14.91 +    # __len__()
   14.92 +
   14.93 +
   14.94 +    def _sort(self):
   14.95 +        self.list.sort(lambda a, b: cmp(a.priority, b.priority))
   14.96 +    # _sort()
   14.97 +
   14.98 +
   14.99 +    def update(self, pluginset):
  14.100 +        self.map.update(pluginset.map)
  14.101 +        self.list.extend(pluginset.list)
  14.102 +        self._sort()
  14.103 +    # update()
  14.104 +
  14.105 +
  14.106 +    def load_from_directory(self, directory):
  14.107 +        for i in load_plugins(directory, self.basetype):
  14.108 +            self._add(i)
  14.109 +        self._sort()
  14.110 +    # load_from_directory()
  14.111 +
  14.112 +
  14.113 +    def __str__(self):
  14.114 +        lst = []
  14.115 +        for o in self.list:
  14.116 +            lst.append('"%s" (%s)' % (o.name, o.__name__))
  14.117 +
  14.118 +        return "%s(basetype=%s, items=[%s])" % \
  14.119 +               (self.__class__.__name__,
  14.120 +                self.basetype.__name__,
  14.121 +                ", ".join(lst))
  14.122 +    # __str__()
  14.123 +# PluginSet
  14.124 +
  14.125 +
  14.126 +def load_plugins(directory, basetype):
  14.127 +    tn = basetype.__name__
  14.128 +    log.debug("Loading plugins from %s, type=%s" % (directory, tn))
  14.129 +
  14.130 +
  14.131 +    plugins = []
  14.132 +    for d in os.listdir(directory):
  14.133 +        if not d.endswith(".py"):
  14.134 +            continue
  14.135 +
  14.136 +        name = d[0: -3]
  14.137 +        if name == "__init__":
  14.138 +            continue
  14.139 +
  14.140 +        directory.replace(os.path.sep, ".")
  14.141 +        mod = _load_module([directory], name)
  14.142 +        for sym in dir(mod):
  14.143 +            cls = getattr(mod, sym)
  14.144 +            if isinstance(cls, type) and issubclass(cls, basetype) and \
  14.145 +                cls != basetype:
  14.146 +                plugins.append(cls)
  14.147 +                log.info("Loaded %s (%s) from %s" % \
  14.148 +                         (cls.__name__, tn, os.path.join(directory, d)))
  14.149 +
  14.150 +    return plugins
  14.151 +# load_plugins()
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/gmyth-stream/server/0.2/plugins/transcoders/gstreamer.py	Wed Apr 18 15:59:10 2007 +0100
    15.3 @@ -0,0 +1,305 @@
    15.4 +#vim:ts=4:sw=4:et
    15.5 +import pygst
    15.6 +pygst.require("0.10")
    15.7 +import gst
    15.8 +import gobject
    15.9 +import time
   15.10 +import lib.utils as utils
   15.11 +import lib.server as server
   15.12 +
   15.13 +from threading import Thread
   15.14 +
   15.15 +__all__ = ("TranscoderGstreamer",)
   15.16 +
   15.17 +class TranscoderGstreamer(server.Transcoder):
   15.18 +    gstreamer_path = utils.which("gst-launch-0.10")
   15.19 +    name = "gstreamer"
   15.20 +    priority = -2
   15.21 +
   15.22 +    # StreamListener()
   15.23 +
   15.24 +    class StreamData:
   15.25 +        stream_count = 0
   15.26 +
   15.27 +        def __init__(self, log, pipe, abin, vbin, sink):
   15.28 +            self.log = log
   15.29 +            self.stream_count += 1
   15.30 +            self.Id = self.stream_count
   15.31 +            self.Pipe = pipe
   15.32 +            self.Abin = abin
   15.33 +            self.Vbin = vbin
   15.34 +            self.Sink = sink
   15.35 +            self.Loop = gobject.MainLoop()
   15.36 +            self.ACaps = ""
   15.37 +            self.VCaps = ""
   15.38 +            self.Ready = False
   15.39 +            self.Connection = None
   15.40 +            self.Addr = None
   15.41 +        # __init__()
   15.42 +
   15.43 +    # StreamData()
   15.44 +
   15.45 +
   15.46 +    def __init__(self, params):
   15.47 +        server.Transcoder.__init__(self, params)
   15.48 +        # set gstreamer basic options
   15.49 +        self.connection = None
   15.50 +        self.addr = None
   15.51 +        self.ready = False
   15.52 +        self.quit = False
   15.53 +
   15.54 +        self.log.info("Params for Gstreamer: %s" % self.params)
   15.55 +    # __init__()
   15.56 +
   15.57 +
   15.58 +    def _create_start_elements(self, uri):
   15.59 +        self.log.info("Opening Uri:" + uri)
   15.60 +        src = gst.element_make_from_uri(gst.URI_SRC, uri, "src")
   15.61 +        decode = gst.element_factory_make("decodebin", "decode")
   15.62 +        mux = gst.element_factory_make("avimux", "mux")
   15.63 +        sink = gst.element_factory_make("fdsink", "sink")
   15.64 +
   15.65 +        return [src, decode, mux, sink]
   15.66 +    # _create_start_elements()
   15.67 +
   15.68 +
   15.69 +    def _setup_video_encode(self, vbin, width, height):
   15.70 +        vqueue = gst.element_factory_make("queue", "vqueue")
   15.71 +        colorspace = gst.element_factory_make("ffmpegcolorspace", "")
   15.72 +        vrate = gst.element_factory_make("videorate", "vrate")
   15.73 +        vencode = gst.element_factory_make("ffenc_mpeg4", "vencode")
   15.74 +        vqueue_src = gst.element_factory_make("queue", "vqueue_src")
   15.75 +
   15.76 +        vencode.set_property("bitrate", 200)
   15.77 +
   15.78 +        if None in [vbin, vqueue, vrate, vencode, vqueue_src]:
   15.79 +            self.log.info("Fail to create video encode elements.")
   15.80 +            return False
   15.81 +
   15.82 +        vbin.add(vqueue)
   15.83 +        if int(width) > 0 and int(height) > 0:
   15.84 +            self.log.info(("Formating output to %d / %d" %(int(width), int(height))))
   15.85 +
   15.86 +            vscale = gst.element_factory_make("ffvideoscale", "vscale")
   15.87 +
   15.88 +            vbin.add(vscale);
   15.89 +            if not vqueue.link(vscale):
   15.90 +                self.log.info("Fail to link video elements")
   15.91 +                return False
   15.92 +
   15.93 +            vbin.add(colorspace)
   15.94 +
   15.95 +            if not vscale.link(colorspace, \
   15.96 +                gst.caps_from_string("video/x-raw-yuv,width=(int)%d,height=(int)%d" %(\
   15.97 +                int(width), int(height)))):
   15.98 +                self.log.info("Fail to link video elements")
   15.99 +                return False
  15.100 +        else:
  15.101 +            vbin.add(colorspace)
  15.102 +            vqueue.link(colorspace)
  15.103 +
  15.104 +        vbin.add(vrate, vencode, vqueue_src)
  15.105 +        if not colorspace.link(vrate):
  15.106 +            self.log.info("Fail to colorspace with vrate")
  15.107 +            return False
  15.108 +
  15.109 +        if not vrate.link(vencode, \
  15.110 +            gst.caps_from_string("video/x-raw-yuv,framerate=(fraction)10/1")):
  15.111 +            self.log.info("Fail to link vrate element")
  15.112 +            return False
  15.113 +
  15.114 +        if not vencode.link(vqueue_src):
  15.115 +            self.log.info("Fail to link video encode with queue")
  15.116 +            return False
  15.117 +
  15.118 +        vbin.add_pad(gst.GhostPad("sink", vqueue.get_pad("sink")))
  15.119 +        vbin.add_pad(gst.GhostPad("src", vqueue_src.get_pad("src")))
  15.120 +
  15.121 +        return True
  15.122 +    # _setup_video_encode()
  15.123 +
  15.124 +
  15.125 +    def _setup_audio_encode(self, abin):
  15.126 +        aqueue = gst.element_factory_make("queue", "aqueue")
  15.127 +        aconvert = gst.element_factory_make("audioconvert", "aconvert")
  15.128 +        arate = gst.element_factory_make("audioresample", "arate")
  15.129 +        aencode = gst.element_factory_make("queue", "aencode")
  15.130 +        aqueue_src = gst.element_factory_make("queue", "aqueue_src")
  15.131 +
  15.132 +        if None in [abin, aqueue, arate, aencode, aqueue_src]:
  15.133 +            self.log.info("Fail to create video encode elements.")
  15.134 +            return False
  15.135 +
  15.136 +        abin.add(aqueue, aconvert, arate, aencode, aqueue_src)
  15.137 +
  15.138 +        if not gst.element_link_many(aqueue,  aconvert, arate, aencode, aqueue_src):
  15.139 +            self.log.info("Fail to link video elements")
  15.140 +            return False
  15.141 +
  15.142 +        abin.add_pad(gst.GhostPad("sink", aqueue.get_pad("sink")))
  15.143 +        abin.add_pad(gst.GhostPad("src", aqueue_src.get_pad("src")))
  15.144 +
  15.145 +        return True
  15.146 +    # _setup_audio_encode()
  15.147 +
  15.148 +
  15.149 +    def setup(self, uri, mux, vcodec, vbitrate,
  15.150 +              fps, acodec, abitrate, width, height, options):
  15.151 +
  15.152 +        ## Pipelines
  15.153 +        pipe = gst.Pipeline()
  15.154 +        src, decode, mux, sink = self._create_start_elements(uri)
  15.155 +
  15.156 +        if None in [src, decode, mux, sink]:
  15.157 +            self.log.info("Problems with while starting basic elements");
  15.158 +            return False
  15.159 +
  15.160 +        #video encode
  15.161 +        #queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! videorate !
  15.162 +        #ffenc_h263p bitrate=256000 me-method=2 ! rtph263ppay ! udpsink  host=224.0.0.1
  15.163 +        #port=5000
  15.164 +
  15.165 +        vbin = gst.Bin()
  15.166 +        if not self._setup_video_encode(vbin, width, height):
  15.167 +            return False
  15.168 +
  15.169 +        #audio encode
  15.170 +        #audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay !
  15.171 +        #udpsink name=upd_audio host=224.0.0.1 port=5002
  15.172 +
  15.173 +        abin = gst.Bin()
  15.174 +        if not self._setup_audio_encode(abin):
  15.175 +            return False
  15.176 +
  15.177 +        #Finish Pipeline
  15.178 +        pipe.add(src, decode, abin, vbin, mux, sink)
  15.179 +        gst.element_link_many(src, decode)
  15.180 +        gst.element_link_many(mux, sink)
  15.181 +
  15.182 +        #Linking decode with mux
  15.183 +        mux_audio = mux.get_pad("audio_0")
  15.184 +        mux_video = mux.get_pad("video_0")
  15.185 +
  15.186 +        audio_pad = abin.get_pad("src")
  15.187 +        video_pad = vbin.get_pad("src")
  15.188 +
  15.189 +        if audio_pad.link(mux_audio) != gst.PAD_LINK_OK:
  15.190 +            self.log.info("Fail to link audio with mux")
  15.191 +            return False
  15.192 +
  15.193 +        if video_pad.link(mux_video) != gst.PAD_LINK_OK:
  15.194 +            self.log.info("Fail to link audio with mux")
  15.195 +            return False
  15.196 +
  15.197 +        self.stream_data = self.StreamData(self.log, pipe, abin, vbin, sink)
  15.198 +        bus = pipe.get_bus()
  15.199 +        bus.add_signal_watch()
  15.200 +        bus.connect("message", self.__on_bus_message, self.stream_data)
  15.201 +
  15.202 +        decode.connect("new-decoded-pad", self.__on_decode_new_pad, self.stream_data)
  15.203 +        decode.connect("unknown-type", self.__on_decode_unknown_type, self.stream_data)
  15.204 +
  15.205 +        self.log.info("Setting PIPELINE state to PAUSED")
  15.206 +        pipe.set_state(gst.STATE_PAUSED)
  15.207 +        self.log.info("Running Loop")
  15.208 +        self.stream_data.Loop.run()
  15.209 +    # setup()
  15.210 +
  15.211 +    def __on_bus_message(self, bus, message, stream_data):
  15.212 +
  15.213 +        t = message.type
  15.214 +
  15.215 +        if t == gst.MESSAGE_STATE_CHANGED:
  15.216 +            oldstate = -1
  15.217 +            newstate = -1
  15.218 +            pending = -1
  15.219 +
  15.220 +            oldstate, newstate, pending = message.parse_state_changed()
  15.221 +
  15.222 +            if oldstate == gst.STATE_READY and \
  15.223 +               newstate == gst.STATE_PAUSED and \
  15.224 +               pending == gst.STATE_VOID_PENDING and \
  15.225 +               stream_data.Ready == False:
  15.226 +
  15.227 +                state_changed_status, current_state, pending_state = stream_data.Pipe.get_state()
  15.228 +                if current_state == gst.STATE_PAUSED and \
  15.229 +                    pending_state == gst.STATE_VOID_PENDING:
  15.230 +                    self.log.info("Pipe paused")
  15.231 +                    stream_data.Loop.quit()
  15.232 +                    stream_data.Ready = True
  15.233 +
  15.234 +        elif t == gst.MESSAGE_EOS:
  15.235 +            self.log.info("Pipe finished")
  15.236 +            stream_data.Loop.quit()
  15.237 +            self.quit = True
  15.238 +
  15.239 +        elif t == gst.MESSAGE_ERROR:
  15.240 +            err, debug = message.parse_error()
  15.241 +            self.log.error("Error: %s %s" %(err, debug))
  15.242 +            stream_data.Loop.quit()
  15.243 +            stream_data.Ready = False
  15.244 +
  15.245 +        return True
  15.246 +    # __on_bus_message()
  15.247 +
  15.248 +    def __on_decode_unknown_type(self, decode, pad, caps, stream_data):
  15.249 +        self.log.info("Unknown Type")
  15.250 +        return None
  15.251 +    # __on_decode_unknown_type
  15.252 +
  15.253 +    def __on_decode_new_pad(self, decode, pad, arg1, stream_data):
  15.254 +
  15.255 +        caps = pad.get_caps().to_string()
  15.256 +        self.log.info("New pad " + caps)
  15.257 +        if caps.rfind("audio") != -1:
  15.258 +            apad = stream_data.Abin.get_pad("sink")
  15.259 +            if pad.link(apad) != gst.PAD_LINK_OK:
  15.260 +                self.log.info("Error on link audio pad")
  15.261 +                return None
  15.262 +        elif caps.rfind("video") != -1:
  15.263 +            vpad = stream_data.Vbin.get_pad("sink")
  15.264 +            if pad.link(vpad) != gst.PAD_LINK_OK:
  15.265 +                self.log.info("Error on link video pad")
  15.266 +                return None
  15.267 +        else:
  15.268 +            self.log.info("Invalid caps")
  15.269 +        self.log.info("Linked")
  15.270 +    # __on_decode_new_pad
  15.271 +
  15.272 +
  15.273 +    def start(self, outfd):
  15.274 +        params_first = self.params_first
  15.275 +
  15.276 +        self.setup(params_first("uri", ""), params_first("mux", "avi"),
  15.277 +                   params_first("vcodec", "ffenc_h263p"), params_first("vbitrate", 256000),
  15.278 +                   params_first("fps", 25),  params_first("acodec", "faac"),
  15.279 +                   params_first("abitrate", 192000),  params_first("width", 320),
  15.280 +                   params_first("height", 240), params_first("options", ""))
  15.281 +
  15.282 +        self.log.info("Play %s", outfd.fileno())
  15.283 +        self.stream_data.Sink.set_property("fd", outfd.fileno())
  15.284 +        self.log.info("Setting Pipeline state to PLAYING")
  15.285 +        self.stream_data.Pipe.set_state(gst.STATE_PLAYING)
  15.286 +
  15.287 +        # keep playing until EOS
  15.288 +        self.log.info("QUIT: %s" % self.quit)
  15.289 +
  15.290 +        i = 0
  15.291 +        loop = gobject.MainLoop()
  15.292 +        loop.run()
  15.293 +
  15.294 +        self.log.info("quit loop")
  15.295 +
  15.296 +        return True
  15.297 +    # start()
  15.298 +
  15.299 +    def stop(self):
  15.300 +        self.log.info("Stop stream_data: %s" % self.stream_data)
  15.301 +
  15.302 +        if self.stream_data:
  15.303 +            self.stream_data.Pipe.set_state(gst.STATE_NULL)
  15.304 +            self.quit = True
  15.305 +
  15.306 +        del self.stream_data
  15.307 +        self.stream_data = None
  15.308 +    # stop
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/gmyth-stream/server/0.2/plugins/transcoders/mencoder.py	Wed Apr 18 15:59:10 2007 +0100
    16.3 @@ -0,0 +1,123 @@
    16.4 +import lib.utils as utils
    16.5 +import lib.server as server
    16.6 +import os
    16.7 +import signal
    16.8 +import subprocess
    16.9 +
   16.10 +__all__ = ("TranscoderMencoder",)
   16.11 +
   16.12 +class TranscoderMencoder(server.Transcoder):
   16.13 +    mencoder_path = utils.which("mencoder")
   16.14 +    def_mencoder_outfile = os.path.join(os.path.sep, "tmp",
   16.15 +                                        "mencoder-fifo-%(uid)s-%(pid)s")
   16.16 +    name = "mencoder"
   16.17 +    priority = -1
   16.18 +
   16.19 +    def __init__(self, params):
   16.20 +        server.Transcoder.__init__(self, params)
   16.21 +        self.proc = None
   16.22 +        self.args = None
   16.23 +
   16.24 +        vars = {"uid": os.getuid(), "pid": os.getpid()}
   16.25 +        mencoder_outfile_base = self.def_mencoder_outfile % vars
   16.26 +        mencoder_outfile = mencoder_outfile_base
   16.27 +        i = 0
   16.28 +        while os.path.exists(mencoder_outfile):
   16.29 +            i += 1
   16.30 +            mencoder_outfile = mencoder_outfile_base + ".%s" % i
   16.31 +
   16.32 +        self.mencoder_outfile = mencoder_outfile
   16.33 +        os.mkfifo(self.mencoder_outfile)
   16.34 +
   16.35 +        args = [self.mencoder_path, "-really-quiet",
   16.36 +                "-o", self.mencoder_outfile]
   16.37 +
   16.38 +        params_first = self.params_first
   16.39 +
   16.40 +        type = params_first("type")
   16.41 +        location = params_first("location")
   16.42 +        args.append("%s://%s" % (type, location))
   16.43 +
   16.44 +        mux = params_first("mux", "avi")
   16.45 +        args.extend(["-of", mux])
   16.46 +
   16.47 +        acodec = params_first("acodec", "mp3")
   16.48 +        abitrate = params_first("abitrate", "128")
   16.49 +        if acodec == "mp3lame":
   16.50 +            args.extend(["-oac", "mp3lame", "-lameopts",
   16.51 +                         "cbr:br=%s" % abitrate])
   16.52 +        else:
   16.53 +            args.extend(["-oac", "lavc", "-lavcopts",
   16.54 +                         "acodec=%s:abitrate=%s" % (acodec, abitrate)])
   16.55 +
   16.56 +        vcodec = params_first("vcodec", "mpeg4")
   16.57 +        vbitrate = params_first("vbitrate", "400")
   16.58 +        args.extend(["-ovc", "lavc", "-lavcopts",
   16.59 +                     "vcodec=%s:vbitrate=%s" % (vcodec, vbitrate)])
   16.60 +
   16.61 +        fps = params_first("fps", "24")
   16.62 +        args.extend(["-ofps", fps])
   16.63 +
   16.64 +        width = params_first("width", "320")
   16.65 +        height = params_first("height", "240")
   16.66 +        args.extend(["-vf", "scale=%s:%s" % (width, height)])
   16.67 +
   16.68 +        self.args = args
   16.69 +    # __init__()
   16.70 +
   16.71 +
   16.72 +    def _unlink_fifo(self):
   16.73 +        try:
   16.74 +            os.unlink(self.mencoder_outfile)
   16.75 +        except Exception, e:
   16.76 +            pass
   16.77 +    # _unlink_fifo()
   16.78 +
   16.79 +
   16.80 +    def start(self, outfd):
   16.81 +        cmd = " ".join(self.args)
   16.82 +        self.log.info("Mencoder: %s" % cmd)
   16.83 +
   16.84 +        try:
   16.85 +            self.proc = subprocess.Popen(self.args, close_fds=True)
   16.86 +        except Exception, e:
   16.87 +            self.log.error("Error executing mencoder: %s" % cmd)
   16.88 +            return False
   16.89 +
   16.90 +        try:
   16.91 +            fifo_read = open(self.mencoder_outfile)
   16.92 +        except Exception, e:
   16.93 +            self.log.error("Error opening fifo: %s" % cmd)
   16.94 +            return False
   16.95 +
   16.96 +        try:
   16.97 +            while self.proc and self.proc.poll() == None:
   16.98 +                d = fifo_read.read(1024)
   16.99 +                outfd.write(d)
  16.100 +        except Exception, e:
  16.101 +            self.log.error("Problems handling data: %s" % e)
  16.102 +            self._unlink_fifo()
  16.103 +            return False
  16.104 +
  16.105 +        self._unlink_fifo()
  16.106 +        return True
  16.107 +    # start()
  16.108 +
  16.109 +
  16.110 +    def stop(self):
  16.111 +        if self.proc:
  16.112 +            try:
  16.113 +                os.kill(self.proc.pid, signal.SIGTERM)
  16.114 +            except OSError, e:
  16.115 +                pass
  16.116 +
  16.117 +            try:
  16.118 +                self.proc.wait()
  16.119 +            except Exception, e:
  16.120 +                pass
  16.121 +
  16.122 +            self.proc = None
  16.123 +
  16.124 +        self._unlink_fifo()
  16.125 +    # stop()
  16.126 +# TranscoderMencoder
    17.1 --- a/gmyth-stream/server/lib.py	Wed Apr 18 15:47:40 2007 +0100
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,36 +0,0 @@
    17.4 -import time
    17.5 -import logging
    17.6 -import os
    17.7 -import stat
    17.8 -
    17.9 -ext = ['mpg', 'avi', 'mp4', 'nuv', 'mpeg', 'mov']
   17.10 -
   17.11 -def now():
   17.12 -    return time.strftime("%Y-%m-%d %H:%M:%S");
   17.13 -
   17.14 -def log(msg):
   17.15 -    logging.log(logging.DEBUG, msg)
   17.16 -    new_msg = "[%s] %s" % (now(), msg)
   17.17 -    return new_msg
   17.18 -
   17.19 -
   17.20 -bin_path_list = os.environ["PATH"].split(os.pathsep)
   17.21 -def which(prg):
   17.22 -    for d in bin_path_list:
   17.23 -        path = os.path.join(d, prg)
   17.24 -        if os.path.exists(path):
   17.25 -            st = os.stat(path)
   17.26 -            if st[stat.ST_MODE] & 0111:
   17.27 -                return path
   17.28 -    return ""
   17.29 -
   17.30 -def list_media_files(directory, file_list):
   17.31 -    for root, dirs, files in os.walk(directory):
   17.32 -        for name in files:
   17.33 -            if os.path.splitext(name)[1].strip(".") in ext:
   17.34 -                media = os.path.join(root,name)
   17.35 -                if media not in file_list:
   17.36 -                    file_list.append(os.path.join(root,name))
   17.37 -
   17.38 -    return True
   17.39 -
    18.1 --- a/gmyth-stream/server/main.py	Wed Apr 18 15:47:40 2007 +0100
    18.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.3 @@ -1,185 +0,0 @@
    18.4 -#!/usr/bin/python
    18.5 -
    18.6 -import os
    18.7 -import lib
    18.8 -import sys
    18.9 -import imp
   18.10 -import ConfigParser
   18.11 -import logging as log
   18.12 -
   18.13 -log.basicConfig(level=log.DEBUG,
   18.14 -                format="%(asctime)s %(levelname)-8s %(message)s",
   18.15 -                datefmt='%Y-%m-%d %H:%M:%S')
   18.16 -
   18.17 -config = ConfigParser.ConfigParser()
   18.18 -config.read("stream.conf")
   18.19 -
   18.20 -def load_module(pathlist, name):
   18.21 -    fp, path, desc = imp.find_module(name, pathlist)
   18.22 -    try:
   18.23 -        module = imp.load_module(name, fp, path, desc)
   18.24 -        return module
   18.25 -    finally:
   18.26 -        if fp:
   18.27 -            fp.close()
   18.28 -
   18.29 -
   18.30 -media_plugin = config.get("Media", "engine")
   18.31 -media_plugin_module = load_module(["./plugins/media"], media_plugin)
   18.32 -media = media_plugin_module.Media(config)
   18.33 -
   18.34 -comm_plugin = config.get("Comm", "engine")
   18.35 -comm_plugin_module = load_module(["./plugins/comm"], comm_plugin)
   18.36 -server = comm_plugin_module.Server(config)
   18.37 -
   18.38 -log.info("Starting GMyth-Stream server")
   18.39 -
   18.40 -
   18.41 -'''
   18.42 -PROTOCOL DESCRIPTION
   18.43 -=====================
   18.44 -
   18.45 -COMMAND OPTIONS
   18.46 -
   18.47 --> SETUP DESCRIPTION
   18.48 -|-> used to setup transcoding and streaming parameters
   18.49 -|-> must be used before any "PLAY" command
   18.50 -|-> e.g:
   18.51 -
   18.52 -file://file_name mux vcodec vbitrate fps acodec abitrate width height options
   18.53 -dvd://title_number mux vcodec vbitrate fps acodec abitrate width height options
   18.54 -
   18.55 --> PLAY DESCRIPTION
   18.56 - |-> used to start transcoding and streaming of file
   18.57 - |-> must be used just if SETUP was used before
   18.58 - |-> after it, _must_ send STOP
   18.59 -
   18.60 --> STOP DESCRIPTION
   18.61 - |-> used to stop transcoding and streaming process
   18.62 - |-> must be used just if PLAY was used before
   18.63 - |-> must be used after PLAY
   18.64 -
   18.65 --> QUIT DESCRIPTION
   18.66 - |-> used to quit the main loop (quit program)
   18.67 -
   18.68 -'''
   18.69 -nextport = 0
   18.70 -setup = (False, "STOPPED")
   18.71 -
   18.72 -def do_setup(server, filename, mux, vcodec, vbitrate, fps, acodec, abitrate,
   18.73 -             width, height, *options):
   18.74 -    global nextport
   18.75 -    global setup
   18.76 -
   18.77 -    if setup[1] != "PLAYING":
   18.78 -        nextport += 1
   18.79 -        ret = media.setup(filename, mux, vcodec, vbitrate, fps, acodec,
   18.80 -                          abitrate, width, height, nextport, options)
   18.81 -        if ret[0]:
   18.82 -            server.sendOk()
   18.83 -        else:
   18.84 -            server.sendNotOk(ret[1])
   18.85 -
   18.86 -        setup = (True, setup[1])
   18.87 -
   18.88 -    else: server.sendNotOk("You must STOP before SETingUP again")
   18.89 -
   18.90 -    return True
   18.91 -
   18.92 -def do_play(server):
   18.93 -    global setup
   18.94 -
   18.95 -    if setup[0] and setup[1] == "STOPPED":
   18.96 -        setup = (setup[0], "PLAYING")
   18.97 -        ret = media.play()
   18.98 -        if ret[0]:
   18.99 -            server.sendOk("%d" % nextport)
  18.100 -        else:
  18.101 -            server.sendNotOk(ret[1])
  18.102 -
  18.103 -    else:
  18.104 -        if setup[1] == "STOPPED":
  18.105 -            server.sendNotOk("You must SETUP before PLAYing")
  18.106 -        else:
  18.107 -            server.sendNotOk("You must STOP before PLAYing again")
  18.108 -
  18.109 -    return True
  18.110 -
  18.111 -def do_stop(server):
  18.112 -    global setup
  18.113 -
  18.114 -    media.stop()
  18.115 -    setup = (False, "STOPPED")
  18.116 -    server.sendOk()
  18.117 -    return True
  18.118 -
  18.119 -def do_list(server, *directory):
  18.120 -    file_list = []
  18.121 -    for j in directory:
  18.122 -        lib.list_media_files(j, file_list)
  18.123 -
  18.124 -    server.sendOk(file_list)
  18.125 -    return True
  18.126 -
  18.127 -def do_quit(server):
  18.128 -    server.finish = 1
  18.129 -    media.stop()
  18.130 -    server.sendOk()
  18.131 -    return True
  18.132 -
  18.133 -
  18.134 -mapping = {
  18.135 -    "SETUP": do_setup,
  18.136 -    "PLAY": do_play,
  18.137 -    "STOP": do_stop,
  18.138 -    "LIST": do_list,
  18.139 -    "QUIT": do_quit,
  18.140 -    }
  18.141 -
  18.142 -
  18.143 -def dispatch(server, msg):
  18.144 -    pieces = msg.split()
  18.145 -    if len(pieces) < 1:
  18.146 -        log.error("Invalid client command format: %r" % msg)
  18.147 -        server.sendNotOk("Invalid Format")
  18.148 -        return False
  18.149 -
  18.150 -    cmd = pieces[0]
  18.151 -    f = mapping.get(cmd, None)
  18.152 -    if not f:
  18.153 -        log.error("Unknow command: %r" % msg)
  18.154 -        server.sendNotOk("Unknow Command")
  18.155 -        return False
  18.156 -
  18.157 -    try:
  18.158 -        return f(server, *pieces[1:])
  18.159 -    except Exception, e:
  18.160 -        log.error("Could not execute %r: %s" % (msg, e))
  18.161 -        server.sendNotOk(str(e))
  18.162 -        return False
  18.163 -
  18.164 -
  18.165 -
  18.166 -while not server.finish:
  18.167 -    conn, client, port = server.getRequest()
  18.168 -    if nextport == 0:
  18.169 -        nextport = port
  18.170 -
  18.171 -    while not server.finish:
  18.172 -        msg = server.getMsg()
  18.173 -        if not msg:
  18.174 -            break
  18.175 -
  18.176 -        log.info("Client %s sent command: %r" % (client, msg))
  18.177 -        dispatch(server, msg)
  18.178 -
  18.179 -    log.info("Closing connection with %s" % (client,))
  18.180 -    server.disconnect_client(conn)
  18.181 -    try:
  18.182 -        os.wait()
  18.183 -    except Exception, e:
  18.184 -        log.error(e)
  18.185 -
  18.186 -server.stop()
  18.187 -log.info("Server stopped. Closing...")
  18.188 -
    19.1 --- a/gmyth-stream/server/plugins/comm/tcp.py	Wed Apr 18 15:47:40 2007 +0100
    19.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.3 @@ -1,79 +0,0 @@
    19.4 -import lib
    19.5 -import time
    19.6 -import socket
    19.7 -import logging as log
    19.8 -
    19.9 -class Server(object):
   19.10 -
   19.11 -    def __init__(self, config):
   19.12 -        self.host = '0.0.0.0'
   19.13 -        self.port = int(config.get("Comm", "port"))
   19.14 -        self.finish = 0
   19.15 -
   19.16 -        addr = (self.host, self.port)
   19.17 -        log.debug("Setup TCP server at %s:%s" % addr)
   19.18 -        self.tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   19.19 -        self.tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
   19.20 -        self.tcp.bind(addr)
   19.21 -        self.tcp.listen(1)
   19.22 -        log.info("TCP server listening at %s:%s (sock=%d)" %
   19.23 -                 (self.host, self.port, self.tcp.fileno()))
   19.24 -
   19.25 -    def getMsg(self):
   19.26 -        bytes = []
   19.27 -        try:
   19.28 -            while 1:
   19.29 -                c = self.con.recv(1)
   19.30 -                bytes.append(c)
   19.31 -                if not c or c == "\n":
   19.32 -                    break
   19.33 -        except Exception, e:
   19.34 -            log.error("Error reading message from client: %s" % e)
   19.35 -            return None
   19.36 -
   19.37 -        if not bytes or bytes[-1] != "\n":
   19.38 -            msg = "".join(bytes)
   19.39 -            log.error("Invalid message from client: %r" % msg)
   19.40 -            return None
   19.41 -
   19.42 -        # remove \n and \r
   19.43 -        bytes.pop()
   19.44 -        if bytes[-1] == "\r":
   19.45 -            bytes.pop()
   19.46 -
   19.47 -        msg = "".join(bytes)
   19.48 -        log.debug("RECV: %r" % msg)
   19.49 -        return msg
   19.50 -
   19.51 -    def sendMsg(self, msg):
   19.52 -        log.debug("SEND: %r" % msg)
   19.53 -        self.con.send(msg + "\n")
   19.54 -
   19.55 -    def sendOk(self, payload=None):
   19.56 -        self.sendMsg("OK %d" % bool(payload is not None))
   19.57 -        if payload is not None:
   19.58 -            if not isinstance(payload, (tuple, list)):
   19.59 -                payload = (payload,)
   19.60 -            for e in payload:
   19.61 -                self.sendMsg("+%s" % e)
   19.62 -            self.sendMsg(".")
   19.63 -
   19.64 -    def sendNotOk(self, reason=""):
   19.65 -        self.sendMsg("NOTOK %r" % reason)
   19.66 -
   19.67 -    def getRequest(self):
   19.68 -        log.debug("Wait for client request at %s:%s (sock=%d)" %
   19.69 -                  (self.host, self.port, self.tcp.fileno()))
   19.70 -        self.con, self.client = self.tcp.accept()
   19.71 -        log.info("Incoming request from %s (con=%s)" %
   19.72 -                 (self.client, self.con.fileno()))
   19.73 -        return (self.con, self.client, self.port)
   19.74 -
   19.75 -    def disconnect_client(self, connection):
   19.76 -        log.info("Closed request from %s (con=%s)" %
   19.77 -                 (self.client, self.con.fileno()))
   19.78 -        connection.close()
   19.79 -
   19.80 -    def stop(self):
   19.81 -        log.debug("Stop")
   19.82 -        self.tcp.close()
    20.1 --- a/gmyth-stream/server/plugins/comm/xmlrpc.py	Wed Apr 18 15:47:40 2007 +0100
    20.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.3 @@ -1,102 +0,0 @@
    20.4 -import lib
    20.5 -import SimpleXMLRPCServer
    20.6 -
    20.7 -
    20.8 -class Handler:
    20.9 -
   20.10 -    def __init__(self, recv_pool, send_pool):
   20.11 -        self.recv_pool = recv_pool
   20.12 -        self.send_pool = send_pool
   20.13 -        self.getMsg = self.sendMsg
   20.14 -
   20.15 -    def _listMethods(self):
   20.16 -        return ['setup', 'play', 'stop', 'close', 'getMsg']
   20.17 -
   20.18 -    def _methodHelp(self, method):
   20.19 -
   20.20 -        if method == 'setup':
   20.21 -            return "Setup the Media: setup( filename, mux, vcodec, vbitrate,"\
   20.22 -                   " fps, acodec, abitrate, width, height, port, options"
   20.23 -        elif method == 'play':
   20.24 -            return "Play the Media: play()"
   20.25 -        elif method == 'stop':
   20.26 -            return "Stop the Media: stop()"
   20.27 -        elif method == 'close':
   20.28 -            return "Close the connection: close()"
   20.29 -        elif method == 'getMsg':
   20.30 -            return "Return the first message in the pool: getMsg()"
   20.31 -        else:
   20.32 -            # By convention, return empty
   20.33 -            # string if no help is available
   20.34 -            return ""
   20.35 -
   20.36 -    def setup(self, filename, mux, vcodec, vbitrate,\
   20.37 -            fps, acodec, abitrate, width, height, port, options):
   20.38 -
   20.39 -        msg = "%s %s %s %s %s %s %s" % (filename, mux, vcodec, vbitrate,\
   20.40 -                                        fps, acodec, abitrate, width, height, port)
   20.41 -
   20.42 -        if len(options) > 0:
   20.43 -            for opt in options:
   20.44 -                msg += " %s" % opt
   20.45 -
   20.46 -        self.recv_pool.append("SETUP")
   20.47 -        self.recv_pool.append(msg)
   20.48 -        return self.sendMsg()
   20.49 -
   20.50 -    def play(self):
   20.51 -        self.recv_pool.append("PLAY")
   20.52 -        return self.sendMsg()
   20.53 -
   20.54 -    def stop(self):
   20.55 -        self.recv_pool.append("STOP")
   20.56 -        return self.sendMsg()
   20.57 -
   20.58 -    def close(self):
   20.59 -        self.recv_pool.append("CLOSE")
   20.60 -        return self.sendMsg()
   20.61 -
   20.62 -    def sendMsg(self):
   20.63 -        if self.send_pool != []:
   20.64 -            return self.send_pool.pop(0)
   20.65 -        else:
   20.66 -            return ""
   20.67 -
   20.68 -
   20.69 -class Server:
   20.70 -
   20.71 -    def __init__(self, config):
   20.72 -        self.host = 'localhost'
   20.73 -        self.port = int(config.get("Comm", "port"))
   20.74 -        self.finish = 0
   20.75 -        self.recv_pool = []
   20.76 -        self.send_pool = []
   20.77 -
   20.78 -        self.handler = Handler(self.recv_pool, self.send_pool)
   20.79 -
   20.80 -        self.xmlrpc = SimpleXMLRPCServer.SimpleXMLRPCServer((self.host, self.port))
   20.81 -        self.xmlrpc.register_instance(self.handler)
   20.82 -
   20.83 -
   20.84 -    def getMsg(self, size):
   20.85 -        if self.recv_pool != []:
   20.86 -            return self.recv_pool.pop(0)
   20.87 -        else:
   20.88 -            return ""
   20.89 -
   20.90 -    def sendMsg(self, msg):
   20.91 -        self.send_pool.append(msg)
   20.92 -
   20.93 -    def Ack(self, command):
   20.94 -        msg = "[%s] Command %s received" % (lib.now(), command)
   20.95 -        self.sendMsg(msg + "\n")
   20.96 -
   20.97 -    def getRequest(self):
   20.98 -        self.xmlrpc.handle_request()
   20.99 -        return (0, "RPC Client")
  20.100 -
  20.101 -    def disconnect_client(self, connection):
  20.102 -        connection = 0
  20.103 -
  20.104 -    def stop(self):
  20.105 -        self.xmlrpc.server_close()
    21.1 --- a/gmyth-stream/server/plugins/media/ffmpeg.py	Wed Apr 18 15:47:40 2007 +0100
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,91 +0,0 @@
    21.4 -import os
    21.5 -import sys
    21.6 -import lib
    21.7 -import time
    21.8 -import socket
    21.9 -import ConfigParser
   21.10 -
   21.11 -class Media:
   21.12 -
   21.13 -    def __init__(self, config):
   21.14 -
   21.15 -        self.config = config
   21.16 -        self.socket = None
   21.17 -        self.child_pid = None
   21.18 -
   21.19 -    def setup(self, filename, mux, vcodec, vbitrate,\
   21.20 -              fps, acodec, abitrate, width, height, port):
   21.21 -
   21.22 -        self.filename = filename
   21.23 -        self.mux = mux
   21.24 -        self.vcodec = vcodec
   21.25 -        self.vbitrate = int(vbitrate)
   21.26 -        self.fps = int(fps)
   21.27 -        self.acodec = acodec
   21.28 -        self.abitrate = int(abitrate)
   21.29 -        self.width = int(width)
   21.30 -        self.height = int(height)
   21.31 -
   21.32 -        self.port = int(port)
   21.33 -
   21.34 -        # good one: /tmp/mpg/cpm.mpg mpeg mpeg1video 400 25 mp2 192 320 240 5000
   21.35 -        self.path = self.config.get("FFmpeg", "path")
   21.36 -        self.path += " -i %s -f %s -vcodec %s -b %d -r %d -acodec %s -ab %d -s %dx%d -" % (
   21.37 -            self.filename, self.mux, self.vcodec, self.vbitrate,\
   21.38 -            self.fps, self.acodec, self.abitrate, self.width, self.height)
   21.39 -
   21.40 -        if (self.socket != None):
   21.41 -            del(self.socket)
   21.42 -
   21.43 -        self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
   21.44 -        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
   21.45 -        self.socket.bind( ('', self.port) )
   21.46 -        self.socket.settimeout(10)
   21.47 -        self.socket.listen(1)
   21.48 -
   21.49 -    def play(self):
   21.50 -
   21.51 -        lib.log("Starting FFmpeg: %s" % self.path)
   21.52 -
   21.53 -        # exec FFmpeg and get stdout
   21.54 -        child_stdin, child_stdout = os.popen2(self.path)
   21.55 -        child_stdin.close()
   21.56 -
   21.57 -        self.child_pid = os.fork()
   21.58 -        if (self.child_pid == 0):
   21.59 -            #child
   21.60 -
   21.61 -            conn,addr= self.socket.accept()
   21.62 -            lib.log("Sending Data to client: %s" % addr[0])
   21.63 -            data = child_stdout.read(1024)
   21.64 -            conn.settimeout(5)
   21.65 -            retry = 0
   21.66 -
   21.67 -            while( data != "" and retry < 5):
   21.68 -                try:
   21.69 -                    conn.send(data)
   21.70 -                except socket.error:
   21.71 -                    lib.log("Socket error (maybe timeout ?)")
   21.72 -                    retry = retry + 1
   21.73 -
   21.74 -                data = child_stdout.read(1024)
   21.75 -
   21.76 -            if (retry < 5):
   21.77 -                lib.log("Finished sending Data to client: %s" % addr[0])
   21.78 -            else:
   21.79 -                lib.log("Client timed out")
   21.80 -
   21.81 -            child_stdout.close()
   21.82 -            #conn.close()
   21.83 -            #sys.exit()
   21.84 -
   21.85 -
   21.86 -    def stop(self):
   21.87 -
   21.88 -        if (self.socket != None):
   21.89 -            lib.log("Closing socket")
   21.90 -            self.socket.close()
   21.91 -
   21.92 -        lib.log("Trying to stop FFmpeg process")
   21.93 -        if (self.child_pid != None):
   21.94 -            os.kill(self.child_pid, 9)
    22.1 --- a/gmyth-stream/server/plugins/media/gstreamer-rtp.py	Wed Apr 18 15:47:40 2007 +0100
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,218 +0,0 @@
    22.4 -import pygst
    22.5 -pygst.require("0.10")
    22.6 -import gst
    22.7 -import gobject
    22.8 -
    22.9 -class Media:
   22.10 -    class StreamData:
   22.11 -        stream_count = 0
   22.12 -		
   22.13 -        def __init__ (self, pipe, abin, vbin):
   22.14 -
   22.15 -	    self.stream_count += 1
   22.16 -	    self.Id = self.stream_count
   22.17 -	    self.Pipe = pipe
   22.18 -	    self.Abin = abin
   22.19 -	    self.Vbin = vbin
   22.20 -	    self.Loop = gobject.MainLoop()
   22.21 -	    self.ACaps = ""
   22.22 -	    self.VCaps = ""
   22.23 -	    self.Ready = False
   22.24 -
   22.25 -
   22.26 -    def __init__(self, config):
   22.27 -        # set gstreamer basic options
   22.28 -        self.config = config
   22.29 -        self.pipe = None
   22.30 -        self.streams = []
   22.31 -
   22.32 -
   22.33 -    def setup(self, filename, mux, vcodec, vbitrate,
   22.34 -              fps, acodec, abitrate, width, height, port, options):
   22.35 -
   22.36 -        ## Pipelines
   22.37 -        self.pipe = gst.Pipeline ()
   22.38 -        uri = "file://" + filename
   22.39 -        print "Opening Uri:" + uri
   22.40 -        src = gst.element_make_from_uri (gst.URI_SRC, uri, "src")
   22.41 -        if (src is None):
   22.42 -            return None
   22.43 -        
   22.44 -        decode = gst.element_factory_make ("decodebin", "decode")
   22.45 -        if (decode is None):
   22.46 -            return None
   22.47 -        
   22.48 -        
   22.49 -        #video encode 
   22.50 -        #queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! videorate ! ffenc_h263p bitrate=256000 me-method=2 ! rtph263ppay ! udpsink  host=224.0.0.1 port=5000
   22.51 -        vbin = gst.Bin ()
   22.52 -        vqueue = gst.element_factory_make ("queue", "vqueue")
   22.53 -        vscale = gst.element_factory_make ("videoscale", "vscale")
   22.54 -        vrate = gst.element_factory_make ("videorate", "vrate")
   22.55 -        vencode = gst.element_factory_make ("ffenc_mpeg4", "vencode")
   22.56 -        vpay = gst.element_factory_make ("rtpmp4vpay", "vpay")
   22.57 -        vsink = gst.element_factory_make ("udpsink", "vsink")
   22.58 -
   22.59 -        if (None in [vbin, vqueue, vscale, vrate, vencode, vpay, vsink]):
   22.60 -            print "Fail to create video encode elements."
   22.61 -            return None
   22.62 -
   22.63 -        vscale_pad = vscale.get_pad("sink")
   22.64 -        if (vscale_pad is None):
   22.65 -            print "Fail to get vscale sink pad."
   22.66 -            return None
   22.67 -
   22.68 -        vscale_caps = gst.caps_from_string ("video/x-raw-yuv, width=%s, height=%s" % (width, height))
   22.69 -        if (vscale_caps is None):
   22.70 -            print "Fail to create video caps"
   22.71 -            return None
   22.72 -
   22.73 -        if (not vscale_pad.set_caps (vscale_caps)):
   22.74 -            print "Fail to set video output caps"
   22.75 -            return None
   22.76 -        
   22.77 -        vencode.set_property ("bitrate", 256000)
   22.78 -        vencode.set_property ("me-method", 2)
   22.79 -        
   22.80 -        vsink.set_property ("host", "224.0.0.1")
   22.81 -        vsink.set_property ("port", 5000)
   22.82 -        
   22.83 -        vbin.add (vqueue, vscale, vrate, vencode, vpay, vsink)
   22.84 -        if (not gst.element_link_many (vqueue,  vscale, vrate, vencode, vpay, vsink)):
   22.85 -            print "Fail to link video elements"
   22.86 -            return None
   22.87 -        
   22.88 -        vbin.add_pad (gst.GhostPad ("sink", vqueue.get_pad ("sink")))
   22.89 -
   22.90 -        #audio encode
   22.91 -        #audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay !  udpsink name=upd_audio host=224.0.0.1 port=5002
   22.92 -        abin = gst.Bin ()
   22.93 -        aqueue = gst.element_factory_make ("queue", "vqueue")
   22.94 -        aconvert = gst.element_factory_make ("audioconvert", "aconvert")
   22.95 -        aencode = gst.element_factory_make ("faac", "aencode")
   22.96 -        apay = gst.element_factory_make ("rtpmp4gpay", "apay")
   22.97 -        asink = gst.element_factory_make ("udpsink", "asink")
   22.98 -
   22.99 -        if (None in [abin, aqueue, aconvert, aencode, apay, asink]):
  22.100 -            print "Fail to create video encode elements."
  22.101 -            return None
  22.102 -
  22.103 -        asink.set_property ("host", "224.0.0.1")
  22.104 -        asink.set_property ("port", 5002)
  22.105 -        
  22.106 -        abin.add (aqueue, aconvert, aencode, apay, asink)
  22.107 -        if (not gst.element_link_many (aqueue, aconvert, aencode, apay, asink)):
  22.108 -            print "Fail to link video elements"
  22.109 -            return None
  22.110 -        
  22.111 -        abin.add_pad (gst.GhostPad ("sink", aqueue.get_pad ("sink")))
  22.112 -
  22.113 -	self.pipe.add (src, decode, abin, vbin)
  22.114 -	gst.element_link_many (src, decode)
  22.115 -
  22.116 -	stream_data = self.StreamData (self.pipe, abin, vbin)
  22.117 -
  22.118 -	bus = self.pipe.get_bus()
  22.119 -	bus.add_signal_watch()
  22.120 -	bus.connect("message", self.__on_bus_message, stream_data)
  22.121 -	
  22.122 -	decode.connect("new-decoded-pad", self.__on_decode_new_pad, stream_data)
  22.123 -	decode.connect("unknown-type", self.__on_decode_unknown_type, stream_data)
  22.124 -
  22.125 -	
  22.126 -	self.pipe.set_state (gst.STATE_PAUSED)
  22.127 -        print "Running Pipe"
  22.128 -	stream_data.Loop.run ()
  22.129 -        print "End run"
  22.130 -
  22.131 -	a_caps = stream_data.ACaps
  22.132 -	v_caps = stream_data.VCaps
  22.133 -	stream_id = stream_data.Id
  22.134 -
  22.135 -        self.streams.append (stream_data)
  22.136 -
  22.137 -    def play(self):
  22.138 -
  22.139 -        print "Trying to play pipeline: %s" % self.pipe
  22.140 -        try:
  22.141 -            if (self.pipe):
  22.142 -                self.pipe.set_state(gst.STATE_PLAYING)
  22.143 -        except gobject.GError, e:
  22.144 -            print "Error: " + str(e)
  22.145 -
  22.146 -
  22.147 -    def stop(self):
  22.148 -
  22.149 -        print "Trying to stop pipeline: %s" % self.pipe
  22.150 -        try:
  22.151 -            if (self.pipeline):
  22.152 -                self.pipeline.set_state(gst.STATE_NULL)
  22.153 -        except gobject.GError, e:
  22.154 -            print "Error: " + str(e)
  22.155 -
  22.156 -    def __on_bus_message (self, bus, message, stream_data):
  22.157 -
  22.158 -        t = message.type
  22.159 -        if (t == gst.MESSAGE_STATE_CHANGED):
  22.160 -            oldstate = -1
  22.161 -            newstate = -1
  22.162 -            pending = -1
  22.163 -            oldstate, newstate, pending = message.parse_state_changed ()
  22.164 -            if ((oldstate == gst.STATE_READY) and \
  22.165 -                (newstate == gst.STATE_PAUSED) and \
  22.166 -                (pending == gst.STATE_VOID_PENDING) and \
  22.167 -                (stream_data.Ready == False)):
  22.168 -                state_changed_status, current_state, pending_state = stream_data.Pipe.get_state () 
  22.169 -		if ((current_state == gst.STATE_PAUSED) and \
  22.170 -                    (pending_state == gst.STATE_VOID_PENDING)):
  22.171 -                    print "Pipe paused"
  22.172 -                    self.__fill_sink_pads (stream_data)
  22.173 -                    stream_data.Loop.quit ()
  22.174 -                    stream_data.Ready = True
  22.175 -        elif (t == gst.MESSAGE_ERROR):
  22.176 -            err, debug = message.parse_error()
  22.177 -	    print "Error: %s" % err, debug
  22.178 -            stream_data.Loop.quit ()
  22.179 -            stream_data.Ready = False
  22.180 -
  22.181 -        return True
  22.182 - 
  22.183 -
  22.184 -    def __fill_sink_pads (self, stream_data):
  22.185 -        
  22.186 -        asink = stream_data.Abin.get_by_name ("asink")
  22.187 -        vsink = stream_data.Vbin.get_by_name ("vsink")
  22.188 -
  22.189 -        asink_pad = asink.get_pad ("sink")
  22.190 -        stream_data.ACaps = asink_pad.get_negotiated_caps().to_string()
  22.191 -        print "ACAPS " + stream_data.ACaps
  22.192 -
  22.193 -        vsink_pad = vsink.get_pad ("sink")
  22.194 -        stream_data.VCaps = vsink_pad.get_negotiated_caps().to_string()
  22.195 -        print "ACAPS " + stream_data.VCaps
  22.196 - 
  22.197 - 
  22.198 -
  22.199 -    def __on_decode_unknown_type (self, decode, pad, caps, stream_data):
  22.200 -
  22.201 -        print "Unknown Type"
  22.202 -        return None
  22.203 -
  22.204 -    def __on_decode_new_pad (self, decode, pad, arg1, stream_data):
  22.205 -        
  22.206 -        caps = pad.get_caps().to_string()
  22.207 -        print "New pad " + caps
  22.208 -	if (caps.rfind ("audio") != -1):
  22.209 -            apad = stream_data.Abin.get_pad ("sink")
  22.210 -            if (pad.link (apad) != gst.PAD_LINK_OK):
  22.211 -                print "Error on link audio pad"
  22.212 -                return None
  22.213 -        elif (caps.rfind ("video") != -1):
  22.214 -            vpad = stream_data.Vbin.get_pad ("sink")
  22.215 -            if (pad.link (vpad) != gst.PAD_LINK_OK):
  22.216 -                print "Error on link video pad"
  22.217 -                return None
  22.218 -        else:
  22.219 -            print "Invalid caps"
  22.220 -
  22.221 -            
    23.1 --- a/gmyth-stream/server/plugins/media/gstreamer.py	Wed Apr 18 15:47:40 2007 +0100
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,290 +0,0 @@
    23.4 -#vim:ts=4:sw=4:et
    23.5 -import pygst
    23.6 -pygst.require("0.10")
    23.7 -import gst
    23.8 -import gobject
    23.9 -import socket
   23.10 -import time
   23.11 -from threading import Thread
   23.12 -
   23.13 -class Media:
   23.14 -    class StreamListener(Thread):
   23.15 -        def __init__ (self, stream_data):
   23.16 -            Thread.__init__(self)
   23.17 -            self.stream = stream_data
   23.18 -            print "Thread Created"
   23.19 -
   23.20 -        def run (self):
   23.21 -            #Create socket
   23.22 -            print "Waiting connection"
   23.23 -            self.stream.Socket.listen(1)
   23.24 -            self.stream.Connection, self.stream.Addr = self.stream.Socket.accept ()
   23.25 -            print "Connection requested"
   23.26 -            self.stream.Sink.set_property ("fd", self.stream.Connection.fileno())
   23.27 -            self.stream.Pipe.set_state(gst.STATE_PLAYING)
   23.28 -            print "PLAYING"
   23.29 -
   23.30 -
   23.31 -    class StreamData:
   23.32 -        stream_count = 0
   23.33 -
   23.34 -        def __init__ (self, pipe, abin, vbin, sink):
   23.35 -            self.stream_count += 1
   23.36 -            self.Id = self.stream_count
   23.37 -            self.Pipe = pipe
   23.38 -            self.Abin = abin
   23.39 -            self.Vbin = vbin
   23.40 -            self.Sink = sink
   23.41 -            self.Loop = gobject.MainLoop()
   23.42 -            self.ACaps = ""
   23.43 -            self.VCaps = ""
   23.44 -            self.Ready = False
   23.45 -            self.Socket = None
   23.46 -            self.Connection = None
   23.47 -            self.Addr = None
   23.48 -
   23.49 -    def __init__(self, config):
   23.50 -        # set gstreamer basic options
   23.51 -        self.config = config
   23.52 -        self.streams = []
   23.53 -        self.socket = None
   23.54 -        self.connection = None
   23.55 -        self.addr = None
   23.56 -        self.ready = False
   23.57 -		self.current = None
   23.58 -
   23.59 -
   23.60 -    def setup(self, uri, mux, vcodec, vbitrate,
   23.61 -              fps, acodec, abitrate, width, height, port, options):
   23.62 -
   23.63 -        ## Pipelines
   23.64 -        pipe = gst.Pipeline ()
   23.65 -        print "Opening Uri:" + uri
   23.66 -        src = gst.element_make_from_uri (gst.URI_SRC, uri, "src")
   23.67 -        #src = gst.element_factory_make ("gnomevfssrc", "src")
   23.68 -        src.set_property ("location", uri)
   23.69 -        if (src is None):
   23.70 -            print "Fail to create src element"
   23.71 -            return None
   23.72 -
   23.73 -        print ("Create source")
   23.74 -        decode = gst.element_factory_make ("decodebin", "decode")
   23.75 -        if (decode is None):
   23.76 -            print "Fail to create decodebin"
   23.77 -            return None
   23.78 -
   23.79 -        print ("Create source")
   23.80 -        mux = gst.element_factory_make ("avimux", "mux")
   23.81 -        if (mux is None):
   23.82 -            print "Fail to create mux"
   23.83 -            return None
   23.84 -
   23.85 -        sink = gst.element_factory_make ("fdsink", "sink")
   23.86 -        if (sink is None):
   23.87 -            print "Fail to create fdsink"
   23.88 -            return None
   23.89 -
   23.90 -        print ("Create source")
   23.91 -
   23.92 -        #video encode
   23.93 -        #queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! videorate ! ffenc_h263p bitrate=256000 me-method=2 ! rtph263ppay ! udpsink  host=224.0.0.1 port=5000
   23.94 -        vbin = gst.Bin ()
   23.95 -        vqueue = gst.element_factory_make ("queue", "vqueue")
   23.96 -        colorspace = gst.element_factory_make ("ffmpegcolorspace", "")
   23.97 -        vrate = gst.element_factory_make ("videorate", "vrate")
   23.98 -        vencode = gst.element_factory_make ("ffenc_mpeg4", "vencode")
   23.99 -        #vencode = gst.element_factory_make ("ffenc_msmpeg4v1", "vencode")
  23.100 -        vqueue_src = gst.element_factory_make ("queue", "vqueue_src")
  23.101 -
  23.102 -        #if (int(vbitrate) > 0):
  23.103 -        vencode.set_property ("bitrate", 200)
  23.104 -        #vencode.set_property ("quant-type", 1)
  23.105 -        vencode.set_property ("pass", 2)
  23.106 -        vencode.set_property ("quantizer", 5)
  23.107 -        #vencode.set_property ("me-method", 1)
  23.108 -
  23.109 -
  23.110 -        if (None in [vbin, vqueue, vrate, vencode, vqueue_src]):
  23.111 -            print "Fail to create video encode elements."
  23.112 -            return None
  23.113 -
  23.114 -        vbin.add (vqueue)
  23.115 -        if ((int(width) > 0) and (int(height) > 0)):
  23.116 -            print ("formating output to %d / %d" % (int(width), int(height)))
  23.117 -  
  23.118 -            vscale = gst.element_factory_make ("ffvideoscale", "vscale")
  23.119 -
  23.120 -            vbin.add (vscale);
  23.121 -            if (not vqueue.link (vscale)):
  23.122 -                print "Fail to link video elements"
  23.123 -                return None
  23.124 -
  23.125 -            vbin.add (colorspace)
  23.126 -
  23.127 -            if (not vscale.link (colorspace, \
  23.128 -                gst.caps_from_string ("video/x-raw-yuv,width=(int)%d,height=(int)%d" % (int(width), int(height))))):
  23.129 -                print "Fail to link video elements"
  23.130 -                return None
  23.131 -        else:                
  23.132 -            vbin.add (colorspace)
  23.133 -            vqueue.link (colorspace)
  23.134 -        
  23.135 -        vbin.add (vrate, vencode, vqueue_src)
  23.136 -        if (not colorspace.link (vrate)):
  23.137 -            print "Fail to colorspace with vrate"
  23.138 -            return None
  23.139 -
  23.140 -
  23.141 -        if (not vrate.link (vencode, \
  23.142 -            gst.caps_from_string ("video/x-raw-yuv,framerate=(fraction)10/1"))):
  23.143 -            print "Fail to link vrate element"
  23.144 -            return None
  23.145 -
  23.146 -        if (not vencode.link (vqueue_src)):
  23.147 -            print "Fail to link video encode with queue"
  23.148 -            return None
  23.149 -
  23.150 -        vbin.add_pad (gst.GhostPad ("sink", vqueue.get_pad ("sink")))
  23.151 -        vbin.add_pad (gst.GhostPad ("src", vqueue_src.get_pad ("src")))
  23.152 -
  23.153 -        #audio encode
  23.154 -        #audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay !  udpsink name=upd_audio host=224.0.0.1 port=5002
  23.155 -        abin = gst.Bin ()
  23.156 -        aqueue = gst.element_factory_make ("queue", "aqueue")
  23.157 -        aconvert = gst.element_factory_make ("audioconvert", "aconvert")
  23.158 -        arate = gst.element_factory_make ("audioresample", "arate")
  23.159 -        #aencode = gst.element_factory_make ("ffenc_ac3", "aencode")
  23.160 -        aencode = gst.element_factory_make ("queue", "aencode")
  23.161 -        #aencode = gst.element_factory_make ("lame", "aencode")
  23.162 -        #aencode = gst.element_factory_make ("ffenc_mp2", "aencode")
  23.163 -        aqueue_src = gst.element_factory_make ("queue", "aqueue_src")
  23.164 -
  23.165 -        if (None in [abin, aqueue, arate, aencode, aqueue_src]):
  23.166 -            print "Fail to create video encode elements."
  23.167 -            return None
  23.168 -
  23.169 -        abin.add (aqueue, aconvert, arate, aencode, aqueue_src)
  23.170 -        if (not gst.element_link_many (aqueue,  aconvert, arate, aencode, aqueue_src)):
  23.171 -            print "Fail to link video elements"
  23.172 -            return None
  23.173 -
  23.174 -        abin.add_pad (gst.GhostPad ("sink", aqueue.get_pad ("sink")))
  23.175 -        abin.add_pad (gst.GhostPad ("src", aqueue_src.get_pad ("src")))
  23.176 -
  23.177 -        #Finish Pipeline
  23.178 -        pipe.add (src, decode, abin, vbin, mux, sink)
  23.179 -        gst.element_link_many (src, decode)
  23.180 -        gst.element_link_many (mux, sink)
  23.181 -
  23.182 -        #Linking decode with mux
  23.183 -        mux_audio = mux.get_pad ("audio_0")
  23.184 -        mux_video = mux.get_pad ("video_0")
  23.185 -
  23.186 -        audio_pad = abin.get_pad ("src")
  23.187 -        video_pad = vbin.get_pad ("src")
  23.188 -
  23.189 -        if (audio_pad.link (mux_audio) != gst.PAD_LINK_OK):
  23.190 -            print "Fail to link audio with mux"
  23.191 -            return None
  23.192 -
  23.193 -        if (video_pad.link (mux_video) != gst.PAD_LINK_OK):
  23.194 -            print "Fail to link audio with mux"
  23.195 -            return None
  23.196 -
  23.197 -        stream_data = self.StreamData (pipe, abin, vbin, sink)
  23.198 -        bus = pipe.get_bus()
  23.199 -        bus.add_signal_watch()
  23.200 -        bus.connect ("message", self.__on_bus_message, stream_data)
  23.201 -
  23.202 -        decode.connect("new-decoded-pad", self.__on_decode_new_pad, stream_data)
  23.203 -        decode.connect("unknown-type", self.__on_decode_unknown_type, stream_data)
  23.204 -
  23.205 -        print ("Create source")
  23.206 -        pipe.set_state (gst.STATE_PAUSED)
  23.207 -        print "Running Pipe"
  23.208 -        stream_data.Loop.run ()
  23.209 -        print "End run"
  23.210 -
  23.211 -
  23.212 -        #Create socket
  23.213 -        stream_data.Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  23.214 -        print "Bind on port %d" % port
  23.215 -        stream_data.Socket.bind(('', int (port)))
  23.216 -        self.streams.append (stream_data)
  23.217 -        return (True, "")
  23.218 -
  23.219 -    def play(self):
  23.220 -        print "Play"
  23.221 -        stream = self.streams[0]
  23.222 -        self.current = self.StreamListener(stream)
  23.223 -        self.current.start ()
  23.224 -        time.sleep (1)
  23.225 -        return (True, "")
  23.226 -
  23.227 -    def stop(self):
  23.228 -		self.current.join ()
  23.229 -        self.current = None
  23.230 -        stream = self.streams[0]
  23.231 -        stream.Pipe.set_state(gst.STATE_NULL)
  23.232 -        del (stream.Pipe)
  23.233 -        stream.Pipe = None
  23.234 -        stream.Abin = None
  23.235 -        stream.Vbin = None
  23.236 -        stream.Sink = None
  23.237 -		if (stream.Connection != None):
  23.238 -	        stream.Connection.close ()
  23.239 -
  23.240 -        self.streams = []
  23.241 -        time.sleep (5)             
  23.242 -        return (True, "")
  23.243 -
  23.244 -
  23.245 -    def __on_bus_message (self, bus, message, stream_data):
  23.246 -
  23.247 -        t = message.type
  23.248 -        if (t == gst.MESSAGE_STATE_CHANGED):
  23.249 -            oldstate = -1
  23.250 -            newstate = -1
  23.251 -            pending = -1
  23.252 -            oldstate, newstate, pending = message.parse_state_changed ()
  23.253 -            if ((oldstate == gst.STATE_READY) and \
  23.254 -                (newstate == gst.STATE_PAUSED) and \
  23.255 -                (pending == gst.STATE_VOID_PENDING) and \
  23.256 -                (stream_data.Ready == False)):
  23.257 -                state_changed_status, current_state, pending_state = stream_data.Pipe.get_state ()
  23.258 -                if ((current_state == gst.STATE_PAUSED) and \
  23.259 -                    (pending_state == gst.STATE_VOID_PENDING)):
  23.260 -                    print "Pipe paused"
  23.261 -                    stream_data.Loop.quit ()
  23.262 -                    stream_data.Ready = True
  23.263 -        elif (t == gst.MESSAGE_ERROR):
  23.264 -            err, debug = message.parse_error()
  23.265 -            print "Error: %s" % err, debug
  23.266 -            stream_data.Loop.quit ()
  23.267 -            stream_data.Ready = False
  23.268 -
  23.269 -        return True
  23.270 -
  23.271 -    def __on_decode_unknown_type (self, decode, pad, caps, stream_data):
  23.272 -
  23.273 -        print "Unknown Type"
  23.274 -        return None
  23.275 -
  23.276 -    def __on_decode_new_pad (self, decode, pad, arg1, stream_data):
  23.277 -
  23.278 -        caps = pad.get_caps().to_string()
  23.279 -        print "New pad " + caps
  23.280 -        if (caps.rfind ("audio") != -1):
  23.281 -            apad = stream_data.Abin.get_pad ("sink")
  23.282 -            if (pad.link (apad) != gst.PAD_LINK_OK):
  23.283 -                print "Error on link audio pad"
  23.284 -                return None
  23.285 -        elif (caps.rfind ("video") != -1):
  23.286 -            vpad = stream_data.Vbin.get_pad ("sink")
  23.287 -            if (pad.link (vpad) != gst.PAD_LINK_OK):
  23.288 -                print "Error on link video pad"
  23.289 -                return None
  23.290 -        else:
  23.291 -            print "Invalid caps"
  23.292 -        print "Linked"            
  23.293 -
    24.1 --- a/gmyth-stream/server/plugins/media/mencoder.py	Wed Apr 18 15:47:40 2007 +0100
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,411 +0,0 @@
    24.4 -from __future__ import division
    24.5 -
    24.6 -import os
    24.7 -import sys
    24.8 -import lib
    24.9 -import time
   24.10 -import shlex
   24.11 -import signal
   24.12 -import socket
   24.13 -import ConfigParser
   24.14 -import logging as log
   24.15 -
   24.16 -from select import *
   24.17 -from subprocess import *
   24.18 -
   24.19 -class Media(object):
   24.20 -
   24.21 -    def __init__(self, config):
   24.22 -
   24.23 -        self.config = config
   24.24 -        self.do_cleanup()
   24.25 -
   24.26 -    # __init__()
   24.27 -
   24.28 -
   24.29 -    def do_cleanup(self):
   24.30 -        self.path = ""
   24.31 -        self.args = []
   24.32 -        self.language = None
   24.33 -        self.subtitle = None
   24.34 -        self.mpegopts = None
   24.35 -        self.socket = None
   24.36 -        self.child_pid = None
   24.37 -        self.mplayer = None
   24.38 -        self.mencoder_pid = None
   24.39 -        self.mplayer_pid = None
   24.40 -        self.audio_opts = None
   24.41 -        self.video_opts = None
   24.42 -        self.gst_pipe = None
   24.43 -        self.gst_pid = None
   24.44 -        self.transcode_local = None
   24.45 -
   24.46 -    # do_cleanup()
   24.47 -
   24.48 -
   24.49 -    def setup_opts(self, options):
   24.50 -
   24.51 -        for opt in options:
   24.52 -
   24.53 -            if opt == "local":
   24.54 -                self.mplayer = lib.which("mplayer")
   24.55 -
   24.56 -            elif opt.find("language=") >= 0:
   24.57 -                try:
   24.58 -                    lan = opt.split("=")[1]
   24.59 -                    if len(lan) < 2:
   24.60 -                        self.language = lan
   24.61 -                except Exception, e:
   24.62 -                    log.error("Bad language option: %s" % opt)
   24.63 -
   24.64 -            elif opt.find("subtitle=") >= 0:
   24.65 -                try:
   24.66 -                    sub = opt.split("=")[1]
   24.67 -                    if len(sub) < 2:
   24.68 -                        self.language = sub
   24.69 -                except Exception, e:
   24.70 -                    log.error("Bad subtitle option: %s" % opt)
   24.71 -
   24.72 -            elif opt.find("format=") >= 0:
   24.73 -                try:
   24.74 -                    self.mpegopts = opt.split("=")[1]
   24.75 -                except Exception, e:
   24.76 -                    log.error("Bad format option: %s" % opt)
   24.77 -
   24.78 -            elif opt.find("outfile=") >= 0:
   24.79 -                try:
   24.80 -                    self.transcode_local = opt.split("=")[1]
   24.81 -                except Exception, e:
   24.82 -                    log.error("Bad outfile option: %s" % opt)
   24.83 -
   24.84 -    # setup_opts()
   24.85 -
   24.86 -
   24.87 -    def run_mplayer(self):
   24.88 -        msg = self.filename
   24.89 -
   24.90 -        if self.kind == "dvd":
   24.91 -            msg = "dvd://" + msg
   24.92 -
   24.93 -        self.mplayer_pid = Popen([self.mplayer, self.filename, "1> %s" % os.devnull,\
   24.94 -                                  "2> %s" % os.devnull], stdout=PIPE, close_fds=True)
   24.95 -
   24.96 -    # run_mplayer()
   24.97 -
   24.98 -
   24.99 -    def setup_mencoder(self):
  24.100 -        self.path = self.config.get("Mencoder", "path")
  24.101 -        mp = Popen([self.path], stdout=PIPE, close_fds=True)
  24.102 -
  24.103 -        version = mp.stdout.read().split("MEncoder ")[1].split(" (C)")[0].split("-")[-1]
  24.104 -
  24.105 -        if version > "4.1.1": self.mencoder_old = False
  24.106 -        else: self.mencoder_old = True
  24.107 -
  24.108 -        os.kill(mp.pid, signal.SIGKILL)
  24.109 -        log.info("Mencoder version: %s" % version)
  24.110 -
  24.111 -        if self.mencoder_old:
  24.112 -            try:
  24.113 -                self.fifo = self.config.get("Mencoder", "fifo_path")
  24.114 -                os.mkfifo(self.fifo)
  24.115 -            except Exception, e:
  24.116 -                log.info("Fifo: %s" % e)
  24.117 -        else:
  24.118 -            self.fifo = "-"
  24.119 -
  24.120 -    # setup_mencoder()
  24.121 -
  24.122 -
  24.123 -    def setup_audio(self):
  24.124 -
  24.125 -        if self.acodec == "mp3lame":
  24.126 -            return "-oac mp3lame -lameopts cbr:br=%s vol=5" % self.abitrate
  24.127 -        else:
  24.128 -            return "-oac lavc -lavcopts acodec=%s:abitrate=%s" % (\
  24.129 -                self.acodec, self.abitrate)
  24.130 -
  24.131 -    # setup_audio()
  24.132 -
  24.133 -
  24.134 -    def setup_video(self):
  24.135 -
  24.136 -        video = ""
  24.137 -
  24.138 -        video += " -of %s" % self.mux
  24.139 -        video += " -ofps %s" % self.fps
  24.140 -
  24.141 -        if self.vcodec == "nuv" or self.vcodec == "xvid"\
  24.142 -               or self.vcodec == "qtvideo" or self.vcodec == "copy":
  24.143 -            video += " -ovc %s" % self.vcodec
  24.144 -        else:
  24.145 -            video += " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s" % (
  24.146 -                self.vcodec, self.vbitrate)
  24.147 -
  24.148 -        if self.mux == "mpeg" and self.mpegopts is not None:
  24.149 -            video += " -mpegopts format=%s" % self.mpegopts
  24.150 -
  24.151 -        video += " -vf scale=%s:%s" % (self.width, self.height)
  24.152 -
  24.153 -        return video
  24.154 -
  24.155 -    # setup_video()
  24.156 -
  24.157 -
  24.158 -    def arg_append(self, args, options):
  24.159 -        l = shlex.split(options)
  24.160 -        for i in l:
  24.161 -            args.append(i)
  24.162 -
  24.163 -    # arg_append()
  24.164 -
  24.165 -
  24.166 -    def setup_args(self, args):
  24.167 -
  24.168 -        args.append(self.path)
  24.169 -
  24.170 -        #args.append(self.filename)
  24.171 -        args.append("-")
  24.172 -
  24.173 -        if self.language != None:
  24.174 -            self.arg_append(args, "-alang %s" % self.language)
  24.175 -
  24.176 -        if self.subtitle != None:
  24.177 -            self.arg_append(args, "-slang %s" % self.subtitle)
  24.178 -            self.arg_append(args, "-subfps %s" % self.fps)
  24.179 -
  24.180 -        self.arg_append(args, "-idx")
  24.181 -        self.arg_append(args, self.audio_opts)
  24.182 -        self.arg_append(args, self.video_opts)
  24.183 -
  24.184 -        self.arg_append(args, "-really-quiet")
  24.185 -        self.arg_append(args, "-o %s" % self.fifo)
  24.186 -        self.arg_append(args, "2> %s" % os.devnull)
  24.187 -
  24.188 -    # setup_args()
  24.189 -
  24.190 -
  24.191 -    def setup_filename(self, filename):
  24.192 -        try:
  24.193 -            self.kind, self.filename = filename.split("://")
  24.194 -        except:
  24.195 -            return (False, "Wrong filename protocol")
  24.196 -
  24.197 -        if self.kind == "file":
  24.198 -            if not os.path.exists(self.filename):
  24.199 -                msg = "File requested does not exist. SETUP failed."
  24.200 -                log.error(msg)
  24.201 -                return (False, msg)
  24.202 -
  24.203 -        elif self.kind == "dvd":
  24.204 -            self.filename = "dvd://" + filename
  24.205 -
  24.206 -        elif self.kind == "myth":
  24.207 -            self.filename = filename
  24.208 -            self.gst_pipe = os.pipe()
  24.209 -            print self.gst_pipe[0]
  24.210 -            print self.gst_pipe[1]
  24.211 -
  24.212 -        return (True, "")
  24.213 -
  24.214 -    # setup_filename()
  24.215 -
  24.216 -
  24.217 -    def setup_socket(self):
  24.218 -        if self.socket != None:
  24.219 -            self.socket = None
  24.220 -
  24.221 -        self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  24.222 -        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  24.223 -
  24.224 -        try:
  24.225 -            self.socket.bind( ('', self.port) )
  24.226 -            self.socket.listen(1)
  24.227 -        except Exception, e:
  24.228 -            log.error("Could not create socket: %s" % e)
  24.229 -            return (False, e)
  24.230 -
  24.231 -        return (True, "")
  24.232 -
  24.233 -    # setup_socket()
  24.234 -
  24.235 -
  24.236 -    '''
  24.237 -    MENCODER SETUP DESCRIPTION
  24.238 -    ===========================
  24.239 -
  24.240 -    -> mux, vcodecs and acodecs
  24.241 -     |-> mencoder (-of | -ovc | -oac) help
  24.242 -
  24.243 -    -> if used mpeg as mux:
  24.244 -     |-> to setup format: format=%s as an option at the end
  24.245 -
  24.246 -    '''
  24.247 -
  24.248 -
  24.249 -    # good one: /tmp/dvb.mpg avi mpeg4 400 25 mp3lame 192 320 240
  24.250 -    # file:///tmp/dvb.mpg mpeg mpeg1video 400 25 mp2 192 320 240 format=mpeg1
  24.251 -    # dvd://4 mpeg mpeg1video 400 25 mp3lame 192 400 240 language=en local
  24.252 -    # file:///tmp/mpg/bad_day.mpg avi mpeg4 400 25 mp3 192 320 240
  24.253 -
  24.254 -    def setup(self, filename, mux, vcodec, vbitrate,\
  24.255 -              fps, acodec, abitrate, width, height, port, options):
  24.256 -
  24.257 -        if self.args != []:
  24.258 -            self.do_cleanup()
  24.259 -
  24.260 -        self.mux = mux
  24.261 -        self.vcodec = vcodec
  24.262 -        self.vbitrate = vbitrate
  24.263 -        self.fps = fps
  24.264 -        self.acodec = acodec
  24.265 -        self.abitrate = abitrate
  24.266 -        self.width = width
  24.267 -        self.height = height
  24.268 -        self.port = int(port)
  24.269 -
  24.270 -        self.setup_mencoder()
  24.271 -
  24.272 -        ret_val = self.setup_filename(filename)
  24.273 -
  24.274 -        if not ret_val[0]:
  24.275 -            return ret_val
  24.276 -
  24.277 -        self.setup_opts(options)
  24.278 -        self.audio_opts = self.setup_audio()
  24.279 -        self.video_opts = self.setup_video()
  24.280 -        self.setup_args(self.args)
  24.281 -
  24.282 -        ret_val = self.setup_socket()
  24.283 -        return ret_val
  24.284 -
  24.285 -    # setup()
  24.286 -
  24.287 -    def play_loop(self, conn):
  24.288 -        data = self.pout.read(4096)
  24.289 -
  24.290 -        conn.settimeout(5)
  24.291 -        retry = 0
  24.292 -
  24.293 -        if not self.transcode_local:
  24.294 -            while data != "" and retry < 5:
  24.295 -                try:
  24.296 -                    conn.send(data)
  24.297 -                    r, w, x = select([conn], [], [], 0)
  24.298 -                    if conn in r:
  24.299 -                        back = conn.recv(1024)
  24.300 -                        if back == "OK" and self.mplayer and not self.mplayer_pid:
  24.301 -                            self.run_mplayer()
  24.302 -
  24.303 -                except socket.error, e:
  24.304 -                    log.error("Socket error: %s" % e)
  24.305 -                    retry += 1
  24.306 -
  24.307 -                data = self.pout.read(4096)
  24.308 -
  24.309 -        else:
  24.310 -            local = open(self.transcode_local, "w")
  24.311 -            total = os.path.getsize(self.filename)
  24.312 -            partial = 4096
  24.313 -
  24.314 -            while data != "":
  24.315 -                try:
  24.316 -                    local.write(data)
  24.317 -                except Exception, e:
  24.318 -                    log.error("Write error: %s" % e)
  24.319 -
  24.320 -                data = self.pout.read(4096)
  24.321 -                partial += len(data)
  24.322 -                conn.send("%.2f\n" % (partial * 100 / total) )
  24.323 -
  24.324 -            local.close()
  24.325 -            conn.send("DONE\n")
  24.326 -
  24.327 -        return retry
  24.328 -
  24.329 -    # play_loop()
  24.330 -
  24.331 -
  24.332 -    def play(self):
  24.333 -
  24.334 -        if self.gst_pipe:
  24.335 -            try:
  24.336 -                gst = [ lib.which("gst-launch-0.10"), "--gst-debug-level=0" ]
  24.337 -                self.arg_append(gst, "mythtvsrc location=%s" % self.filename)
  24.338 -                self.arg_append(gst, "! fdsink fd=2")
  24.339 -                self.gst_pid = Popen(gst, close_fds=True)
  24.340 -                log.info("Running Gstreamer: %s" % gst);
  24.341 -            except Exception, e:
  24.342 -                msg = "Could not init Gstreamer: %s" % e
  24.343 -                log.error(msg)
  24.344 -                return (False, msg)
  24.345 -
  24.346 -
  24.347 -        log.info("Starting Mencoder: %s" % self.args )
  24.348 -        try:
  24.349 -            if not self.gst_pipe:
  24.350 -                self.stdin = open(self.filename)
  24.351 -            else:
  24.352 -                self.stdin = self.gst_pid.stdout
  24.353 -
  24.354 -            self.mencoder_pid = Popen(self.args, stdin=self.stdin, stdout=PIPE, close_fds=True)
  24.355 -        except Exception, e:
  24.356 -            msg = "Could not init Mencoder: %s" % e
  24.357 -            log.error(msg)
  24.358 -            return (False, msg)
  24.359 -
  24.360 -        if self.mencoder_old: self.pout = open(self.fifo)
  24.361 -        else: self.pout = self.mencoder_pid.stdout
  24.362 -
  24.363 -        self.child_pid = os.fork()
  24.364 -
  24.365 -        if self.child_pid == 0:
  24.366 -            conn, addr = self.socket.accept()
  24.367 -
  24.368 -            log.info("Sending Data to client: %s" % addr[0])
  24.369 -            retry = self.play_loop(conn)
  24.370 -
  24.371 -            if retry < 5:
  24.372 -                log.info("Finished sending Data to client: %s" % addr[0])
  24.373 -            else:
  24.374 -                log.error("Client timed out, retried more than %s times" % retry)
  24.375 -
  24.376 -            os.kill(self.mencoder_pid.pid, signal.SIGKILL)
  24.377 -            sys.exit(0)
  24.378 -
  24.379 -        return (True, "")
  24.380 -
  24.381 -    # play()
  24.382 -
  24.383 -
  24.384 -    def stop(self):
  24.385 -        try:
  24.386 -
  24.387 -            if self.mencoder_pid:
  24.388 -                os.kill(self.mencoder_pid.pid, signal.SIGTERM)
  24.389 -                self.mencoder_pid = None
  24.390 -
  24.391 -            if self.mplayer_pid:
  24.392 -                os.kill(self.mplayer_pid.pid, signal.SIGTERM)
  24.393 -                self.mplayer_pid = None
  24.394 -
  24.395 -            if self.socket:
  24.396 -                self.socket.close()
  24.397 -                self.socket = None
  24.398 -
  24.399 -            if self.child_pid:
  24.400 -                os.kill(self.child_pid, signal.SIGTERM)
  24.401 -                self.child_pid = None
  24.402 -
  24.403 -            if self.gst_pid:
  24.404 -                os.kill(self.gst_pid.pid, signal.SIGTERM)
  24.405 -                self.gst_pid = None
  24.406 -
  24.407 -            self.do_cleanup()
  24.408 -
  24.409 -            os.wait()
  24.410 -
  24.411 -        except Exception, e:
  24.412 -            log.error("Stop error: %s" % e)
  24.413 -
  24.414 -    # stop()
    25.1 --- a/gmyth-stream/server/plugins/media/vlc.py	Wed Apr 18 15:47:40 2007 +0100
    25.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.3 @@ -1,80 +0,0 @@
    25.4 -import os
    25.5 -import sys
    25.6 -import time
    25.7 -import socket
    25.8 -import ConfigParser
    25.9 -
   25.10 -class Media:
   25.11 -
   25.12 -    def __init__(self, config):
   25.13 -
   25.14 -        self.config = config
   25.15 -        self.pipe = ""
   25.16 -        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   25.17 -
   25.18 -        self.path = config.get("Vlc", "path")
   25.19 -        self.host = config.get("Vlc", "host")
   25.20 -        self.port = int(config.get("Vlc", "port"))
   25.21 -        self.pwd = config.get("Vlc", "pwd")
   25.22 -
   25.23 -        # exec VLC
   25.24 -        pid = os.fork()
   25.25 -        if (pid == 0):
   25.26 -            #child
   25.27 -            print "ESTOU EM CHILD"
   25.28 -            self.path += " -I telnet -d 1> /dev/null 2> /dev/null &"
   25.29 -            os.system(self.path)
   25.30 -            sys.exit(0)
   25.31 -        else:
   25.32 -            print "ESTOU EM PARENT 1"
   25.33 -            time.sleep(3)
   25.34 -            print "ESTOU EM PARENT 2"
   25.35 -            self.sock.connect( (self.host, self.port) )
   25.36 -            self.sock.send("%s\n" % self.pwd)
   25.37 -
   25.38 -
   25.39 -    def insert_file(self, filename):
   25.40 -
   25.41 -        self.sock.send("setup output0 input %s\n" % filename)
   25.42 -
   25.43 -
   25.44 -
   25.45 -    def setup(self, filename, mux, vcodec, vbitrate,\
   25.46 -              fps, acodec, abitrate, width, height, port):
   25.47 -
   25.48 -        self.filename = filename
   25.49 -        self.mux = mux
   25.50 -        self.vcodec = vcodec
   25.51 -        self.vbitrate = int(vbitrate)
   25.52 -        self.fps = int(fps)
   25.53 -        self.acodec = acodec
   25.54 -        self.abitrate = int(abitrate)
   25.55 -        self.width = int(width)
   25.56 -        self.height = int(height)
   25.57 -
   25.58 -        self.port = int(port)
   25.59 -
   25.60 -
   25.61 -        self.pipe = "#transcode{vcodec=%s,vb=%d,"\
   25.62 -                    "fps=25.0,scale=1,acodec=mpga,"\
   25.63 -                    "ab=64,channels=1,width=%d,height=%d}"\
   25.64 -                    ":duplicate{dst=std{access=http,"\
   25.65 -                    "mux=mpeg1,dst=:%d}}" % (self.vcodec, self.vbitrate,\
   25.66 -                                             self.widht, self.height,\
   25.67 -                                             self.port)
   25.68 -
   25.69 -        self.sock.send("setup output0 broadcast %s\n" % self.pipe)
   25.70 -        self.insert_file(self.filename)
   25.71 -
   25.72 -    def play(self):
   25.73 -
   25.74 -        print "Trying to play: %s" % self.pipe
   25.75 -        self.sock.send("control output0 play\n")
   25.76 -
   25.77 -
   25.78 -    def stop(self):
   25.79 -
   25.80 -        print "Trying to stop: %s" % self.pipe
   25.81 -        self.sock.send("control output0 stop\n")
   25.82 -
   25.83 -
    26.1 --- a/gmyth-stream/server/stream.conf	Wed Apr 18 15:47:40 2007 +0100
    26.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.3 @@ -1,23 +0,0 @@
    26.4 -[Comm]
    26.5 -engine = tcp
    26.6 -port = 50000
    26.7 -
    26.8 -
    26.9 -[Media]
   26.10 -engine = mencoder
   26.11 -
   26.12 -
   26.13 -[Vlc]
   26.14 -path = /usr/local/bin/vlc
   26.15 -host = 127.0.0.1
   26.16 -port = 4212
   26.17 -pwd = admin
   26.18 -
   26.19 -
   26.20 -[FFmpeg]
   26.21 -path = /usr/local/bin/ffmpeg
   26.22 -
   26.23 -
   26.24 -[Mencoder]
   26.25 -path = /usr/local/bin/mencoder
   26.26 -fifo_path = /tmp/teste
    27.1 --- a/gmyth-stream/server/tests/client.py	Wed Apr 18 15:47:40 2007 +0100
    27.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.3 @@ -1,51 +0,0 @@
    27.4 -import os
    27.5 -import sys
    27.6 -import time
    27.7 -import socket
    27.8 -
    27.9 -
   27.10 -if len(sys.argv) < 2:
   27.11 -    HOST = 'localhost'
   27.12 -    PORT = 50000
   27.13 -elif len(sys.argv) == 2:
   27.14 -    HOST = sys.argv[1]
   27.15 -    PORT = 50000
   27.16 -else:
   27.17 -    HOST = sys.argv[1]
   27.18 -    PORT = int(sys.argv[2])
   27.19 -
   27.20 -socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
   27.21 -socket.settimeout(10)
   27.22 -
   27.23 -try:
   27.24 -    socket.connect( (HOST,PORT) )
   27.25 -except:
   27.26 -    print "\n--> Could not connect to ('%s':'%d')\n" % (HOST,PORT)
   27.27 -    sys.exit(-1)
   27.28 -
   27.29 -
   27.30 -mplayer = os.popen("which mplayer").read().strip()
   27.31 -mplayer += " -idx - -vo x11 1> /dev/null"
   27.32 -pin, pout = os.popen2(mplayer)
   27.33 -
   27.34 -#teste = open("teste.avi", "w")
   27.35 -
   27.36 -data = socket.recv(4096)
   27.37 -i = 0
   27.38 -
   27.39 -while (data != ""):
   27.40 -    pin.write(data)
   27.41 -    #teste.write(data)
   27.42 -    data = socket.recv(4096)
   27.43 -    #if (i == 500):
   27.44 -    #    socket.send("OK")
   27.45 -    i += 1
   27.46 -
   27.47 -pin.close()
   27.48 -socket.close()
   27.49 -#teste.close()
   27.50 -
   27.51 -# from select import select
   27.52 -# r, w, x = select([pout], []. [], 0)
   27.53 -# if pout in r:
   27.54 -#     pout.read(32)