Nenhuma descrição
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

ffmpeg_render.py 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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. # create folder if necessary
  75. dir = os.path.dirname(output)
  76. osdir = nuke.callbacks.filenameFilter(dir)
  77. try:
  78. os.makedirs(osdir)
  79. except OSError:
  80. pass
  81. tc = frames_to_tc(fr.first(), framerate)
  82. ffmpeg_args = "ffmpeg -hide_banner -loglevel info -y \
  83. -f rawvideo -pixel_format rgb48le -video_size {0}x{1} \
  84. -framerate {2} -i pipe:0 -timecode {3} {4} {5}".format(
  85. node.width(), node.height(), framerate, tc,
  86. node['ffmpeg_args'].getValue(), output)
  87. print(ffmpeg_args)
  88. ffproc = subprocess.Popen(
  89. shlex.split(ffmpeg_args),
  90. stdin=subprocess.PIPE,
  91. stdout=subprocess.PIPE
  92. )
  93. for i, f in enumerate(fr):
  94. nuke.execute(write, f, f)
  95. print("Rendering frame \t{0} of {1}".format(i, fr.frames()))
  96. # tifffile usage
  97. img = tifffile.imread(tmpimg)
  98. # numpy usage
  99. img.tofile(ffproc.stdin)
  100. if _platform == 'win':
  101. try:
  102. os.remove(tmpimg.replace("\\","/"))
  103. except:
  104. pass
  105. else:
  106. try:
  107. os.remove(tmpimg)
  108. except:
  109. pass
  110. result, error = ffproc.communicate()
  111. print("Rendering done.")
  112. if __name__=="__main__":
  113. terminal_render()
  114. def prep():
  115. nuke.scriptSave()
  116. node = nuke.thisNode()
  117. ffpy = __file__
  118. ffpy = ffpy.replace('pyc', 'py')
  119. node_framerange = node['framerange'].getValue()
  120. nk_cmd = "{0} -t {1} {2} --write {3} --output {4}".format(
  121. "\"" + nuke.EXE_PATH + "\"",
  122. ffpy,
  123. nuke.root().knob("name").value(),
  124. node.fullName(),
  125. node['file'].getValue())
  126. print("RENDER COMMAND:\n\t{0}".format(nk_cmd))
  127. if _platform == "win":
  128. print (os.system(nk_cmd))
  129. return
  130. if _platform == "osx":
  131. cmd = '''osascript 2>/dev/null <<EOF
  132. tell application "Terminal"
  133. if not (exists window 1) then reopen
  134. activate
  135. do script "{0}"
  136. end tell
  137. EOF'''.format(nk_cmd)
  138. elif _platform == "linux":
  139. # cmd = 'xterm -e "bash {0}"'.format(nk_cmd)
  140. cmd = 'gnome-terminal -e "bash -c \\"{0}; exec bash\\""'.format(nk_cmd)
  141. #cmd = 'gnome-terminal -e "bash -c \\"{0}\\""'.format(nk_cmd)
  142. subprocess.Popen(cmd, shell=True)