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 plugins.transcoders.mencoder_lib.mythtv as mythtv
19 from select import select
20 import lib.transcoder as transcoder
22 __all__ = ("TranscoderMencoder",)
24 class TranscoderMencoder(transcoder.Transcoder):
25 """Transcoder class that implements a transcoder using Mencoder"""
26 mencoder_path = utils.which("mencoder")
33 # only works with avi container
36 def _setup_params(self):
37 params_first = self.params_first
40 self.args["local"] = params_first("local", False)
41 self.args["language"] = params_first("language", False)
42 self.args["subtitle"] = params_first("subtitle", False)
43 self.args["format"] = params_first("format", "mpeg1")
44 self.args["outfile"] = params_first("outfile", "-")
47 self.args["type"] = params_first("type", "file")
48 self.args["input"] = params_first("uri", "-")
51 self.args["acodec"] = params_first("acodec", "mp2")
52 self.args["abitrate"] = params_first("abitrate", 192)
53 self.args["volume"] = params_first("volume", 5)
56 self.args["mux"] = params_first("mux", "mpeg")
57 self.args["fps"] = params_first("fps", 25)
58 self.args["vcodec"] = params_first("vcodec", "mpeg1video")
59 self.args["vbitrate"] = params_first("vbitrate", 400)
60 self.args["width"] = params_first("width", 320)
61 self.args["height"] = params_first("height", 240)
65 def _setup_audio(self):
66 if self.args["acodec"] == "mp3lame":
67 audio = "-oac mp3lame -lameopts cbr:br=%s vol=%s" % (
68 self.args["abitrate"], self.args["volume"])
70 audio = "-oac lavc -lavcopts acodec=%s:abitrate=%s" % (
71 self.args["acodec"], self.args["abitrate"])
77 def _setup_video(self):
78 video = " -of %s" % self.args["mux"]
79 video += " -ofps %s" % self.args["fps"]
81 vcodec = self.args["vcodec"]
82 if vcodec == "nuv" or vcodec == "xvid"\
83 or vcodec == "qtvideo" or vcodec == "copy":
84 video += " -ovc %s" % vcodec
86 video += " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s" % (
87 vcodec, self.args["vbitrate"])
89 if self.args["mux"] == "mpeg":
90 video += " -mpegopts format=%s" % self.args["format"]
92 video += " -vf scale=%s:%s" % (self.args["width"], self.args["height"])
97 def _arg_append(self, args, options):
98 for arg in shlex.split(options):
102 def _setup_mencoder_opts(self, args):
103 args.append(self.mencoder_path)
105 if self.args["type"] and self.args["type"] == "tv":
106 self._arg_append(args, self.args["tv"])
107 elif self.args["outfile"] == "-" and self.args["type"]:
108 args.append(self.args["input"])
112 if self.args["language"]:
113 self._arg_append(args, "-alang %s" % self.args["language"])
115 if self.args["subtitle"]:
116 self._arg_append(args, "-slang %s" % self.args["subtitle"])
117 self._arg_append(args, "-subfps %s" % self.args["fps"])
119 self._arg_append(args, "-idx")
120 self._arg_append(args, "-cache 1024")
121 self._arg_append(args, self._setup_audio())
122 self._arg_append(args, self._setup_video())
124 self._arg_append(args, "-really-quiet")
126 if self.args["outfile"] != "-":
127 self.args["outfile"] = ".transcoded/%s" % (
128 os.path.basename(self.args["outfile"]))
130 self._arg_append(args, "-o %s" % self.args["outfile"])
131 self._arg_append(args, "2>%s" % os.devnull)
134 def _setup_filename(self):
135 """This function setups the file to encode parsing the uri.
141 If the last one is detected we have to parse the uri to find args.
142 Then we store all the args inside a dictionary: self.args['gmyth-cat']
144 _type = self.args["type"]
147 if not os.path.exists(self.args["input"]):
149 "File requested does not exist: %s." % self.args["input"]
151 self.args["input"] = "file://%s" % self.args["input"]
154 self.args["input"] = "dvd://%s" % self.args["input"]
156 elif _type == "myth":
157 self.args["gmyth-cat"] = mythtv._setup_mythfilename(self)
160 driver = self.params_first("driver", "v4l2")
161 norm = self.params_first("norm", "pal-m")
162 channel = self.params_first("channel", "13")
163 chanlist = self.params_first("chanlist", "us-bcast")
164 outfmt = self.params_first("outfmt", "yuy2")
165 vdev = self.params_first("vdev", "/dev/video0")
166 adev = self.params_first("adev", "/dev/dsp")
167 self.args["tv"] = "tv:// -v -tv driver=%s:norm=%s:channel=%s:" \
168 "chanlist=%s:width=%s:height=%s:outfmt=%s:" \
169 "device=%s:adevice=%s" % (driver, norm,
177 def __init__(self, params):
178 transcoder.Transcoder.__init__(self, params)
179 self.mencoder_opts = []
183 self._setup_filename()
184 self._setup_mencoder_opts(self.mencoder_opts)
186 self.log.error(self.tid, "Error: %s" % e)
190 def _check_opened_file(self, stdw, _stdin):
194 return open(self.args["outfile"])
196 os.write(stdw, _stdin.read(1024))
200 def _start_outfile(self, outfd):
205 filename = self.args["input"].split("://")[1]
206 _stdin = open(filename)
207 size = int(os.path.getsize(filename))
209 self.log.error(self.tid, "Error: Mencoder stdin"\
210 " setup error: %s" % e)
211 outfd.write("Error: Mencoder stdin setup error: %s" %e)
218 stdr, stdw = os.pipe()
220 if not self._run_mencoder(input=stdr):
223 stdout = self._check_opened_file(stdw, _stdin)
227 while self.proc and self.proc.poll() == None:
229 data_in = _stdin.read(4096)
231 os.write(stdw, data_in)
233 d = stdout.read(4096)
234 self.status = utils.progress_bar(int(total_read),
241 d = stdout.read(4096)
244 self.log.error(self.tid, "Error: %s" % e)
248 self.log.info(self.tid, "OK: Done")
253 def _start(self, outfd):
254 # Play a file on disk or DVD
255 if not self._run_mencoder(output=subprocess.PIPE):
259 while self.proc and self.proc.poll() == None:
260 d = self.proc.stdout.read(1024)
263 self.log.error(self.tid, "Error: %s" % e)
266 self.log.info(self.tid, "OK: Done")
270 def _run_mencoder(self, input=None, output=None):
272 self.proc = subprocess.Popen(self.mencoder_opts, stdin=input,
273 stdout=output, close_fds=True)
275 self.log.error(self.tid, "Error: Mencoder: %s" % e)
281 def start(self, outfd):
282 print "mencoder_opts: %s" % self.mencoder_opts
283 cmd = " ".join(self.mencoder_opts)
284 self.log.debug(self.tid, "Plugin's tid: %s" % self.tid)
285 self.log.debug(self.tid, "Mencoder: %s" % cmd)
289 if self.args["outfile"] == "-" and \
290 self.args["type"] in ["file", "dvd", "tv"]:
291 ret = self._start(outfd)
293 elif self.args["type"] == "myth":
294 ret = mythtv.start_myth(self, outfd)
297 ret = self._start_outfile(outfd)
302 self.log.error(self.tid, "Error: Problems while "\
303 "starting streaming.")
308 def _aux_stop(self, obj, next=False):
311 os.kill(obj.pid, signal.SIGKILL)
313 os.kill(obj.pid+1, signal.SIGKILL)
326 self._aux_stop(self.proc, True)
327 self._aux_stop(self.gmyth)