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