Earlier this week, I posted a super basic beginner's tutorial intro into manipulating scripts inside of Nuke, and gave you a handy little code that played a sound when your render was finished. Well, after a little trial and error, I managed to come up with a script that attaches itself to Nuke's Write node and adds a custom tab with the 'Render with Sound' function. I tried to mimic the original Write node's interface, but unfortunately due to the dynamic nature of the Write node and the various file extensions and video codecs that are interactively added, it tends to switch back and forth between tabs. Although, once you set your file extension and codec, you can switch back to the 'WriteSound' tab without it swapping back. If anyone knows a workaround to this, please let me know.
The final result:
As with the last post, to make this work, you need a .WAV sound file. Check out AT&T Labs and make your own if needed. Make sure to take note of its physical location on your drive.
We're going to be changing the user interface ever so slightly and to do that we'll need to tell Nuke to make some changes. The menu.py file specifies any customization to Nuke's interface, and is usually found in the default user plugins folder. The default locations for this folder are:
Win - 'C:/Documents and Settings/USER/.nuke/
Mac - '$HOME/.nuke/
If you can't find a menu.py file in these folders, go ahead and create your own by saving out of your favorite text editor. To get started, you will need to add the following code to your menu.py file.
import writeSound
writeSound.attachWriteSoundNode()
This tells Nuke to import the writeSound script, and inside of writeSound go ahead and execute the attachWriteSoundNode command.
Next, you will need the following bit of code. Go ahead and copy this into a new file in your text editor.
# Developed by Christian Castaneda
# chris@castanedafx.com
# This should create a custom write node that plays a sound when finished rendering
import nuke
nukeOriginalWriteSoundNode = nuke.createNode
def attachWriteSoundNode():
nuke.createNode = customWriteSoundNode
def customWriteSoundNode(node, knobs = "", inpanel = True):
if node == "Write":
writeNode = nukeOriginalWriteSoundNode( node, knobs, inpanel )
## attach our custom tab
createWriteSoundTab( writeNode )
return writeNode
else:
return nukeOriginalWriteSoundNode( node, knobs, inpanel )
def createWriteSoundTab(node):
#### create knobs
tabKnob = nuke.Tab_Knob('WriteSound')
channelKnob = nuke.Link_Knob('channels_name', 'channels')
fileKnob = nuke.Link_Knob('file_name', 'file')
proxyKnob = nuke.Link_Knob('proxy_name', 'proxy')
divideKnob = nuke.Text_Knob('')
colorKnob = nuke.Link_Knob('colorspace_name', 'colorspace')
preMultKnob = nuke.Link_Knob('premultiplied_name', 'premultiplied')
rawDataKnob = nuke.Link_Knob('raw data name', 'raw data')
viewsKnob = nuke.Link_Knob('views_name', 'views')
typeKnob = nuke.Link_Knob('file type name', 'file type')
orderKnob = nuke.Link_Knob('render_order_name', 'render order')
buttonKnob = nuke.PyScript_Knob('Render With Sound')
#### make links to the Original Write
channelKnob.setLink('channels')
fileKnob.setLink('file')
proxyKnob.setLink('proxy')
colorKnob.setLink('colorspace')
preMultKnob.setLink('premultiplied')
rawDataKnob.setLink('raw')
viewsKnob.setLink('views')
typeKnob.setLink('file_type')
orderKnob.setLink('render_order')
script = """
############ This section by Fredrik Brannbacka #############
##
## Make sure you set the sounds file path
macSound = 'PATH/TO/SOUND/FILE'
winSound = 'PATH/TO/SOUND/FILE'
def playSound():
if nuke.env["MACOS"]:
sys.path.append('/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python')
sys.path.append('/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python/PyObjC')
from AppKit import NSSound
sound = NSSound.alloc()
sound.initWithContentsOfFile_byReference_(macSound, True)
sound.play()
elif nuke.env["WIN32"]:
import winsound
winsound.PlaySound(winSound, winsound.SND_FILENAME|winsound.SND_ASYNC)
node = nuke.selectedNode()
if node.Class()=='Write':
start,end = nuke.getFramesAndViews('Render Range','%i,%i' % (nuke.root()['first_frame'].value(),nuke.root()['last_frame'].value()))[0].split(',',2)
if nuke.execute(node.name(),int(start),int(end)):
playSound()
"""
buttonKnob.setValue(script)
#### add knobs to node
for k in [tabKnob, channelKnob, fileKnob, proxyKnob, divideKnob, colorKnob, preMultKnob, rawDataKnob, viewsKnob, typeKnob, orderKnob, buttonKnob]:
node.addKnob(k)
Here's an important step to make sure that this works. You need to change the path of the sound file in the code, which should be lines 50/51. Specifically, you are looking for:
## Make sure you set the sounds file path
macSound = 'PATH/TO/SOUND/FILE'
winSound = 'PATH/TO/SOUND/FILE'
Once you're done editing the code, save it out in the same folder as menu.py with the filename of 'writeSound.py'.
Restart Nuke and feel free to enjoy the wonderful bliss that is audible renders. Ahhhhh.
