{ // AEtoMayaAudioKeyframeConverter_vCS5.5.jsx // // Peter Stache // // PeteStache.weebly.com // PeteTheGerman.blogspot.com // // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // // NOTE: // This is the CS5.5 version! // If you run it on any other version there might be complications! // // This script converts the audio waveform of any audio file or video file with // audio to keyframes and then exports this information as a Maya ASCII file. // // The script has a UI. // The UI allows the user to import a audio or audio- video file. // Since Maya only accepts audio files of WAV and AIFF format, the script will // check the file format of the imported file // and convert it if needed. // After import the user the user can convert the audio waveform to keyframes. // The "Convert Audio to Keyframe" function is a After Effects native function and // not a result of this script! // After converting the user can export the After Effects scene to a Maya ASCII file. // // The Maya ASCII file will include a locator called "Audio Amplitude" with // attributes ("Left Channel", "Right Channel", "Both Channels"), similar to the null // that After Effects creates when converting audio to keyframes. // // This script is free. // Feel free to play around, change and improve things, but if you pubished a script // based on this script,please give me some credit. // // Also if there are any questions or ideason how to improve this script, visit my blog or website // listed on top and send me an email. // main variables var win = new Window("palette", scriptName); var scriptName = "AE to Maya Audio Keyframe Converter"; function AEtoMayaAudioKeyframeConverter() { // confirm that the script will close the current project var conf = confirm(scriptName + " needs to close the current project\nDo you want to continue?", false, "New Project"); if(!conf){ return false; } // create a new project var proj =app.newProject(); // create the UI AEtoMayaAudioKeyframeConverterUI = function() { importPnl = win.add("panel", [0,0,500,50], "File Options"); importPnl.pathT = importPnl.add("statictext", [10, 10, 55, 30], "File Path:"); importPnl.path = importPnl.add("statictext", [55, 10, 350, 30], " "); importPnl.importBtn = importPnl.add("button", [350, 10, 490, 30], "Import"); convertPnl = win.add("panel", [0, 0, 500, 70], "Convert Options"); var fps = [15, 24, 25, 30, 48, 50, 60]; convertPnl.fpsList = convertPnl.add("dropdownlist", [30,10, 80, 30], fps); convertPnl.fpsListText = convertPnl.add("statictext", [90, 12, 200, 30], "Frame Rate"); convertPnl.fpsList.selection = 1; convertPnl.smoothCheck = convertPnl.add("checkbox", [200, 12, 350, 30], "Smooth Keyframes"); convertPnl.normalizeCheck = convertPnl.add("checkbox", [350, 12, 500, 30], "Noramlize Keyframes"); convertPnl.convertBtn = convertPnl.add("button", [10, 30, 490, 60], "Convert To Keyframes"); convertPnl.enabled = false; convertPnl.smoothCheck.value = true; convertPnl.normalizeCheck.value = true; exportPnl = win.add("panel", [0, 0, 500, 80], "Export Options"); exportPnl.includeAudioCheck = exportPnl.add("checkbox", [100, 10, 250, 30], "Include Audio File"); exportPnl.launchCheck = exportPnl.add("checkbox", [300, 10, 500, 30], "Launch Maya after export"); exportPnl.exportBtn = exportPnl.add("button", [10, 30, 490, 70], "Export as Maya ASCII File"); exportPnl.enabled = false; exportPnl.includeAudioCheck.value = true; exportPnl.launchCheck.value = false; } AEtoMayaAudioKeyframeConverterUI(); // import a file importPnl.importBtn.onClick = function() { var path = File.openDialog(); var pathText; if(path.fsName.length > 50) { pathText = "..." + path.fsName.substring(20, path.fsName.length); } else{ pathText = path.fsName; } importPnl.path.text = pathText; importAudio(path); } importAudio = function(path) { // check the number of items in the project panel // NOTE: the script only works with one audio file if(proj.numItems>0){ var conf = confirm(scriptName+" will remove existing comps and files. Continue?"); if(!conf){ return false; } for(i = proj.numItems; i >0; --i){ // reverse loop. Don't ask! it somehow works better proj.item(i).remove(); // when removing items } } var audioFile = proj.importFile(new ImportOptions(path)); // check whether the file has audio if(!audioFile.hasAudio) { alert(audioFile.name + " has no Audio!\rPlease select a file with audio!"); importPnl.path.text = " "; audioFile.remove(); return false; } else{ var audioFileName = audioFile.name; // check file extension if(audioFileName.search(".wav")== -1 && audioFileName.search(".aif")== -1) { // if the file is not a Maya friendly WAV or AIFF file the user can will be asked whether to convert the file var aifConv = confirm("Maya does not accept this format. Do you want to convert the sound to Maya friendly AIFF format? (Recomended)", false, "AIFF Conversion"); if(aifConv){ var aifFile = new File(File.saveDialog("Save", "AIFF: *.aif")); if(aifFile){ proj.showWindow(false); proj.showWindow(true); proj.item(1).selected =true; app.executeCommand(app.findMenuCommandId("New Comp from Selection")); var comp = proj.activeItem; var aifTemp = 'AIFF 48kHz'; var renderItem = proj.renderQueue.items.add(comp); renderItem.outputModule(1).file = aifFile; renderItem.outputModule(1).applyTemplate(aifTemp); renderItem.outputModule(1).postRenderAction = 3014; proj.renderQueue.render(); audioFile.remove(); comp.remove(); importPnl.path.text = aifFile.fsName; } } } proj.showWindow(false); proj.showWindow(true); proj.item(1).selected =true; app.executeCommand(app.findMenuCommandId("New Comp from Selection")); proj.activeItem.frameRate = 24; convertPnl.enabled= true; return true; } } // function to change the frame rate of the comp from the UI convertPnl.fpsList.onChange = function(){ var newFps = convertPnl.fpsList.selection; proj.activeItem.frameRate = newFps.text; } convertPnl.convertBtn.onClick = function() { // settings set proj.timeDisplayType = 1813; proj.framesCountType = 2413; proj.framesUseFeetFrames = false; // check the "Smooth Keyframes" checkbox if(convertPnl.smoothCheck.value == true){ var orgFps = proj.activeItem.frameRate; proj.activeItem.frameRate = orgFps/2; app.executeCommand(app.findMenuCommandId("Convert Audio to Keyframes")); proj.activeItem.frameRate = orgFps; } else{ app.executeCommand(app.findMenuCommandId("Convert Audio to Keyframes")); } smoothAndNormalize(); } function smoothAndNormalize(){ var channels = new Array("Left Channel", "Right Channel", "Both Channels"); // again check the "Smooth Keyframes" checkbox if(convertPnl.smoothCheck.value == true){ for(i = 0; i<3; ++i){ var layer = proj.activeItem.layer(1); var effect = layer.effect(channels[i])(1); var keyNum = layer.effect(channels[i])(1).numKeys; for(c = 1; c <= keyNum; ++c){ effect.setTemporalAutoBezierAtKey(c, true); } } } // check the "Normalize Keyframes" checkbox if(convertPnl.normalizeCheck.value == true){ for(i = 0; i<=2; ++i){ var layer = proj.activeItem.layer(1); var effect = layer.effect(channels[i])(1); var keyNum = layer.effect(channels[i])(1).numKeys; var maxValue=0; for (f=1; f <= keyNum; ++f){ var value = effect.keyValue(f); if(value> maxValue){ maxValue = value; } } for(d =1; d<=keyNum; ++d){ var newValue = effect.keyValue(d) / maxValue; effect.setValueAtKey(d, newValue); } } } exportPnl.enabled = true; } exportPnl.exportBtn.onClick = function(){ // set some settings proj.timecodeDisplayType = 1813; proj.framesCountType = 2413; proj.framesUseFeetFrames = false; // create a new ma file var myFile = new File(File.saveDialog("Save", "Maya ASCII: *.ma")); myFile.open("a"); // get the date var date = new Date; var fpsIndex = convertPnl.fpsList.selection.index; var timeNames = new Array("game", "film", "pal", "ntsc", "show", "palf", "ntscf"); var timeName = timeNames[fpsIndex]; // write the default part of the Maya ASCII file var text = '//Maya ASCII 4.5 scene\ //Name: AE to Maya Audio Keyframe Converter v1.0:\ //Last modified: '+ date.toLocaleDateString() +'\ requires maya "4.5"; \ currentUnit -l centimeter -a degree -t '+ timeName+';\ createNode transform -n "Audio_Amplitude";\ addAttr -ci true -sn "LeftChannel" -ln "LeftChannel" -at "double";\ addAttr -ci true -sn "RightChannel" -ln "RightChannel" -at "double";\ addAttr -ci true -sn "BothChannels" -ln "BothChannels" -at "double";\ setAttr -k on ".LeftChannel";\ setAttr -k on ".RightChannel";\ setAttr -k on ".BothChannels";\ createNode locator -n "Audio_AmplitudeShape" -p "Audio_Amplitude";\ setAttr -k off ".v";\ createNode transform -s -n "persp";\ setAttr ".v" no;\ setAttr ".t" -type "double3" 37.8 28.4 37.8 ;\ setAttr ".r" -type "double3" -27.9 45 0 ;\ createNode camera -s -n "perspShape" -p "persp";\ setAttr -k off ".v" no;\ setAttr ".rnd" no;\ setAttr ".ncp" 0.1;\ setAttr ".fcp" 1000;\ setAttr ".fd" 5;\ setAttr ".coi" 100;\ setAttr ".ow" 10;\ setAttr ".imn" -type "string" "persp";\ setAttr ".den" -type "string" "persp_depth";\ setAttr ".man" -type "string" "persp_mask";\ setAttr ".hc" -type "string" "viewSet -p %camera";\ createNode transform -s -n "top";\ setAttr ".v" no;\ setAttr ".t" -type "double3" 0 100 0 ;\ setAttr ".r" -type "double3" -90 0 0 ;\ createNode camera -s -n "topShape" -p "top";\ setAttr -k off ".v" no;\ setAttr ".rnd" no;\ setAttr ".ncp" 0.1;\ setAttr ".fcp" 200;\ setAttr ".fd" 5;\ setAttr ".coi" 100;\ setAttr ".ow" 30;\ setAttr ".imn" -type "string" "top";\ setAttr ".den" -type "string" "top_depth";\ setAttr ".man" -type "string" "top_mask";\ setAttr ".hc" -type "string" "viewSet -t %camera";\ setAttr ".o" yes;\ createNode transform -s -n "front";\ setAttr ".v" no;\ setAttr ".t" -type "double3" 0 0 100 ;\ createNode camera -s -n "frontShape" -p "front";\ setAttr -k off ".v" no;\ setAttr ".rnd" no;\ setAttr ".ncp" 0.1;\ setAttr ".fcp" 200;\ setAttr ".fd" 5;\ setAttr ".coi" 100;\ setAttr ".ow" 30;\ setAttr ".imn" -type "string" "front";\ setAttr ".den" -type "string" "front_depth";\ setAttr ".man" -type "string" "front_mask";\ setAttr ".hc" -type "string" "viewSet -f %camera";\ setAttr ".o" yes;\ createNode transform -s -n "side";\ setAttr ".v" no;\ setAttr ".t" -type "double3" 100 0 0 ;\ setAttr ".r" -type "double3" 0 90 0 ;\ createNode camera -s -n "sideShape" -p "side";\ setAttr -k off ".v" no;\ setAttr ".rnd" no;\ setAttr ".ncp" 0.1;\ setAttr ".fcp" 200;\ setAttr ".fd" 5;\ setAttr ".coi" 100;\ setAttr ".ow" 30;\ setAttr ".imn" -type "string" "side";\ setAttr ".den" -type "string" "side_depth";\ setAttr ".man" -type "string" "side_mask";\ setAttr ".hc" -type "string" "viewSet -s %camera";\ setAttr ".o" yes;'; myFile.write(text); // now the main part // check smooth keyframe is checked var tan; if(convertPnl.smoothCheck.value == true){ tan = "9"; } else{ tan = "2"; } var layer = proj.activeItem.layer(1); var fps = proj.activeItem.frameRate; var effect = layer.effect("Left Channel")(1); var numKeys = effect.numKeys; // first left Channel text = 'createNode animCurveTU -n "Audio_Amplitude_LeftChannel";\ setAttr ".tan" '+tan+';\ setAttr ".wgt" no;\ setAttr -s '+numKeys+ ' ".ktv[1:'+numKeys+']" '; myFile.write(text); for(i =1; i<= numKeys; ++i){ // return Frame number var value = effect.keyValue(i); var time = effect.keyTime(i); var frame = timeToCurrentFormat(time, fps, false); var input; if(i == numKeys){ var input = frame + " " +value +";\n"; } else{ var input = frame + " " +value +" "; } myFile.write(input); } // then right Channel effect = layer.effect("Right Channel")(1); numKeys = effect.numKeys; text = 'createNode animCurveTU -n "Audio_Amplitude_RightChannel";\ setAttr ".tan" '+tan+';\ setAttr ".wgt" no;\ setAttr -s '+numKeys+ ' ".ktv[1:'+numKeys+']" '; myFile.write(text); for(i =1; i<= numKeys; ++i){ // return Frame number var value = effect.keyValue(i); var time = effect.keyTime(i); var frame = timeToCurrentFormat(time, fps, false); var input; if(i == numKeys){ var input = frame + " " +value +";\n"; } else{ var input = frame + " " +value +" "; } myFile.write(input); } // last both Channels effect = layer.effect("Both Channels")(1); numKeys = effect.numKeys; text = 'createNode animCurveTU -n "Audio_Amplitude_BothChannels";\ setAttr ".tan" '+tan+';\ setAttr ".wgt" no;\ setAttr -s '+numKeys+ ' ".ktv[1:'+numKeys+']" '; myFile.write(text); for(i =1; i<= numKeys; ++i){ // return Frame number var value = effect.keyValue(i); var time = effect.keyTime(i); var frame = timeToCurrentFormat(time, fps, false); var input; if(i == numKeys){ var input = frame + " " +value +";\n"; } else{ var input = frame + " " +value +" "; } myFile.write(input); } // check if "Audio included" is checked if(exportPnl.includeAudioCheck.value == true){ var path = " "; var newPath = ""; // check which item is the audio file for(i =1 ; i <= proj.numItems; ++i){ if(proj.item(i).hasAudio == true && proj.item(i) instanceof FootageItem){ path = proj.item(i).mainSource.file.fsName; for (i = 0; i < path.length; ++i){ if (path.charAt(i) == "\\"){ newPath += "/"; } else{ newPath += path.charAt(i); } } } } var audioName = proj.activeItem.name; var duration = proj.activeItem.duration; var numFrames = timeToCurrentFormat(duration, fps, true); var charIndex; for (i = 0 ; i < numFrames.length; ++i){ if(numFrames.charAt(i) != "0"){ charIndex = i; break; } } numFrames = numFrames.substr(charIndex, numFrames.length); var plusFrame = parseInt(numFrames) +1; text = 'createNode audio -n ' + audioName + ';\ setAttr ".ef" ' + numFrames + ';\ setAttr ".ss" 1;\ setAttr ".se" '+plusFrame+';\ setAttr ".f" -type "string" "'+newPath+'";\ timeControl -e -displaySound 1 -sound '+audioName+' $gPlayBackSlider;\n'; myFile.write(text); } // now to setup the Maya scene settings var duration = proj.activeItem.duration; var numFrames = timeToCurrentFormat(duration, fps, true); text= 'createNode script -n "sceneConfigurationScriptNode";\ setAttr ".b" -type "string" "playbackOptions -min 1 -max '+numFrames+' -ast 1 -aet '+numFrames+'";\ setAttr ".st" 6;\ connectAttr "Audio_Amplitude_LeftChannel.o" "Audio_Amplitude.LeftChannel";\ connectAttr "Audio_Amplitude_RightChannel.o" "Audio_Amplitude.RightChannel";\ connectAttr "Audio_Amplitude_BothChannels.o" "Audio_Amplitude.BothChannels";'; myFile.write(text); myFile.close(); // check "Launch Maya after export" is checked if(exportPnl.launchCheck.value == true){ myFile.execute(); } return true; } win.show(); } AEtoMayaAudioKeyframeConverter(); }