""" Playblast Module for creating quick renders from motion builder Example: from RS.Utils import Playblast Playblast.PlaybastRender(r"X:\playblast.mov", 20, 100, 500,500, showtimeCode=True) """ import os import tempfile import uuid import shutil from PIL import Image from PySide import QtGui import pyfbsdk as mobu from RS.Core.Video import videoManager def PlaybastRender( filePath, frameStart, frameEnd, imageHeight, imageWidth, showtimeCode=False, camera=None, includeAudio=False, compression=None, codec=None ): """ Create a Playblast movie for a given range Args: filePath (str): The final output location frameStart (int): The start Frame frameEnd (int): The end frame imageHeight (int): The height of the output imageWidth (int): The width of the output Kwargs: showtimeCode (bool): If the timecode/frame number is to be present on the render camera (FBCamera): The camera to render from includeAudio (booL): if the clip should contain the audio compression (list of strings): Compression strings to be applied to the FFMEPG file codec (str): The video codec to use when encoding the video """ progressBar = mobu.FBProgress() imageFileName = "playblast" imageFilePadding = 6 player = mobu.FBPlayerControl() initalTimeStart = player.LoopStart initalTimeEnd = player.LoopStop workingFolder = os.path.join(tempfile.gettempdir(), "mobuThumbailPlaybast", str(uuid.uuid1())) os.makedirs(workingFolder) frames = [] player.LoopStart = mobu.FBTime(0, 0, 0, frameStart) player.LoopStop = mobu.FBTime(0, 0, 0, frameEnd) progressBar.ProgressBegin() for frameNumber in xrange(frameStart, frameEnd + 1): progressBar.Text = "Playblasting frame: {0}".format(frameNumber) outputPath = os.path.join(workingFolder, "{0}_{1}.png".format(imageFileName, str(frameNumber).zfill(imageFilePadding))) PlaybastFrame(outputPath, frameNumber, imageHeight, imageWidth, showtimeCode=showtimeCode, camera=camera) frames.append(outputPath) if (progressBar.UserRequestCancell()): return progressBar.Percent = int((frameNumber - frameStart) / float(frameEnd - frameStart) * 100) audioFilePath = os.path.join(workingFolder, "{0}.wav".format(imageFileName)) if includeAudio: audioOptions = mobu.FBAudioRenderOptions() audioOptions.OutputFileName = audioFilePath mobu.FBApplication().AudioRender(audioOptions) player.LoopStart = initalTimeStart player.LoopStop = initalTimeEnd progressBar.ProgressDone() imgPath = os.path.join(workingFolder, "{0}_%0{1}d.png".format(imageFileName, imageFilePadding)) videoFilePath = os.path.join(workingFolder, "{0}.mov".format(imageFileName)) videoManager.VideoManager.createVideoFromImageSequence(imgPath, videoFilePath, startNumber=frameStart) if includeAudio and os.path.isfile(audioFilePath): videoManager.VideoManager.mergeVideoAndAudio(videoFilePath, audioFilePath, filePath, videoCodec=codec, compression=compression) else: videoManager.VideoManager.compressVideo(videoFilePath, filePath, videoCodec=codec, compression=compression) shutil.rmtree(workingFolder) def PlaybastFrame( filePath, frameNumber, imageHeight, imageWidth, showtimeCode=False, camera=None, ): """ Create a Playblast movie for a given range Args: filePath (str): The final output location frameNumber (int): The Frame to render imageHeight (int): The height of the output imageWidth (int): The width of the output Kwargs: showtimeCode (bool): If the timecode/frame number is to be present on the render camera (FBCamera): The camera to render from """ camera = camera or mobu.FBSystem().Scene.Renderer.CurrentCamera mobu.FBSystem().Scene.Renderer.CurrentCamera = camera imageSize = (imageHeight, imageWidth) workingFolder = os.path.join(tempfile.gettempdir(), "mobuThumbailPlaybast", str(uuid.uuid1())) os.makedirs(workingFolder) player = mobu.FBPlayerControl() player.Goto(mobu.FBTime(0, 0, 0, frameNumber)) # Render Image blaster = mobu.FBVideoGrabber().RenderSnapshot( imageSize[0], imageSize[1], False, showtimeCode, False, True, True, False, False ) rawRender = os.path.join(workingFolder, "rawRender.tif") blaster.ConvertFormat(mobu.FBImageFormat.kFBImageFormatRGB24) blaster.WriteToTif(rawRender, "", False) # Join them compImage = os.path.join(workingFolder, "render.png") render = Image.open(rawRender) render.save(filePath) # Close the file del render shutil.rmtree(workingFolder)