-from Components.Task import Task, Job, job_manager, DiskspacePrecondition, Condition
+from Components.Task import Task, Job, job_manager, DiskspacePrecondition, Condition, ToolExistsPrecondition
from Screens.MessageBox import MessageBox
class png2yuvTask(Task):
def run(self, callback, task_progress_changed):
Task.run(self, callback, task_progress_changed)
+ self.container.stdoutAvail.get().remove(self.processStdout)
self.container.dumpToFile(self.dumpFile)
def processStderr(self, data):
- print "[png2yuvTask]", data
-
- def processStdout(self, data):
- pass
+ print "[png2yuvTask]", data[:-1]
class mpeg2encTask(Task):
def __init__(self, job, inputfile, outputfile):
self.container.readFromFile(self.inputFile)
def processOutputLine(self, line):
- print "[mpeg2encTask]", line
+ print "[mpeg2encTask]", line[:-1]
class spumuxTask(Task):
def __init__(self, job, xmlfile, inputfile, outputfile):
def run(self, callback, task_progress_changed):
Task.run(self, callback, task_progress_changed)
+ self.container.stdoutAvail.get().remove(self.processStdout)
self.container.dumpToFile(self.dumpFile)
self.container.readFromFile(self.inputFile)
def processStderr(self, data):
- print "[spumuxTask]", data
-
- def processStdout(self, data):
- pass
+ print "[spumuxTask]", data[:-1]
class MakeFifoNode(Task):
def __init__(self, job, number):
self.args += ["-s", sourcefile, link_name]
self.weighting = 10
+class CopyMeta(Task):
+ def __init__(self, job, sourcefile):
+ Task.__init__(self, job, "Copy title meta files")
+ self.setTool("/bin/cp")
+ from os import listdir
+ path, filename = sourcefile.rstrip("/").rsplit("/",1)
+ tsfiles = listdir(path)
+ for file in tsfiles:
+ if file.startswith(filename+"."):
+ self.args += [path+'/'+file]
+ self.args += [self.job.workspace]
+ self.weighting = 10
+
class DemuxTask(Task):
def __init__(self, job, inputfile):
Task.__init__(self, job, "Demux video into ES")
self.generated_files.append(file)
def haveProgress(self, progress):
- print "PROGRESS [%s]" % progress
+ #print "PROGRESS [%s]" % progress
MSG_CHECK = "check & synchronize audio file"
MSG_DONE = "done..."
if progress == "preparing collection(s)...":
for f in self.generated_files:
os.remove(f)
+class MplexTaskPostcondition(Condition):
+ def check(self, task):
+ if task.error == task.ERROR_UNDERRUN:
+ return True
+ return task.error is None
+
+ def getErrorMessage(self, task):
+ print "[MplexTaskPostcondition] getErrorMessage", task
+ return {
+ task.ERROR_UNDERRUN: ("Can't multiplex source video!"),
+ task.ERROR_UNKNOWN: ("An unknown error occured!")
+ }[task.error]
+
class MplexTask(Task):
+ ERROR_UNDERRUN, ERROR_UNKNOWN = range(2)
def __init__(self, job, outputfile, inputfiles=None, demux_task=None):
Task.__init__(self, job, "Mux ES into PS")
self.weighting = 500
self.demux_task = demux_task
+ self.postconditions.append(MplexTaskPostcondition())
self.setTool("/usr/bin/mplex")
self.args += ["-f8", "-o", outputfile, "-v1"]
if inputfiles:
self.args += inputfiles
+ def setTool(self, tool):
+ self.cmd = tool
+ self.args = [tool]
+ self.global_preconditions.append(ToolExistsPrecondition())
+ # we don't want the ReturncodePostcondition in this case because for right now we're just gonna ignore the fact that mplex fails with a buffer underrun error on some streams (this always at the very end)
+
def prepare(self):
+ self.error = None
if self.demux_task:
self.args += self.demux_task.generated_files
def processOutputLine(self, line):
- print "[MplexTask] processOutputLine=", line
+ print "[MplexTask] processOutputLine=", line[:-1]
+ if line.startswith("**ERROR:"):
+ if line.find("Frame data under-runs detected") != -1:
+ self.error = self.ERROR_UNDERRUN
+ else:
+ self.error = self.ERROR_UNKNOWN
class RemoveESFiles(Task):
def __init__(self, job, demux_task):
self.menupreview = job.menupreview
def processOutputLine(self, line):
- print "[DVDAuthorTask] processOutputLine=", line
+ print "[DVDAuthorTask] processOutputLine=", line[:-1]
if not self.menupreview and line.startswith("STAT: Processing"):
self.callback(self, [], stay_resident=True)
callback(self, [])
class BurnTaskPostcondition(Condition):
+ RECOVERABLE = True
def check(self, task):
return task.error is None
class BurnTask(Task):
ERROR_MEDIA, ERROR_SIZE, ERROR_WRITE_FAILED, ERROR_DVDROM, ERROR_ISOFS, ERROR_UNKNOWN = range(6)
- def __init__(self, job):
+ def __init__(self, job, extra_args=[]):
Task.__init__(self, job, "burn")
self.weighting = 500
self.postconditions.append(BurnTaskPostcondition())
self.setTool("/bin/growisofs")
volName = self.getASCIIname(job.project.settings.name.getValue())
- self.args += ["-dvd-video", "-dvd-compat", "-Z", "/dev/cdroms/cdrom0", "-V", volName, "-P", "Dreambox", "-use-the-force-luke=dummy", self.job.workspace + "/dvd"]
+ self.args += ["-dvd-compat", "-Z", "/dev/cdroms/cdrom0", "-V", volName, "-P", "Dreambox", "-use-the-force-luke=dummy", self.job.workspace + "/dvd"]
+ self.args += extra_args
def getASCIIname(self, name):
ASCIIname = ""
if self.job.menupreview:
self.waitAndOpenPlayer()
else:
- self.job.project.session.openWithCallback(self.previewCB, MessageBox, _("Do you want to preview this project before burning?"), timeout = 60, default = False)
+ self.job.project.session.openWithCallback(self.previewCB, MessageBox, _("Do you want to preview this DVD before burning?"), timeout = 60, default = False)
def previewCB(self, answer):
if answer == True:
if self.job.menupreview:
self.closedCB(True)
else:
- self.job.project.session.openWithCallback(self.closedCB, MessageBox, _("Do you want to burn this project to DVD medium?") )
+ self.job.project.session.openWithCallback(self.closedCB, MessageBox, _("Do you want to burn this collection to DVD medium?") )
def closedCB(self, answer):
if answer == True:
return titles_per_menu
def formatTitle(template, title, track):
- import re
template = template.replace("$i", str(track))
template = template.replace("$t", title.name)
template = template.replace("$d", title.descr)
template = template.replace("$c", str(len(title.chaptermarks)+1))
+ template = template.replace("$A", str(title.audiotracks))
template = template.replace("$f", title.inputfile)
+ template = template.replace("$C", title.channel)
l = title.length
lengthstring = "%d:%02d:%02d" % (l/3600, l%3600/60, l%60)
template = template.replace("$l", lengthstring)
- res = re.search("(?:/.*?).*/(?P<year>\d{4})(?P<month>\d{2})(?P<day>\d{2}).(?P<hour>\d{2})(?P<minute>\d{2}).-.*.?.ts", title.inputfile)
- if res:
- template = template.replace("$Y", res.group("year"))
- template = template.replace("$M", res.group("month"))
- template = template.replace("$D", res.group("day"))
- template = template.replace("$h", res.group("hour"))
- template = template.replace("$m", res.group("minute"))
+ if title.timeCreate:
+ template = template.replace("$Y", str(title.timeCreate[0]))
+ template = template.replace("$M", str(title.timeCreate[1]))
+ template = template.replace("$D", str(title.timeCreate[2]))
+ timestring = "%d:%02d" % (title.timeCreate[3], title.timeCreate[4])
+ template = template.replace("$T", timestring)
else:
- template = template.replace("$Y", "").replace("$M", "").replace("$D", "").replace("$h", "").replace("$m", "")
+ template = template.replace("$Y", "").replace("$M", "").replace("$D", "").replace("$T", "")
return template.decode("utf-8")
def CreateMenus(job):
authorxml.append(' </menus>\n')
authorxml.append(' <titles>\n')
for i in range( nr_titles ):
+ for audiotrack in job.project.titles[i].audiotracks:
+ authorxml.append(' <audio lang="'+audiotrack[0][:2]+'" format="'+audiotrack[1]+'" />\n')
chapters = ','.join(["%d:%02d:%02d.%03d" % (p / (90000 * 3600), p % (90000 * 3600) / (90000 * 60), p % (90000 * 60) / 90000, (p % 90000) / 90) for p in job.project.titles[i].chaptermarks])
title_no = i+1
title_filename = job.workspace + "/dvd_title_%d.mpg" % (title_no)
if titlesize > maxsize: maxsize = titlesize
totalsize += titlesize
diskSpaceNeeded = totalsize + maxsize
- print "diskSpaceNeeded:", diskSpaceNeeded
DVDAuthorTask(self, diskSpaceNeeded)
RemoveESFiles(self, demux)
WaitForResidentTasks(self)
PreviewTask(self)
- BurnTask(self)
+ BurnTask(self,["-dvd-video"])
+ RemoveDVDFolder(self)
+
+class DVDdataJob(Job):
+ def __init__(self, project):
+ Job.__init__(self, "Data DVD Burn")
+ self.project = project
+ from time import strftime
+ from Tools.Directories import SCOPE_HDD, resolveFilename, createDir
+ new_workspace = resolveFilename(SCOPE_HDD) + "tmp/" + strftime("%Y%m%d%H%M%S") + "/dvd/"
+ createDir(new_workspace, True)
+ self.workspace = new_workspace
+ self.project.workspace = self.workspace
+ self.conduct()
+
+ def conduct(self):
+ diskSpaceNeeded = 50*1024*1024 # require an extra safety 50 MB
+ for title in self.project.titles:
+ diskSpaceNeeded += title.filesize
+ nr_titles = len(self.project.titles)
+
+ for self.i in range(nr_titles):
+ title = self.project.titles[self.i]
+ filename = title.inputfile.rstrip("/").rsplit("/",1)[1]
+ link_name = self.workspace + filename
+ LinkTS(self, title.inputfile, link_name)
+ CopyMeta(self, title.inputfile)
+ BurnTask(self)
RemoveDVDFolder(self)
def Burn(session, project):
- print "burning cuesheet!"
j = DVDJob(project)
job_manager.AddJob(j)
return j
def PreviewMenu(session, project):
- print "preview DVD menu!"
j = DVDJob(project, menupreview=True)
job_manager.AddJob(j)
return j
+
+def BurnDataTS(session, project):
+ j = DVDdataJob(project)
+ job_manager.AddJob(j)
+ return j
\ No newline at end of file