gmyth-stream/server/plugins/media/mencoder.py
author morphbr
Wed Apr 04 17:08:11 2007 +0100 (2007-04-04)
branchtrunk
changeset 497 08a2d7d67ae5
parent 492 63d9475228ac
child 498 7a0c3906dce2
permissions -rw-r--r--
[svn r502] GMyth-Streamer: code cleanup
renatofilho@484
     1
import os
renatofilho@484
     2
import sys
renatofilho@484
     3
import lib
renatofilho@484
     4
import time
renatofilho@484
     5
import signal
renatofilho@484
     6
import socket
renatofilho@484
     7
import ConfigParser
renatofilho@484
     8
renatofilho@484
     9
from select import *
renatofilho@484
    10
from subprocess import *
renatofilho@484
    11
morphbr@497
    12
class Media(object):
renatofilho@484
    13
renatofilho@484
    14
    def __init__(self, config):
renatofilho@484
    15
renatofilho@484
    16
        self.config = config
renatofilho@484
    17
        self.language = "en"
renatofilho@484
    18
        self.socket = None
renatofilho@484
    19
        self.child_pid = None
renatofilho@484
    20
        self.mplayer = None
renatofilho@484
    21
        self.mencoder_pid = None
renatofilho@484
    22
        self.mplayer_pid = None
renatofilho@484
    23
        signal.signal(signal.SIGABRT, self.kill_handler)
renatofilho@484
    24
renatofilho@484
    25
    def kill_handler(self, sig, frame):
renatofilho@484
    26
        try:
renatofilho@484
    27
            os.kill(self.mplayer_pid.pid + 1, signal.SIGKILL)
renatofilho@484
    28
            sys.exit(0)
renatofilho@484
    29
        except:
renatofilho@484
    30
            lib.log("Problems closing child")
renatofilho@484
    31
renatofilho@484
    32
    def set_args(self, options):
renatofilho@484
    33
renatofilho@484
    34
        for opt in options:
renatofilho@484
    35
morphbr@497
    36
            if opt is "file" or opt is "dvd":
morphbr@497
    37
morphbr@497
    38
                if self.acodec is "mp3lame":
renatofilho@484
    39
                    audio = "-oac mp3lame -lameopts cbr:br=%s vol=5" % self.abitrate
renatofilho@484
    40
                else:
morphbr@492
    41
                    audio = "-oac lavc -lavcopts acodec=%s:abitrate=%s" % (\
renatofilho@484
    42
                        self.acodec, self.abitrate)
renatofilho@484
    43
morphbr@497
    44
morphbr@497
    45
            if opt is "file":
renatofilho@484
    46
                self.kind = "file"
morphbr@497
    47
                self.args += " %s -mf fps=%s -of %s %s"\
renatofilho@484
    48
                             " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s -vf scale=%s:%s"\
renatofilho@484
    49
                             " -o %s 1> /dev/null 2> /dev/null" % (
renatofilho@484
    50
                    self.filename, self.fps, self.mux, audio, self.vcodec,
renatofilho@484
    51
                    self.vbitrate, self.width, self.height, self.fifo)
renatofilho@484
    52
morphbr@497
    53
            elif opt is "dvd":
renatofilho@484
    54
                self.kind = "dvd"
renatofilho@484
    55
                self.args += " dvd://%s -alang %s -vf scale=%s:%s %s"\
renatofilho@484
    56
                             " -of %s -ovc lavc -lavcopts vcodec=%s:vbitrate=%s -o %s"\
renatofilho@484
    57
                             " -ofps %s 1> /dev/null 2> /dev/null" % (
renatofilho@484
    58
                    self.filename, self.language, self.width, self.height, audio,
renatofilho@484
    59
                    self.mux, self.vcodec, self.vbitrate, self.fifo, self.fps)
renatofilho@484
    60
morphbr@497
    61
            elif opt is "local":
renatofilho@484
    62
                self.mplayer = os.popen("which mplayer").read().strip()
renatofilho@484
    63
morphbr@497
    64
            elif opt.find("language=") >= 0:
renatofilho@484
    65
                try:
renatofilho@484
    66
                    self.language = opt.split("=")[1]
renatofilho@484
    67
                except:
renatofilho@484
    68
                    lib.log("Bad language option")
renatofilho@484
    69
morphbr@497
    70
            elif opt.find("format=") >= 0:
morphbr@497
    71
                try:
morphbr@497
    72
                    self.mux += " -mpegopts format=%s" % opt.split("=")[1]
morphbr@497
    73
                except:
morphbr@497
    74
                    lib.log("Bad format option")
morphbr@497
    75
renatofilho@484
    76
renatofilho@484
    77
    def run_mplayer(self):
renatofilho@484
    78
        msg = "%s 1>/dev/null 2>/dev/null" % self.filename
morphbr@497
    79
morphbr@497
    80
        if self.kind is "dvd":
renatofilho@484
    81
            msg = "dvd://" + msg
renatofilho@484
    82
renatofilho@484
    83
        self.mplayer += " " + msg
renatofilho@484
    84
        self.mplayer_pid = Popen(self.mplayer, shell=True)
renatofilho@484
    85
renatofilho@484
    86
    def setup(self, filename, mux, vcodec, vbitrate,\
renatofilho@484
    87
              fps, acodec, abitrate, width, height, port, options):
renatofilho@484
    88
renatofilho@484
    89
        self.filename = filename
renatofilho@484
    90
        self.mux = mux
renatofilho@484
    91
        self.vcodec = vcodec
renatofilho@484
    92
        self.vbitrate = vbitrate
renatofilho@484
    93
        self.fps = fps
renatofilho@484
    94
        self.acodec = acodec
renatofilho@484
    95
        self.abitrate = abitrate
renatofilho@484
    96
        self.width = width
renatofilho@484
    97
        self.height = height
renatofilho@484
    98
renatofilho@484
    99
        self.port = int(port)
renatofilho@484
   100
        self.fifo = self.config.get("Mencoder", "fifo_path")
renatofilho@484
   101
renatofilho@484
   102
        self.args = ""
renatofilho@484
   103
        self.kind = ""
renatofilho@484
   104
        self.set_args(options)
renatofilho@484
   105
morphbr@497
   106
        if self.kind is "file" and not os.path.exists(self.filename):
renatofilho@484
   107
            msg = "File requested does not exist. SETUP failed."
renatofilho@484
   108
            lib.log(msg)
renatofilho@484
   109
            return msg
renatofilho@484
   110
renatofilho@484
   111
        # good one: /tmp/dvb.mpg avi mpeg4 400 25 mp3lame 192 320 240 5000
morphbr@497
   112
        #4 mpeg mpeg1video 400 25 mp3lame 192 400 240 5000 language=en local dvd
renatofilho@484
   113
        self.path = self.config.get("Mencoder", "path")
renatofilho@484
   114
morphbr@497
   115
        if self.socket is not None:
renatofilho@484
   116
            del(self.socket)
renatofilho@484
   117
renatofilho@484
   118
        self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
renatofilho@484
   119
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
renatofilho@484
   120
        self.socket.bind( ('', self.port) )
renatofilho@484
   121
        self.socket.listen(1)
renatofilho@484
   122
renatofilho@484
   123
        return 0
renatofilho@484
   124
renatofilho@484
   125
renatofilho@484
   126
    def play(self):
renatofilho@484
   127
renatofilho@484
   128
        try:
renatofilho@484
   129
            os.mkfifo(self.fifo)
renatofilho@484
   130
        except:
renatofilho@484
   131
            lib.log("Fifo already exists")
renatofilho@484
   132
renatofilho@484
   133
        lib.log("Starting Mencoder: %s %s" % (self.path, self.args) )
renatofilho@484
   134
        # exec Mencoder
renatofilho@484
   135
        self.mencoder_pid = Popen(self.path + self.args, shell=True)
renatofilho@484
   136
renatofilho@484
   137
        fifo = open(self.fifo)
renatofilho@484
   138
renatofilho@484
   139
        self.child_pid = os.fork()
renatofilho@484
   140
morphbr@497
   141
        if self.child_pid is 0:
renatofilho@484
   142
            conn,addr= self.socket.accept()
renatofilho@484
   143
            lib.log("Sending Data to client: %s" % addr[0])
renatofilho@484
   144
renatofilho@484
   145
            data = fifo.read(1024)
renatofilho@484
   146
            conn.settimeout(5)
renatofilho@484
   147
            retry = 0
renatofilho@484
   148
morphbr@497
   149
            while data is not "" and retry < 5:
renatofilho@484
   150
                try:
renatofilho@484
   151
                    conn.send(data)
renatofilho@484
   152
                    r, w, x = select([conn], [], [], 0)
renatofilho@484
   153
                    if conn in r:
renatofilho@484
   154
                        back = conn.recv(1024)
morphbr@497
   155
                        if back is "OK" and self.mplayer and not self.mplayer_pid:
renatofilho@484
   156
                            self.run_mplayer()
renatofilho@484
   157
renatofilho@484
   158
                except socket.error:
renatofilho@484
   159
                    lib.log("Socket error (maybe timeout ?)")
renatofilho@484
   160
                    retry += 1
renatofilho@484
   161
renatofilho@484
   162
                data = fifo.read(1024)
renatofilho@484
   163
morphbr@497
   164
            if retry < 5:
renatofilho@484
   165
                lib.log("Finished sending Data to client: %s" % addr[0])
renatofilho@484
   166
            else:
renatofilho@484
   167
                lib.log("Client timed out")
renatofilho@484
   168
renatofilho@484
   169
            sys.exit(0)
renatofilho@484
   170
renatofilho@484
   171
renatofilho@484
   172
    def stop(self):
renatofilho@484
   173
        try:
renatofilho@484
   174
            os.kill(self.mencoder_pid.pid + 1, signal.SIGKILL)
renatofilho@484
   175
            self.mplayer = None
renatofilho@484
   176
        except:
renatofilho@484
   177
            lib.log("Trying to stop before playing...")
renatofilho@484
   178
morphbr@497
   179
        if self.socket is not None:
renatofilho@484
   180
            lib.log("Closing socket")
renatofilho@484
   181
            self.socket.close()
renatofilho@484
   182
renatofilho@484
   183
            lib.log("Trying to stop Mencoder process")
morphbr@497
   184
            if self.child_pid is not None:
renatofilho@484
   185
                os.kill(self.child_pid, signal.SIGABRT)