线程中的线程

时间:2014-05-28 14:09:40

标签: python multithreading image ffmpeg popen

我的公司正致力于视觉效果,我们通过浏览器为我们的客户设置内部镜头回放。为此,我们需要将视频文件上传到FTP服务器。

我想将图片序列转换为mp4,并在渲染完成后直接上传此文件。

为此,我使用:

  • 一个转换命令提示符
  • 获取`md5hash
  • 的一个命令提示符
  • 一个用于上传文件

我已经在我的本地计算机上实现了这一点,我只是链接os.system('command')

在识别出程序因较长的图像序列冻结很长时间后,我改变了脚本以使用os.system链产生一个线程。 但是在Render Farm Server上,这个脚本实际上并不起作用。

RenderFarm服务器运行Python 2.5

有一些代码示例:

class CopraUpload(threading.Thread):

    # initializing Thread
    # via super constructor
    def __init__(self):
        threading.Thread.__init__(self)


    # return the size of the
    # created mp4 file
    #
    # @return: the file size in byte
    def _getFileSize(self):


    # creates a random id for organising
    # the server upload used as flag
    #
    # @return: a hash
    def _getHash(self):
            self.fileLoc = str(self.outputfileName + '.mp4')
            self.fileLoc = os.path.normpath(self.fileLoc)
            return str(os.path.getsize(self.fileLoc))

    # integrates the "missing" data for the xml file
    # generated post render from the mp4 file
    def _setPreviewDataToXML(self):
        self.xmlFile = str(self.outputfileName + '_copraUpload.xml')
        self.xmlFile = os.path.normpath(self.xmlFile)

        ett = ET.parse(self.xmlFile)
        root = ett.getroot()
        for child in root.getiterator('preview_size'):
            child.text = self._getFileSize()
        for child in root.getiterator('preview_md5hash'):
            child.text = self._getHash()
        ett.write(self.xmlFile)


    # create a connection to a ftp server
    # and copies the mp4 file and the xml file
    # on the server
    def _uploadToCopra(self):

        os.system(self.uploadCommand)
        #process = Popen(self.uploadCommand)


    # the main function of the program
    # called via start from a Thread Object
    def run(self):

        # the command which will be send to the commando shell
        # for further adjustments see ffmpeg help with ffmpeg.exe -h
        FinalCommand = self.ffmpegLocation + " -r "+ self.framerate + " -i " + self.inputPath + " -an -strict experimental -s hd720 -vcodec libx264 -preset slow -profile:v baseline -level 31 -refs 1 -maxrate 6M -bufsize 10M -vb 6M -threads 0 -g 8 -r " + self.framerate + " " + self.outputfileName + ".mp4 -y"
        FinalCommandList = FinalCommand.split(" ")


        # calling the program
        print "Start ffmpeg convertion"

        outInfo = os.path.normpath("C:\\Users\\sarender\\Desktop\\stdoutFFMPEG.txt")
        outError = os.path.normpath("C:\\Users\\sarender\\Desktop\\stderrFFMPEG.txt")
        stdoutFile = open(outInfo,"w")
        stderrFile = open(outError,"w")

        handle = subp.check_all(FinalCommandList,stdout = stdoutFile,stderr = stderrFile)
        handle.communicate()
        stdoutFile.close()
        stderrFile.close()
        print "Convertion from ffmpeg done"

        # fill the xml file with the missing data
        # - preview file size
        # - preview md5hash
        self._setPreviewDataToXML()
        self._uploadToCopra()
        print "---------------------------------->FINISHED------------------------------------------------------>"


    # Creates a callable Thread for the Copra Upload.
    # start is calling the run method which will start the Uploading

和主要开始:

    if "$(RenderSet.writenode)" == "PREVIEW":
        print "---------------------------------->Initializing Script------------------------------------------------------>"
        process = CopraUpload()
        process.start()

会发生什么:

脚本在渲染后开始,ffmpeg转换图像序列并创建mp4。但在那之后就停止了。它不会打印"Conversion from ffmpeg complet"。只需停止剧本。

它实际上应该用ffmpeg创建线程转换并等到它完成。它应该在xml文件中写入一些东西并将它们上传到服务器。

我错过了什么吗?一个帖子中的subprocess是不是要走的路?但我需要一个Thread,因为我无法使渲染管理服务器死锁。

1 个答案:

答案 0 :(得分:0)

我的猜测是命令失败并在handle.communicate()中引发异常。确保捕获所有异常并将其记录在某处,因为线程无法传递异常。

此外,你不应该使用FinalCommand.split(" ") - 如果文件名包含空格,这将以奇怪(和不可预测)的方式失败。创建一个列表,而不是将该列表传递给subp

FinalCommand = [
    self.ffmpegLocation,
    "-r", self.framerate,
    "-i", self.inputPath,
    "-an",
    "-strict experimental",
    ...
]

更具可读性。