123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- from __future__ import with_statement
- from __future__ import print_function
- from __future__ import division
- import os, sys
- import subprocess, shlex
- import argparse
- import tempfile
- import numpy as np
- import nuke
- import tifffile
-
-
- class ffmpeg_render(KellerNukePlugin):
-
- def configurePlugin(self):
- workgroup = os.getenv('NUKE_PATH')
- nk = os.path.join(workgroup, "pythonpluginsUI/nukeffmpeg", "Preview_QT.nk")
- nk = nk.replace('\\','/')
- nk = "\"" + nk + "\""
- menubar = nuke.menu("Nuke")
- self.m = menubar.addMenu("&Render")
- self.m.addCommand('FFmpeg Render', 'nuke.nodePaste({nk})'.format(nk=nk),shortcut='F6')
-
-
- def unconfigurePlugin(self):
- self.m.removeItem("FFmpeg Render")
-
-
- from sys import platform as __platform
- if __platform == "linux" or __platform == "linux2":
- _platform = 'linux'
- elif __platform == "darwin":
- _platform = 'osx'
- elif __platform == "win32":
- _platform = 'win'
-
-
- def frames_to_tc(total_frames, frame_rate):
- fps_int = int(round(frame_rate))
- smpte_token = ":"
- hours = int(total_frames / (3600 * fps_int))
- minutes = int(total_frames / (60 * fps_int) % 60)
- seconds = int(total_frames / fps_int % 60)
- frames = int(total_frames % fps_int)
- return "%02d:%02d:%02d%s%02d" % (hours, minutes, seconds, smpte_token, frames)
-
- def terminal_render():
- parser = argparse.ArgumentParser(description='Render from Nuke to ffmpeg.')
- parser.add_argument("nuke_script",
- help="Nuke script to render.")
- parser.add_argument("-X", "--write",
- help="Name of the WriteFFMPEG node to render.")
- parser.add_argument("-F", "--framerange",
- help="framerange to render. Please specify <start>-<end>.",
- required=False)
- parser.add_argument("-o", "--output",
- help="Output qt to render to. Will use the value of the file knob on the WriteFFMPEG node if not specified.",
- required=False)
- args = parser.parse_args()
- nuke_script = args.nuke_script
- nuke.scriptOpen(nuke_script)
- node = nuke.toNode(args.write)
- node.begin()
- write = nuke.toNode('write_tmp')
- if args.framerange and "-" in args.framerange:
- fr = nuke.FrameRange()
- fr.setLast(int(args.framerange.split('-')[-1]))
- fr.setFirst(int(args.framerange.split('-')[0]))
- else:
- node_framerange = node['framerange'].getValue()
- if node_framerange and "-" in node_framerange:
- fr = nuke.FrameRange()
- fr.setLast(int(node_framerange.split('-')[-1]))
- fr.setFirst(int(node_framerange.split('-')[0]))
- else:
- fr = node.frameRange()
-
- tmpimg = tempfile.mkstemp('.tiff', "ffmpeg_temp_")[1]
- if _platform == 'win':
- write['file'].setValue(tmpimg.replace("\\","/"))
- else:
- write['file'].setValue(tmpimg)
- framerate = node['framerate'].getValue()
- output = node['file'].getValue()
-
- # vcurrent
- vcurrent = node['vcurrent'].getValue()
-
- # create folder if necessary
- dir = os.path.dirname(output)
- osdir = nuke.callbacks.filenameFilter(dir)
- try:
- os.makedirs(osdir)
- except OSError:
- pass
-
- tc = frames_to_tc(fr.first(), framerate)
- ffmpeg_args = "ffmpeg -hide_banner -loglevel info -y \
- -f rawvideo -pixel_format rgb48le -video_size {0}x{1} \
- -framerate {2} -i pipe:0 -timecode {3} {4} {5}".format(
- node.width(), node.height(), framerate, tc,
- node['ffmpeg_args'].getValue(), output)
- print(ffmpeg_args)
- ffproc = subprocess.Popen(
- shlex.split(ffmpeg_args),
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE
- )
- for i, f in enumerate(fr):
- nuke.execute(write, f, f)
- print("Rendering frame \t{0} of {1}".format(i, fr.frames()))
- # tifffile usage
- img = tifffile.imread(tmpimg)
- # numpy usage
- img.tofile(ffproc.stdin)
-
- if _platform == 'win':
- try:
- os.remove(tmpimg.replace("\\","/"))
- except:
- pass
- else:
- try:
- os.remove(tmpimg)
- except:
- pass
- result, error = ffproc.communicate()
-
- print("Rendering done.")
-
- # vcurrent
- import re
- import shutil
- import os.path as path
-
- if vcurrent == 1:
- print("Copying vcurrent.")
- pattern = re.compile('[vV]\d+')
- ending = output.split('/')[-1]
- result = pattern.findall(ending)
- two_up = path.abspath(path.join(output, "../.."))
- vcurrentfile = two_up + '\\' + ending.replace((result[-1]), 'vcurrent')
- shutil.copyfile(output, vcurrentfile)
- print("Copying vcurrent done.")
-
- if __name__=="__main__":
- terminal_render()
-
-
- def prep():
- nuke.scriptSave()
- node = nuke.thisNode()
- ffpy = __file__
- ffpy = ffpy.replace('pyc', 'py')
- node_framerange = node['framerange'].getValue()
-
- nk_cmd = "{0} -t {1} {2} --write {3} --output {4}".format(
- "\"" + nuke.EXE_PATH + "\"",
- ffpy,
- nuke.root().knob("name").value(),
- node.fullName(),
- node['file'].getValue())
- print("RENDER COMMAND:\n\t{0}".format(nk_cmd))
- if _platform == "win":
- print (os.system(nk_cmd))
- return
- if _platform == "osx":
- cmd = '''osascript 2>/dev/null <<EOF
- tell application "Terminal"
- if not (exists window 1) then reopen
- activate
- do script "{0}"
- end tell
- EOF'''.format(nk_cmd)
- elif _platform == "linux":
- # cmd = 'xterm -e "bash {0}"'.format(nk_cmd)
- cmd = 'gnome-terminal -e "bash -c \\"{0}; exec bash\\""'.format(nk_cmd)
- #cmd = 'gnome-terminal -e "bash -c \\"{0}\\""'.format(nk_cmd)
- subprocess.Popen(cmd, shell=True)
|