from Components.Task import Task, Job, DiskspacePrecondition, Condition, ToolExistsPrecondition from Components.Harddisk import harddiskmanager from Screens.MessageBox import MessageBox class png2yuvTask(Task): def __init__(self, job, inputfile, outputfile): Task.__init__(self, job, "Creating menu video") self.setTool("/usr/bin/png2yuv") self.args += ["-n1", "-Ip", "-f25", "-j", inputfile] self.dumpFile = outputfile self.weighting = 15 def run(self, callback): Task.run(self, callback) self.container.stdoutAvail.remove(self.processStdout) self.container.dumpToFile(self.dumpFile) def processStderr(self, data): print "[png2yuvTask]", data[:-1] class mpeg2encTask(Task): def __init__(self, job, inputfile, outputfile): Task.__init__(self, job, "Encoding menu video") self.setTool("/usr/bin/mpeg2enc") self.args += ["-f8", "-np", "-a2", "-o", outputfile] self.inputFile = inputfile self.weighting = 25 def run(self, callback): Task.run(self, callback) self.container.readFromFile(self.inputFile) def processOutputLine(self, line): print "[mpeg2encTask]", line[:-1] class spumuxTask(Task): def __init__(self, job, xmlfile, inputfile, outputfile): Task.__init__(self, job, "Muxing buttons into menu") self.setTool("/usr/bin/spumux") self.args += [xmlfile] self.inputFile = inputfile self.dumpFile = outputfile self.weighting = 15 def run(self, callback): Task.run(self, callback) self.container.stdoutAvail.remove(self.processStdout) self.container.dumpToFile(self.dumpFile) self.container.readFromFile(self.inputFile) def processStderr(self, data): print "[spumuxTask]", data[:-1] class MakeFifoNode(Task): def __init__(self, job, number): Task.__init__(self, job, "Make FIFO nodes") self.setTool("/bin/mknod") nodename = self.job.workspace + "/dvd_title_%d" % number + ".mpg" self.args += [nodename, "p"] self.weighting = 10 class LinkTS(Task): def __init__(self, job, sourcefile, link_name): Task.__init__(self, job, "Creating symlink for source titles") self.setTool("/bin/ln") 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 = 15 class DemuxTask(Task): def __init__(self, job, inputfile): Task.__init__(self, job, "Demux video into ES") title = job.project.titles[job.i] self.global_preconditions.append(DiskspacePrecondition(title.estimatedDiskspace)) self.setTool("/usr/bin/projectx") self.args += [inputfile, "-demux", "-out", self.job.workspace ] self.end = 300 self.prog_state = 0 self.weighting = 1000 self.cutfile = self.job.workspace + "/cut_%d.Xcl" % (job.i+1) self.cutlist = title.cutlist self.currentPID = None self.relevantAudioPIDs = [ ] self.getRelevantAudioPIDs(title) self.generated_files = [ ] self.mplex_streamfiles = [ ] if len(self.cutlist) > 1: self.args += [ "-cut", self.cutfile ] def prepare(self): self.writeCutfile() def getRelevantAudioPIDs(self, title): for audiotrack in title.properties.audiotracks: if audiotrack.active.getValue(): self.relevantAudioPIDs.append(audiotrack.pid.getValue()) def processOutputLine(self, line): line = line[:-1] #print "[DemuxTask]", line MSG_NEW_FILE = "---> new File: " MSG_PROGRESS = "[PROGRESS] " MSG_NEW_MP2 = "++> Mpg Audio: PID 0x" MSG_NEW_AC3 = "++> AC3/DTS Audio: PID 0x" if line.startswith(MSG_NEW_FILE): file = line[len(MSG_NEW_FILE):] if file[0] == "'": file = file[1:-1] self.haveNewFile(file) elif line.startswith(MSG_PROGRESS): progress = line[len(MSG_PROGRESS):] self.haveProgress(progress) elif line.startswith(MSG_NEW_MP2) or line.startswith(MSG_NEW_AC3): try: self.currentPID = str(int(line.split(': PID 0x',1)[1].split(' ',1)[0],16)) except ValueError: print "[DemuxTask] ERROR: couldn't detect Audio PID (projectx too old?)" def haveNewFile(self, file): print "[DemuxTask] produced file:", file, self.currentPID self.generated_files.append(file) if self.currentPID in self.relevantAudioPIDs or file.endswith("m2v"): self.mplex_streamfiles.append(file) def haveProgress(self, progress): #print "PROGRESS [%s]" % progress MSG_CHECK = "check & synchronize audio file" MSG_DONE = "done..." if progress == "preparing collection(s)...": self.prog_state = 0 elif progress[:len(MSG_CHECK)] == MSG_CHECK: self.prog_state += 1 else: try: p = int(progress) p = p - 1 + self.prog_state * 100 if p > self.progress: self.progress = p except ValueError: pass def writeCutfile(self): f = open(self.cutfile, "w") f.write("CollectionPanel.CutMode=4\n") for p in self.cutlist: s = p / 90000 m = s / 60 h = m / 60 m %= 60 s %= 60 f.write("%02d:%02d:%02d\n" % (h, m, s)) f.close() def cleanup(self, failed): if failed: import os for file in self.generated_files: try: os.remove(file) except OSError: pass class MplexTaskPostcondition(Condition): def check(self, task): if task.error == task.ERROR_UNDERRUN: return True return task.error is None def getErrorMessage(self, 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, weighting = 500): Task.__init__(self, job, "Mux ES into PS") self.weighting = weighting 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.mplex_streamfiles def processOutputLine(self, line): print "[MplexTask] ", 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): Task.__init__(self, job, "Remove temp. files") self.demux_task = demux_task self.setTool("/bin/rm") self.weighting = 10 def prepare(self): self.args += ["-f"] self.args += self.demux_task.generated_files self.args += [self.demux_task.cutfile] class DVDAuthorTask(Task): def __init__(self, job): Task.__init__(self, job, "Authoring DVD") self.weighting = 20 self.setTool("/usr/bin/dvdauthor") self.CWD = self.job.workspace self.args += ["-x", self.job.workspace+"/dvdauthor.xml"] self.menupreview = job.menupreview def processOutputLine(self, line): print "[DVDAuthorTask] ", line[:-1] if not self.menupreview and line.startswith("STAT: Processing"): self.callback(self, [], stay_resident=True) elif line.startswith("STAT: VOBU"): try: progress = int(line.split("MB")[0].split(" ")[-1]) if progress: self.job.mplextask.progress = progress print "[DVDAuthorTask] update mplextask progress:", self.job.mplextask.progress, "of", self.job.mplextask.end except: print "couldn't set mux progress" class DVDAuthorFinalTask(Task): def __init__(self, job): Task.__init__(self, job, "dvdauthor finalize") self.setTool("/usr/bin/dvdauthor") self.args += ["-T", "-o", self.job.workspace + "/dvd"] class WaitForResidentTasks(Task): def __init__(self, job): Task.__init__(self, job, "waiting for dvdauthor to finalize") def run(self, callback): print "waiting for %d resident task(s) %s to finish..." % (len(self.job.resident_tasks),str(self.job.resident_tasks)) if self.job.resident_tasks == 0: callback(self, []) class BurnTaskPostcondition(Condition): RECOVERABLE = True def check(self, task): if task.returncode == 0: return True elif task.error is None or task.error is task.ERROR_MINUSRWBUG: return True return False def getErrorMessage(self, task): return { task.ERROR_NOTWRITEABLE: _("Medium is not a writeable DVD!"), task.ERROR_LOAD: _("Could not load Medium! No disc inserted?"), task.ERROR_SIZE: _("Content does not fit on DVD!"), task.ERROR_WRITE_FAILED: _("Write failed!"), task.ERROR_DVDROM: _("No (supported) DVDROM found!"), task.ERROR_ISOFS: _("Medium is not empty!"), task.ERROR_FILETOOLARGE: _("TS file is too large for ISO9660 level 1!"), task.ERROR_ISOTOOLARGE: _("ISO file is too large for this filesystem!"), task.ERROR_UNKNOWN: _("An unknown error occured!") }[task.error] class BurnTask(Task): ERROR_NOTWRITEABLE, ERROR_LOAD, ERROR_SIZE, ERROR_WRITE_FAILED, ERROR_DVDROM, ERROR_ISOFS, ERROR_FILETOOLARGE, ERROR_ISOTOOLARGE, ERROR_MINUSRWBUG, ERROR_UNKNOWN = range(10) def __init__(self, job, extra_args=[], tool="/bin/growisofs"): Task.__init__(self, job, job.name) self.weighting = 500 self.end = 120 # 100 for writing, 10 for buffer flush, 10 for closing disc self.postconditions.append(BurnTaskPostcondition()) self.setTool(tool) self.args += extra_args def prepare(self): self.error = None def processOutputLine(self, line): line = line[:-1] print "[GROWISOFS] %s" % line if line[8:14] == "done, ": self.progress = float(line[:6]) print "progress:", self.progress elif line.find("flushing cache") != -1: self.progress = 100 elif line.find("closing disc") != -1: self.progress = 110 elif line.startswith(":-["): if line.find("ASC=30h") != -1: self.error = self.ERROR_NOTWRITEABLE elif line.find("ASC=24h") != -1: self.error = self.ERROR_LOAD elif line.find("SK=5h/ASC=A8h/ACQ=04h") != -1: self.error = self.ERROR_MINUSRWBUG else: self.error = self.ERROR_UNKNOWN print "BurnTask: unknown error %s" % line elif line.startswith(":-("): if line.find("No space left on device") != -1: self.error = self.ERROR_SIZE elif self.error == self.ERROR_MINUSRWBUG: print "*sigh* this is a known bug. we're simply gonna assume everything is fine." self.postconditions = [] elif line.find("write failed") != -1: self.error = self.ERROR_WRITE_FAILED elif line.find("unable to open64(") != -1 and line.find(",O_RDONLY): No such file or directory") != -1: self.error = self.ERROR_DVDROM elif line.find("media is not recognized as recordable DVD") != -1: self.error = self.ERROR_NOTWRITEABLE else: self.error = self.ERROR_UNKNOWN print "BurnTask: unknown error %s" % line elif line.startswith("FATAL:"): if line.find("already carries isofs!"): self.error = self.ERROR_ISOFS else: self.error = self.ERROR_UNKNOWN print "BurnTask: unknown error %s" % line elif line.find("-allow-limited-size was not specified. There is no way do represent this file size. Aborting.") != -1: self.error = self.ERROR_FILETOOLARGE elif line.startswith("genisoimage: File too large."): self.error = self.ERROR_ISOTOOLARGE def setTool(self, tool): self.cmd = tool self.args = [tool] self.global_preconditions.append(ToolExistsPrecondition()) class RemoveDVDFolder(Task): def __init__(self, job): Task.__init__(self, job, "Remove temp. files") self.setTool("/bin/rm") self.args += ["-rf", self.job.workspace] self.weighting = 10 class CheckDiskspaceTask(Task): def __init__(self, job): Task.__init__(self, job, "Checking free space") totalsize = 0 # require an extra safety 50 MB maxsize = 0 for title in job.project.titles: titlesize = title.estimatedDiskspace if titlesize > maxsize: maxsize = titlesize totalsize += titlesize diskSpaceNeeded = totalsize + maxsize job.estimateddvdsize = totalsize / 1024 / 1024 totalsize += 50*1024*1024 # require an extra safety 50 MB self.global_preconditions.append(DiskspacePrecondition(diskSpaceNeeded)) self.weighting = 5 def abort(self): self.finish(aborted = True) def run(self, callback): self.callback = callback failed_preconditions = self.checkPreconditions(True) + self.checkPreconditions(False) if len(failed_preconditions): callback(self, failed_preconditions) return Task.processFinished(self, 0) class PreviewTask(Task): def __init__(self, job, path): Task.__init__(self, job, "Preview") self.postconditions.append(PreviewTaskPostcondition()) self.job = job self.path = path self.weighting = 10 def run(self, callback): self.callback = callback if self.job.menupreview: self.previewProject() else: import Screens.Standby if Screens.Standby.inStandby: self.previewCB(False) else: from Tools import Notifications Notifications.AddNotificationWithCallback(self.previewCB, MessageBox, _("Do you want to preview this DVD before burning?"), timeout = 60, default = False) def abort(self): self.finish(aborted = True) def previewCB(self, answer): if answer == True: self.previewProject() else: self.closedCB(True) def playerClosed(self): if self.job.menupreview: self.closedCB(True) else: from Tools import Notifications Notifications.AddNotificationWithCallback(self.closedCB, MessageBox, _("Do you want to burn this collection to DVD medium?") ) def closedCB(self, answer): if answer == True: Task.processFinished(self, 0) else: Task.processFinished(self, 1) def previewProject(self): from Plugins.Extensions.DVDPlayer.plugin import DVDPlayer self.job.project.session.openWithCallback(self.playerClosed, DVDPlayer, dvd_filelist= [ self.path ]) class PreviewTaskPostcondition(Condition): def check(self, task): return task.returncode == 0 def getErrorMessage(self, task): return "Cancel" class ImagingPostcondition(Condition): def check(self, task): return task.returncode == 0 def getErrorMessage(self, task): return _("Failed") + ": python-imaging" class ImagePrepareTask(Task): def __init__(self, job): Task.__init__(self, job, _("please wait, loading picture...")) self.postconditions.append(ImagingPostcondition()) self.weighting = 20 self.job = job self.Menus = job.Menus def run(self, callback): self.callback = callback # we are doing it this weird way so that the TaskView Screen actually pops up before the spinner comes from enigma import eTimer self.delayTimer = eTimer() self.delayTimer.callback.append(self.conduct) self.delayTimer.start(10,1) def conduct(self): try: from ImageFont import truetype from Image import open as Image_open s = self.job.project.menutemplate.settings (width, height) = s.dimensions.getValue() self.Menus.im_bg_orig = Image_open(s.menubg.getValue()) if self.Menus.im_bg_orig.size != (width, height): self.Menus.im_bg_orig = self.Menus.im_bg_orig.resize((width, height)) self.Menus.fontsizes = [s.fontsize_headline.getValue(), s.fontsize_title.getValue(), s.fontsize_subtitle.getValue()] self.Menus.fonts = [(truetype(s.fontface_headline.getValue(), self.Menus.fontsizes[0])), (truetype(s.fontface_title.getValue(), self.Menus.fontsizes[1])),(truetype(s.fontface_subtitle.getValue(), self.Menus.fontsizes[2]))] Task.processFinished(self, 0) except: Task.processFinished(self, 1) class MenuImageTask(Task): def __init__(self, job, menu_count, spuxmlfilename, menubgpngfilename, highlightpngfilename): Task.__init__(self, job, "Create Menu %d Image" % menu_count) self.postconditions.append(ImagingPostcondition()) self.weighting = 10 self.job = job self.Menus = job.Menus self.menu_count = menu_count self.spuxmlfilename = spuxmlfilename self.menubgpngfilename = menubgpngfilename self.highlightpngfilename = highlightpngfilename def run(self, callback): self.callback = callback #try: import ImageDraw, Image, os s = self.job.project.menutemplate.settings s_top = s.margin_top.getValue() s_bottom = s.margin_bottom.getValue() s_left = s.margin_left.getValue() s_right = s.margin_right.getValue() s_rows = s.space_rows.getValue() s_cols = s.space_cols.getValue() nr_cols = s.cols.getValue() nr_rows = s.rows.getValue() thumb_size = s.thumb_size.getValue() if thumb_size[0]: from Image import open as Image_open (s_width, s_height) = s.dimensions.getValue() fonts = self.Menus.fonts im_bg = self.Menus.im_bg_orig.copy() im_high = Image.new("P", (s_width, s_height), 0) im_high.putpalette(self.Menus.spu_palette) draw_bg = ImageDraw.Draw(im_bg) draw_high = ImageDraw.Draw(im_high) if self.menu_count == 1: headlineText = self.job.project.settings.name.getValue().decode("utf-8") headlinePos = self.getPosition(s.offset_headline.getValue(), 0, 0, s_width, s_top, draw_bg.textsize(headlineText, font=fonts[0])) draw_bg.text(headlinePos, headlineText, fill=self.Menus.color_headline, font=fonts[0]) spuxml = """ """ % (self.highlightpngfilename, self.Menus.spu_palette[0], self.Menus.spu_palette[1], self.Menus.spu_palette[2]) #rowheight = (self.Menus.fontsizes[1]+self.Menus.fontsizes[2]+thumb_size[1]+s_rows) menu_start_title = (self.menu_count-1)*self.job.titles_per_menu + 1 menu_end_title = (self.menu_count)*self.job.titles_per_menu + 1 nr_titles = len(self.job.project.titles) if menu_end_title > nr_titles: menu_end_title = nr_titles+1 col = 1 row = 1 for title_no in range( menu_start_title , menu_end_title ): title = self.job.project.titles[title_no-1] col_width = ( s_width - s_left - s_right ) / nr_cols row_height = ( s_height - s_top - s_bottom ) / nr_rows left = s_left + ( (col-1) * col_width ) + s_cols/2 right = left + col_width - s_cols top = s_top + ( (row-1) * row_height) + s_rows/2 bottom = top + row_height - s_rows width = right - left height = bottom - top if bottom > s_height: bottom = s_height #draw_bg.rectangle((left, top, right, bottom), outline=(255,0,0)) im_cell_bg = Image.new("RGBA", (width, height),(0,0,0,0)) draw_cell_bg = ImageDraw.Draw(im_cell_bg) im_cell_high = Image.new("P", (width, height), 0) im_cell_high.putpalette(self.Menus.spu_palette) draw_cell_high = ImageDraw.Draw(im_cell_high) if thumb_size[0]: thumbPos = self.getPosition(s.offset_thumb.getValue(), 0, 0, width, height, thumb_size) box = (thumbPos[0], thumbPos[1], thumbPos[0]+thumb_size[0], thumbPos[1]+thumb_size[1]) try: thumbIm = Image_open(title.inputfile.rsplit('.',1)[0] + ".png") im_cell_bg.paste(thumbIm,thumbPos) except: draw_cell_bg.rectangle(box, fill=(64,127,127,127)) border = s.thumb_border.getValue() if border: draw_cell_high.rectangle(box, fill=1) draw_cell_high.rectangle((box[0]+border, box[1]+border, box[2]-border, box[3]-border), fill=0) titleText = title.formatDVDmenuText(s.titleformat.getValue(), title_no).decode("utf-8") titlePos = self.getPosition(s.offset_title.getValue(), 0, 0, width, height, draw_bg.textsize(titleText, font=fonts[1])) draw_cell_bg.text(titlePos, titleText, fill=self.Menus.color_button, font=fonts[1]) draw_cell_high.text(titlePos, titleText, fill=1, font=self.Menus.fonts[1]) subtitleText = title.formatDVDmenuText(s.subtitleformat.getValue(), title_no).decode("utf-8") subtitlePos = self.getPosition(s.offset_subtitle.getValue(), 0, 0, width, height, draw_cell_bg.textsize(subtitleText, font=fonts[2])) draw_cell_bg.text(subtitlePos, subtitleText, fill=self.Menus.color_button, font=fonts[2]) del draw_cell_bg del draw_cell_high im_bg.paste(im_cell_bg,(left, top, right, bottom), mask=im_cell_bg) im_high.paste(im_cell_high,(left, top, right, bottom)) spuxml += """ \n') if menu_count > 1: authorxml.append(' \n') if menu_count < job.nr_menus: authorxml.append(' \n') menuoutputfilename = job.workspace+"/dvdmenu"+str(menu_count)+".mpg" authorxml.append(' \n') authorxml.append(' \n') authorxml.append(' \n') authorxml.append(' \n') for i in range( nr_titles ): chapters = ','.join(job.project.titles[i].getChapterMarks()) title_no = i+1 title_filename = job.workspace + "/dvd_title_%d.mpg" % (title_no) if job.menupreview: LinkTS(job, job.project.settings.vmgm.getValue(), title_filename) else: MakeFifoNode(job, title_no) if mode.endswith("linked") and title_no < nr_titles: post_tag = "jump title %d;" % ( title_no+1 ) elif mode.startswith("menu"): post_tag = "call vmgm menu 1;" else: post_tag = "" authorxml.append(' \n') authorxml.append(' \n') authorxml.append(' ' + post_tag + ' \n') authorxml.append(' \n') authorxml.append(' \n') authorxml.append(' \n') authorxml.append(' \n') f = open(job.workspace+"/dvdauthor.xml", "w") for x in authorxml: f.write(x) f.close() def CreateAuthoringXML_multiset(job): nr_titles = len(job.project.titles) mode = job.project.settings.authormode.getValue() authorxml = [] authorxml.append('\n') authorxml.append(' \n') authorxml.append(' \n') authorxml.append(' \n') authorxml.append(' \n') authorxml.append(' \n') for i in range( nr_titles ): title = job.project.titles[i] authorxml.append(' \n') authorxml.append(' \n') authorxml.append(' \n') authorxml.append('
\n')
		authorxml.append('      jump vmgm menu entry title;\n')
		authorxml.append('     
\n') authorxml.append('
\n') authorxml.append('
\n') authorxml.append(' \n') for audiotrack in title.properties.audiotracks: active = audiotrack.active.getValue() if active: format = audiotrack.format.getValue() language = audiotrack.language.getValue() audio_tag = ' \n') authorxml.append('
\n') authorxml.append('
\n') f = open(job.workspace+"/dvdauthor.xml", "w") for x in authorxml: f.write(x) f.close() def getISOfilename(isopath, volName): from Tools.Directories import fileExists i = 0 filename = isopath+'/'+volName+".iso" while fileExists(filename): i = i+1 filename = isopath+'/'+volName + str(i).zfill(3) + ".iso" return filename class DVDJob(Job): def __init__(self, project, menupreview=False): Job.__init__(self, "DVDBurn Job") 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") createDir(new_workspace, True) self.workspace = new_workspace self.project.workspace = self.workspace self.menupreview = menupreview self.conduct() def conduct(self): CheckDiskspaceTask(self) if self.project.settings.authormode.getValue().startswith("menu") or self.menupreview: Menus(self) if self.project.settings.titlesetmode.getValue() == "multi": CreateAuthoringXML_multiset(self) else: CreateAuthoringXML_singleset(self) DVDAuthorTask(self) nr_titles = len(self.project.titles) if self.menupreview: PreviewTask(self, self.workspace + "/dvd/VIDEO_TS/") else: for self.i in range(nr_titles): self.title = self.project.titles[self.i] link_name = self.workspace + "/source_title_%d.ts" % (self.i+1) title_filename = self.workspace + "/dvd_title_%d.mpg" % (self.i+1) LinkTS(self, self.title.inputfile, link_name) demux = DemuxTask(self, link_name) self.mplextask = MplexTask(self, outputfile=title_filename, demux_task=demux) self.mplextask.end = self.estimateddvdsize RemoveESFiles(self, demux) WaitForResidentTasks(self) PreviewTask(self, self.workspace + "/dvd/VIDEO_TS/") output = self.project.settings.output.getValue() volName = self.project.settings.name.getValue() if output == "dvd": self.name = _("Burn DVD") tool = "/bin/growisofs" burnargs = [ "-Z", "/dev/" + harddiskmanager.getCD(), "-dvd-compat" ] if self.project.size/(1024*1024) > self.project.MAX_SL: burnargs += [ "-use-the-force-luke=4gms", "-speed=1", "-R" ] elif output == "iso": self.name = _("Create DVD-ISO") tool = "/usr/bin/mkisofs" isopathfile = getISOfilename(self.project.settings.isopath.getValue(), volName) burnargs = [ "-o", isopathfile ] burnargs += [ "-dvd-video", "-publisher", "Dreambox", "-V", volName, self.workspace + "/dvd" ] BurnTask(self, burnargs, tool) 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): if self.project.settings.output.getValue() == "iso": CheckDiskspaceTask(self) 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) output = self.project.settings.output.getValue() volName = self.project.settings.name.getValue() tool = "/bin/growisofs" if output == "dvd": self.name = _("Burn DVD") burnargs = [ "-Z", "/dev/" + harddiskmanager.getCD(), "-dvd-compat" ] if self.project.size/(1024*1024) > self.project.MAX_SL: burnargs += [ "-use-the-force-luke=4gms", "-speed=1", "-R" ] elif output == "iso": tool = "/usr/bin/mkisofs" self.name = _("Create DVD-ISO") isopathfile = getISOfilename(self.project.settings.isopath.getValue(), volName) burnargs = [ "-o", isopathfile ] if self.project.settings.dataformat.getValue() == "iso9660_1": burnargs += ["-iso-level", "1" ] elif self.project.settings.dataformat.getValue() == "iso9660_4": burnargs += ["-iso-level", "4", "-allow-limited-size" ] elif self.project.settings.dataformat.getValue() == "udf": burnargs += ["-udf", "-allow-limited-size" ] burnargs += [ "-publisher", "Dreambox", "-V", volName, "-follow-links", self.workspace ] BurnTask(self, burnargs, tool) RemoveDVDFolder(self) class DVDisoJob(Job): def __init__(self, project, imagepath): Job.__init__(self, _("Burn DVD")) self.project = project self.menupreview = False from Tools.Directories import getSize if imagepath.endswith(".iso"): PreviewTask(self, imagepath) burnargs = [ "-Z", "/dev/" + harddiskmanager.getCD() + '='+imagepath, "-dvd-compat" ] if getSize(imagepath)/(1024*1024) > self.project.MAX_SL: burnargs += [ "-use-the-force-luke=4gms", "-speed=1", "-R" ] else: PreviewTask(self, imagepath + "/VIDEO_TS/") volName = self.project.settings.name.getValue() burnargs = [ "-Z", "/dev/" + harddiskmanager.getCD(), "-dvd-compat" ] if getSize(imagepath)/(1024*1024) > self.project.MAX_SL: burnargs += [ "-use-the-force-luke=4gms", "-speed=1", "-R" ] burnargs += [ "-dvd-video", "-publisher", "Dreambox", "-V", volName, imagepath ] tool = "/bin/growisofs" BurnTask(self, burnargs, tool)