fix order and correct association of languages and audio stream files and set a limit...
[vuplus_dvbapp] / lib / python / Plugins / Extensions / DVDBurn / Process.py
index d0c9d3c..e00dedd 100644 (file)
@@ -5,7 +5,7 @@ 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.setTool("png2yuv")
                self.args += ["-n1", "-Ip", "-f25", "-j", inputfile]
                self.dumpFile = outputfile
                self.weighting = 15
@@ -21,7 +21,7 @@ class png2yuvTask(Task):
 class mpeg2encTask(Task):
        def __init__(self, job, inputfile, outputfile):
                Task.__init__(self, job, "Encoding menu video")
-               self.setTool("/usr/bin/mpeg2enc")
+               self.setTool("mpeg2enc")
                self.args += ["-f8", "-np", "-a2", "-o", outputfile]
                self.inputFile = inputfile
                self.weighting = 25
@@ -36,7 +36,7 @@ class mpeg2encTask(Task):
 class spumuxTask(Task):
        def __init__(self, job, xmlfile, inputfile, outputfile):
                Task.__init__(self, job, "Muxing buttons into menu")
-               self.setTool("/usr/bin/spumux")
+               self.setTool("spumux")
                self.args += [xmlfile]
                self.inputFile = inputfile
                self.dumpFile = outputfile
@@ -54,7 +54,7 @@ class spumuxTask(Task):
 class MakeFifoNode(Task):
        def __init__(self, job, number):
                Task.__init__(self, job, "Make FIFO nodes")
-               self.setTool("/bin/mknod")
+               self.setTool("mknod")
                nodename = self.job.workspace + "/dvd_title_%d" % number + ".mpg"
                self.args += [nodename, "p"]
                self.weighting = 10
@@ -62,14 +62,14 @@ class MakeFifoNode(Task):
 class LinkTS(Task):
        def __init__(self, job, sourcefile, link_name):
                Task.__init__(self, job, "Creating symlink for source titles")
-               self.setTool("/bin/ln")
+               self.setTool("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")
+               self.setTool("cp")
                from os import listdir
                path, filename = sourcefile.rstrip("/").rsplit("/",1)
                tsfiles = listdir(path)
@@ -84,7 +84,7 @@ class DemuxTask(Task):
                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.setTool("projectx")
                self.args += [inputfile, "-demux", "-out", self.job.workspace ]
                self.end = 300
                self.prog_state = 0
@@ -95,6 +95,8 @@ class DemuxTask(Task):
                self.relevantAudioPIDs = [ ]
                self.getRelevantAudioPIDs(title)
                self.generated_files = [ ]
+               self.mplex_audiofiles = { }
+               self.mplex_videofile = ""
                self.mplex_streamfiles = [ ]
                if len(self.cutlist) > 1:
                        self.args += [ "-cut", self.cutfile ]
@@ -109,10 +111,11 @@ class DemuxTask(Task):
 
        def processOutputLine(self, line):
                line = line[:-1]
+               #print "[DemuxTask]", line
                MSG_NEW_FILE = "---> new File: "
                MSG_PROGRESS = "[PROGRESS] "
-               MSG_NEW_MP2 = "--> MPEG Audio (0x"
-               MSG_NEW_AC3 = "--> AC-3/DTS Audio on PID "
+               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):]
@@ -123,13 +126,18 @@ class DemuxTask(Task):
                        progress = line[len(MSG_PROGRESS):]
                        self.haveProgress(progress)
                elif line.startswith(MSG_NEW_MP2) or line.startswith(MSG_NEW_AC3):
-                       self.currentPID = str(int(line.rstrip()[-6:].rsplit('0x',1)[-1],16))
+                       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)
+               if self.currentPID in self.relevantAudioPIDs:
+                       self.mplex_audiofiles[self.currentPID] = file
+               elif file.endswith("m2v"):
+                       self.mplex_videofile = file
 
        def haveProgress(self, progress):
                #print "PROGRESS [%s]" % progress
@@ -163,10 +171,19 @@ class DemuxTask(Task):
                f.close()
 
        def cleanup(self, failed):
+               print "[DemuxTask::cleanup]"
+               self.mplex_streamfiles = [ self.mplex_videofile ]
+               for pid in self.relevantAudioPIDs:
+                       self.mplex_streamfiles.append(self.mplex_audiofiles[pid])
+               print self.mplex_streamfiles
+
                if failed:
                        import os
                        for file in self.generated_files:
-                               os.remove(file)
+                               try:
+                                       os.remove(file)
+                               except OSError:
+                                       pass
 
 class MplexTaskPostcondition(Condition):
        def check(self, task):
@@ -187,7 +204,7 @@ class MplexTask(Task):
                self.weighting = weighting
                self.demux_task = demux_task
                self.postconditions.append(MplexTaskPostcondition())
-               self.setTool("/usr/bin/mplex")
+               self.setTool("mplex")
                self.args += ["-f8", "-o", outputfile, "-v1"]
                if inputfiles:
                        self.args += inputfiles
@@ -215,7 +232,7 @@ 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.setTool("rm")
                self.weighting = 10
 
        def prepare(self):
@@ -227,7 +244,7 @@ class DVDAuthorTask(Task):
        def __init__(self, job):
                Task.__init__(self, job, "Authoring DVD")
                self.weighting = 20
-               self.setTool("/usr/bin/dvdauthor")
+               self.setTool("dvdauthor")
                self.CWD = self.job.workspace
                self.args += ["-x", self.job.workspace+"/dvdauthor.xml"]
                self.menupreview = job.menupreview
@@ -248,7 +265,7 @@ class DVDAuthorTask(Task):
 class DVDAuthorFinalTask(Task):
        def __init__(self, job):
                Task.__init__(self, job, "dvdauthor finalize")
-               self.setTool("/usr/bin/dvdauthor")
+               self.setTool("dvdauthor")
                self.args += ["-T", "-o", self.job.workspace + "/dvd"]
 
 class WaitForResidentTasks(Task):
@@ -257,6 +274,7 @@ class WaitForResidentTasks(Task):
                
        def run(self, callback):
                print "waiting for %d resident task(s) %s to finish..." % (len(self.job.resident_tasks),str(self.job.resident_tasks))
+               self.callback = callback
                if self.job.resident_tasks == 0:
                        callback(self, [])
 
@@ -284,7 +302,7 @@ class BurnTaskPostcondition(Condition):
 
 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"):
+       def __init__(self, job, extra_args=[], tool="growisofs"):
                Task.__init__(self, job, job.name)
                self.weighting = 500
                self.end = 120 # 100 for writing, 10 for buffer flush, 10 for closing disc
@@ -308,9 +326,9 @@ class BurnTask(Task):
                elif line.startswith(":-["):
                        if line.find("ASC=30h") != -1:
                                self.error = self.ERROR_NOTWRITEABLE
-                       if line.find("ASC=24h") != -1:
+                       elif line.find("ASC=24h") != -1:
                                self.error = self.ERROR_LOAD
-                       if line.find("SK=5h/ASC=A8h/ACQ=04h") != -1:
+                       elif line.find("SK=5h/ASC=A8h/ACQ=04h") != -1:
                                self.error = self.ERROR_MINUSRWBUG
                        else:
                                self.error = self.ERROR_UNKNOWN
@@ -349,7 +367,7 @@ class BurnTask(Task):
 class RemoveDVDFolder(Task):
        def __init__(self, job):
                Task.__init__(self, job, "Remove temp. files")
-               self.setTool("/bin/rm")
+               self.setTool("rm")
                self.args += ["-rf", self.job.workspace]
                self.weighting = 10
 
@@ -372,11 +390,11 @@ class CheckDiskspaceTask(Task):
                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
-               self.callback = callback
                Task.processFinished(self, 0)
 
 class PreviewTask(Task):
@@ -392,8 +410,12 @@ class PreviewTask(Task):
                if self.job.menupreview:
                        self.previewProject()
                else:
-                       from Tools import Notifications
-                       Notifications.AddNotificationWithCallback(self.previewCB, MessageBox, _("Do you want to preview this DVD before burning?"), timeout = 60, default = False)
+                       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)
@@ -668,7 +690,7 @@ def CreateAuthoringXML_singleset(job):
        authorxml.append('<?xml version="1.0" encoding="utf-8"?>\n')
        authorxml.append(' <dvdauthor dest="' + (job.workspace+"/dvd") + '">\n')
        authorxml.append('  <vmgm>\n')
-       authorxml.append('   <menus>\n')
+       authorxml.append('   <menus lang="' + job.project.menutemplate.settings.menulang.getValue() + '">\n')
        authorxml.append('    <pgc>\n')
        authorxml.append('     <vob file="' + job.project.settings.vmgm.getValue() + '" />\n', )
        if mode.startswith("menu"):
@@ -680,7 +702,7 @@ def CreateAuthoringXML_singleset(job):
        authorxml.append('  </vmgm>\n')
        authorxml.append('  <titleset>\n')
        if mode.startswith("menu"):
-               authorxml.append('   <menus>\n')
+               authorxml.append('   <menus lang="' + job.project.menutemplate.settings.menulang.getValue() + '">\n')
                authorxml.append('    <video aspect="4:3"/>\n')
                for menu_count in range(1 , job.nr_menus+1):
                        if menu_count == 1:
@@ -736,11 +758,14 @@ def CreateAuthoringXML_multiset(job):
        authorxml.append('<?xml version="1.0" encoding="utf-8"?>\n')
        authorxml.append(' <dvdauthor dest="' + (job.workspace+"/dvd") + '" jumppad="yes">\n')
        authorxml.append('  <vmgm>\n')
-       authorxml.append('   <menus>\n')
+       authorxml.append('   <menus lang="' + job.project.menutemplate.settings.menulang.getValue() + '">\n')
        authorxml.append('    <video aspect="4:3"/>\n')
        if mode.startswith("menu"):
                for menu_count in range(1 , job.nr_menus+1):
-                       authorxml.append('    <pgc>\n')
+                       if menu_count == 1:
+                               authorxml.append('    <pgc>\n')
+                       else:
+                               authorxml.append('    <pgc>\n')
                        menu_start_title = (menu_count-1)*job.titles_per_menu + 1
                        menu_end_title = (menu_count)*job.titles_per_menu + 1
                        if menu_end_title > nr_titles:
@@ -765,6 +790,13 @@ def CreateAuthoringXML_multiset(job):
        for i in range( nr_titles ):
                title = job.project.titles[i]
                authorxml.append('  <titleset>\n')
+               authorxml.append('   <menus lang="' + job.project.menutemplate.settings.menulang.getValue() + '">\n')
+               authorxml.append('    <pgc entry="root">\n')
+               authorxml.append('     <pre>\n')
+               authorxml.append('      jump vmgm menu entry title;\n')
+               authorxml.append('     </pre>\n')
+               authorxml.append('    </pgc>\n')
+               authorxml.append('   </menus>\n')
                authorxml.append('   <titles>\n')
                for audiotrack in title.properties.audiotracks:
                        active = audiotrack.active.getValue()
@@ -860,11 +892,13 @@ class DVDJob(Job):
                        volName = self.project.settings.name.getValue()
                        if output == "dvd":
                                self.name = _("Burn DVD")
-                               tool = "/bin/growisofs"
+                               tool = "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"
+                               tool = "genisoimage"
                                isopathfile = getISOfilename(self.project.settings.isopath.getValue(), volName)
                                burnargs = [ "-o", isopathfile ]
                        burnargs += [ "-dvd-video", "-publisher", "Dreambox", "-V", volName, self.workspace + "/dvd" ]
@@ -896,12 +930,14 @@ class DVDdataJob(Job):
 
                output = self.project.settings.output.getValue()
                volName = self.project.settings.name.getValue()
-               tool = "/bin/growisofs"
+               tool = "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"
+                       tool = "genisoimage"
                        self.name = _("Create DVD-ISO")
                        isopathfile = getISOfilename(self.project.settings.isopath.getValue(), volName)
                        burnargs = [ "-o", isopathfile ]
@@ -920,13 +956,18 @@ class DVDisoJob(Job):
                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"
+               tool = "growisofs"
                BurnTask(self, burnargs, tool)