3 __author__ = "Artur Duque de Souza"
4 __author_email__ = "artur.souza@indt.org.br"
15 import lib.utils as utils
16 import lib.server as server
17 import lib.file_handler as files
18 import plugins.transcoders.mencoder_lib.mythtv as mythtv
20 from select import select
21 import lib.transcoder as transcoder
23 __all__ = ("TranscoderMencoder",)
25 class TranscoderMencoder(transcoder.Transcoder):
26 """Transcoder class that implements a transcoder using Mencoder"""
27 mencoder_path = utils.which("mencoder")
34 # only works with avi container
37 def _setup_params(self):
38 params_first = self.params_first
41 self.args["local"] = params_first("local", False)
42 self.args["language"] = params_first("language", False)
43 self.args["subtitle"] = params_first("subtitle", False)
44 self.args["format"] = params_first("format", "mpeg1")
45 self.args["outfile"] = params_first("outfile", "-")
48 self.args["type"] = params_first("type", "file")
49 self.args["input"] = params_first("uri", "-")
52 self.args["acodec"] = params_first("acodec", "mp2")
53 self.args["abitrate"] = params_first("abitrate", 192)
54 self.args["volume"] = params_first("volume", 5)
57 self.args["mux"] = params_first("mux", "mpeg")
58 self.args["fps"] = params_first("fps", 25)
59 self.args["vcodec"] = params_first("vcodec", "mpeg1video")
60 self.args["vbitrate"] = params_first("vbitrate", 400)
61 self.args["width"] = params_first("width", 320)
62 self.args["height"] = params_first("height", 240)
66 def _setup_audio(self):
67 if self.args["acodec"] == "mp3lame":
68 audio = "-oac mp3lame -lameopts cbr:br=%s vol=%s" % (
69 self.args["abitrate"], self.args["volume"])
71 audio = "-oac lavc -lavcopts acodec=%s:abitrate=%s" % (
72 self.args["acodec"], self.args["abitrate"])
78 def _setup_video(self):
79 video = " -of %s" % self.args["mux"]
80 video += " -ofps %s" % self.args["fps"]
82 vcodec = self.args["vcodec"]
83 if vcodec == "nuv" or vcodec == "xvid"\
84 or vcodec == "qtvideo" or vcodec == "copy":
85 video += " -ovc %s" % vcodec
87 video += " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s" % (
88 vcodec, self.args["vbitrate"])
90 if self.args["mux"] == "mpeg":
91 video += " -mpegopts format=%s" % self.args["format"]
92 video += " -vf scale=%s:%s" % (self.args["width"], self.args["height"])
98 def _arg_append(self, args, options):
99 for arg in shlex.split(options):
103 def _setup_mencoder_opts(self, args):
104 args.append(self.mencoder_path)
106 if self.args["outfile"] == "-" and self.args["type"]:
107 args.append(self.args["input"])
111 if self.args["language"]:
112 self._arg_append(args, "-alang %s" % self.args["language"])
114 if self.args["subtitle"]:
115 self._arg_append(args, "-slang %s" % self.args["subtitle"])
116 self._arg_append(args, "-subfps %s" % self.args["fps"])
118 self._arg_append(args, "-idx")
119 self._arg_append(args, "-cache 1024")
120 self._arg_append(args, self._setup_audio())
121 self._arg_append(args, self._setup_video())
123 self._arg_append(args, "-really-quiet")
125 if self.args["outfile"] != "-":
126 self.args["outfile"] = ".transcoded/%s" % (
127 os.path.basename(self.args["outfile"]))
129 self._arg_append(args, "-o %s" % self.args["outfile"])
130 self._arg_append(args, "2>%s" % os.devnull)
133 def _setup_filename(self):
134 """This function setups the file to encode parsing the uri.
140 If the last one is detected we have to parse the uri to find args.
141 Then we store all the args inside a dictionary: self.args['gmyth-cat']
143 _type = self.args["type"]
146 if not os.path.exists(self.args["input"]):
148 "File requested does not exist: %s." % self.args["input"]
150 self.args["input"] = "file://%s" % self.args["input"]
153 self.args["input"] = "dvd://".join(self.args["input"])
155 elif _type == "myth":
156 self.args["gmyth-cat"] = mythtv._setup_mythfilename(self)
160 def __init__(self, params):
161 transcoder.Transcoder.__init__(self, params)
162 self.mencoder_opts = []
166 self._setup_filename()
167 self._setup_mencoder_opts(self.mencoder_opts)
169 self.log.error(self.tid, "Error: %s" % e)
173 def _check_opened_file(self, stdw, _stdin):
177 return open(self.args["outfile"])
179 os.write(stdw, _stdin.read(1024))
183 def _start_outfile(self, outfd):
188 filename = self.args["input"].split("://")[1]
189 _stdin = open(filename)
190 size = int(os.path.getsize(filename))
192 self.log.error(self.tid, "Error: Mencoder stdin"\
193 " setup error: %s" % e)
194 outfd.write("Error: Mencoder stdin setup error: %s" %e)
201 stdr, stdw = os.pipe()
203 if not self._run_mencoder(input=stdr):
206 stdout = self._check_opened_file(stdw, _stdin)
209 while self.proc and self.proc.poll() == None:
211 data_in = _stdin.read(4096)
213 os.write(stdw, data_in)
215 d = stdout.read(4096)
216 self.status = utils.progress_bar(int(total_read),
223 d = stdout.read(4096)
226 self.log.error(self.tid, "Error: %s" % e)
230 files.TranscodedFile("", self.args)
231 self.log.info(self.tid, "OK: Done")
235 def _start(self, outfd):
236 # Play a file on disk or DVD
237 if not self._run_mencoder(output=subprocess.PIPE):
241 while self.proc and self.proc.poll() == None:
242 d = self.proc.stdout.read(1024)
245 self.log.error(self.tid, "Error: %s" % e)
248 self.log.info(self.tid, "OK: Done")
252 def _run_mencoder(self, input=None, output=None):
254 self.proc = subprocess.Popen(self.mencoder_opts, stdin=input,
255 stdout=output, close_fds=True)
257 self.log.error(self.tid, "Error: Mencoder: %s" % e)
263 def start(self, outfd):
264 cmd = " ".join(self.mencoder_opts)
265 self.log.debug(self.tid, "Plugin's tid: %s" % self.tid)
266 self.log.debug(self.tid, "Mencoder: %s" % cmd)
271 if self.args["outfile"] == "-" and \
272 self.args["type"] in ["file", "dvd"]:
273 ret = self._start(outfd)
275 elif self.args["type"] == "myth":
276 ret = mythtv.start_myth(self, outfd)
279 ret = self._start_outfile(outfd)
284 self.log.error(self.tid, "Error: Problems while "\
285 "starting streaming.")
290 def _aux_stop(self, obj, next=False):
293 os.kill(obj.pid, signal.SIGKILL)
295 os.kill(obj.pid+1, signal.SIGKILL)
308 self._aux_stop(self.proc, True)
309 self._aux_stop(self.gmyth)