Ingen beskrivning
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ffmpeg_render.py 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. from __future__ import with_statement
  2. from __future__ import print_function
  3. from __future__ import division
  4. import os, sys
  5. import subprocess, shlex
  6. import argparse
  7. import tempfile
  8. import numpy as np
  9. import nuke
  10. import tifffile
  11. class ffmpeg_render(KellerNukePlugin):
  12. def configurePlugin(self):
  13. workgroup = os.getenv('NUKE_PATH')
  14. nk = os.path.join(workgroup, "pythonpluginsUI/nukeffmpeg", "Preview_QT.nk")
  15. nk = nk.replace('\\','/')
  16. nk = "\"" + nk + "\""
  17. menubar = nuke.menu("Nuke")
  18. self.m = menubar.addMenu("&Render")
  19. self.m.addCommand('FFmpeg Render', 'nuke.nodePaste({nk})'.format(nk=nk),shortcut='F6')
  20. def unconfigurePlugin(self):
  21. self.m.removeItem("FFmpeg Render")
  22. from sys import platform as __platform
  23. if __platform == "linux" or __platform == "linux2":
  24. _platform = 'linux'
  25. elif __platform == "darwin":
  26. _platform = 'osx'
  27. elif __platform == "win32":
  28. _platform = 'win'
  29. def frames_to_tc(total_frames, frame_rate):
  30. fps_int = int(round(frame_rate))
  31. smpte_token = ":"
  32. hours = int(total_frames / (3600 * fps_int))
  33. minutes = int(total_frames / (60 * fps_int) % 60)
  34. seconds = int(total_frames / fps_int % 60)
  35. frames = int(total_frames % fps_int)
  36. return "%02d:%02d:%02d%s%02d" % (hours, minutes, seconds, smpte_token, frames)
  37. def terminal_render():
  38. parser = argparse.ArgumentParser(description='Render from Nuke to ffmpeg.')
  39. parser.add_argument("nuke_script",
  40. help="Nuke script to render.")
  41. parser.add_argument("-X", "--write",
  42. help="Name of the WriteFFMPEG node to render.")
  43. parser.add_argument("-F", "--framerange",
  44. help="framerange to render. Please specify <start>-<end>.",
  45. required=False)
  46. parser.add_argument("-o", "--output",
  47. help="Output qt to render to. Will use the value of the file knob on the WriteFFMPEG node if not specified.",
  48. required=False)
  49. args = parser.parse_args()
  50. nuke_script = args.nuke_script
  51. nuke.scriptOpen(nuke_script)
  52. node = nuke.toNode(args.write)
  53. node.begin()
  54. write = nuke.toNode('write_tmp')
  55. if args.framerange and "-" in args.framerange:
  56. fr = nuke.FrameRange()
  57. fr.setLast(int(args.framerange.split('-')[-1]))
  58. fr.setFirst(int(args.framerange.split('-')[0]))
  59. else:
  60. node_framerange = node['framerange'].getValue()
  61. if node_framerange and "-" in node_framerange:
  62. fr = nuke.FrameRange()
  63. fr.setLast(int(node_framerange.split('-')[-1]))
  64. fr.setFirst(int(node_framerange.split('-')[0]))
  65. else:
  66. fr = node.frameRange()
  67. tmpimg = tempfile.mkstemp('.tiff', "ffmpeg_temp_")[1]
  68. if _platform == 'win':
  69. write['file'].setValue(tmpimg.replace("\\","/"))
  70. else:
  71. write['file'].setValue(tmpimg)
  72. framerate = node['framerate'].getValue()
  73. output = node['file'].getValue()
  74. # vcurrent
  75. vcurrent = node['vcurrent'].getValue()
  76. # create folder if necessary
  77. dir = os.path.dirname(output)
  78. osdir = nuke.callbacks.filenameFilter(dir)
  79. try:
  80. os.makedirs(osdir)
  81. except OSError:
  82. pass
  83. tc = frames_to_tc(fr.first(), framerate)
  84. ffmpeg_args = "ffmpeg -hide_banner -loglevel info -y \
  85. -f rawvideo -pixel_format rgb48le -video_size {0}x{1} \
  86. -framerate {2} -i pipe:0 -timecode {3} {4} {5}".format(
  87. node.width(), node.height(), framerate, tc,
  88. node['ffmpeg_args'].getValue(), output)
  89. print(ffmpeg_args)
  90. ffproc = subprocess.Popen(
  91. shlex.split(ffmpeg_args),
  92. stdin=subprocess.PIPE,
  93. stdout=subprocess.PIPE
  94. )
  95. for i, f in enumerate(fr):
  96. nuke.execute(write, f, f)
  97. print("Rendering frame \t{0} of {1}".format(i, fr.frames()))
  98. # tifffile usage
  99. img = tifffile.imread(tmpimg)
  100. # numpy usage
  101. img.tofile(ffproc.stdin)
  102. if _platform == 'win':
  103. try:
  104. os.remove(tmpimg.replace("\\","/"))
  105. except:
  106. pass
  107. else:
  108. try:
  109. os.remove(tmpimg)
  110. except:
  111. pass
  112. result, error = ffproc.communicate()
  113. print("Rendering done.")
  114. # vcurrent
  115. import re
  116. import shutil
  117. import os.path as path
  118. if vcurrent == 1:
  119. print("Copying vcurrent.")
  120. pattern = re.compile('[vV]\d+')
  121. ending = output.split('/')[-1]
  122. result = pattern.findall(ending)
  123. two_up = path.abspath(path.join(output, "../.."))
  124. vcurrentfile = two_up + '\\' + ending.replace((result[-1]), 'vcurrent')
  125. shutil.copyfile(output, vcurrentfile)
  126. print("Copying vcurrent done.")
  127. if __name__=="__main__":
  128. terminal_render()
  129. def prep():
  130. nuke.scriptSave()
  131. node = nuke.thisNode()
  132. ffpy = __file__
  133. ffpy = ffpy.replace('pyc', 'py')
  134. node_framerange = node['framerange'].getValue()
  135. nk_cmd = "{0} -t {1} {2} --write {3} --output {4}".format(
  136. "\"" + nuke.EXE_PATH + "\"",
  137. ffpy,
  138. nuke.root().knob("name").value(),
  139. node.fullName(),
  140. node['file'].getValue())
  141. print("RENDER COMMAND:\n\t{0}".format(nk_cmd))
  142. if _platform == "win":
  143. print (os.system(nk_cmd))
  144. return
  145. if _platform == "osx":
  146. cmd = '''osascript 2>/dev/null <<EOF
  147. tell application "Terminal"
  148. if not (exists window 1) then reopen
  149. activate
  150. do script "{0}"
  151. end tell
  152. EOF'''.format(nk_cmd)
  153. elif _platform == "linux":
  154. # cmd = 'xterm -e "bash {0}"'.format(nk_cmd)
  155. cmd = 'gnome-terminal -e "bash -c \\"{0}; exec bash\\""'.format(nk_cmd)
  156. #cmd = 'gnome-terminal -e "bash -c \\"{0}\\""'.format(nk_cmd)
  157. subprocess.Popen(cmd, shell=True)