Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Save an animation preset with a script and then customize the file explorer it opened

Explorer ,
Dec 11, 2021 Dec 11, 2021

So for the context, I'm working on a script and and what it has to do now is to save an animation preset, the only way to do that is by using : app.executeCommand(3075); what it does is that basically presses the button to save the preset ( so it opens you the file explorer and you have to name it + save it yourself )

I have 3 small questions linked to each other:

1. Is there a way to put a "default directory" for that file explorer? ( Considering I'm not using the way to just open the file explorer, I'm using app.executeCommand(3075); and it opens the " save an animation preset " file explorer)

2. Is there a way to to customize that window? Like changing the extension, the title, etc. ) just like when we would do that : new File("Default File Name").saveDlg(["Title"],["PNG Files:*.png"]);

3. Is there a way to know what the user wrote inside of that file explorer? ( like the name he put to the file )

I know that's a lot of question, but this whole file world is not really clear for me

Thanks in advance,
Redy

TOPICS
Error or problem , FAQ , Scripting
2.7K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Participant , Dec 12, 2021 Dec 12, 2021

Hey, I'd have some ideas for workarounds:

 

quote

1. Is there a way to put a "default directory" for that file explorer? ( Considering I'm not using the way to just open the file explorer, I'm using app.executeCommand(3075); and it opens the " save an animation preset " file explorer)

 

I just tested this successfully: so, the file explorer always opens up from the last folder. And that also goes for from where you applied a preset. So the idea would be to create a dummy ffx preset from where you want the

...
Translate
LEGEND ,
Dec 12, 2021 Dec 12, 2021

Long and short: No, no and no. When you use menu commands, the default AE behavior takes over. You can only control any of that by writing your own file dialog, but even that won't help you much. unlike e.g. in Photoshop's file dialogs, most options cannot be accessed by scripts in AE. It's just a black box.

 

Mylenium

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Dec 12, 2021 Dec 12, 2021

Hey, I'd have some ideas for workarounds:

 

quote

1. Is there a way to put a "default directory" for that file explorer? ( Considering I'm not using the way to just open the file explorer, I'm using app.executeCommand(3075); and it opens the " save an animation preset " file explorer)

 

I just tested this successfully: so, the file explorer always opens up from the last folder. And that also goes for from where you applied a preset. So the idea would be to create a dummy ffx preset from where you want the default directory to be and apply the preset to your comp. Then delete it from the comp and from the directory. Now execute the command to save the preset and the file explorer should open from the directory you applied the preset from.

 

 

quote

2. Is there a way to to customize that window? Like changing the extension, the title, etc. ) just like when we would do that : new File("Default File Name").saveDlg(["Title"],["PNG Files:*.png"]);

 

Maybe you could copy a text to your clipboard and then paste it once the dialog opens. But this would be really hacky and I'm not sure whether it would work. I haven't been able to make it work yet when using AE's paste command. Maybe it'll work when forcing keyboard commands (like Ctrl+V)? I once have been able to make an enter keypress work on one these dialogs by simulating an enter keypress with AutoIt on Windows and via AppleScript on Mac right before I executed the dialog. Maybe the same would apply for pasting? Not sure. Also, this would, of course, be only to give it a default name. Other than that, I don't think there is a way to do any other modifications.

 

 

quote

3. Is there a way to know what the user wrote inside of that file explorer? ( like the name he put to the file )

 

Hm, not sure. The only thing I could think of right now would be to scan all possible folders first and then after the file has been saved to look for a new ffx file. But that might be quite insane since there would be probably too many folders on your computer to scan. Another interesting note though: once you save an animation preset, it will be listed with its name under "Recent Animation Presets". The menu command ID for the most recent preset is "2460". However, I don't know how to get the name from the command ID (usually it's just the other way around ;)). If you could somehow get the name, you would know what the user typed in.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 12, 2021 Dec 12, 2021

Woww!

Thank you so much, I'll sure use that 1st workaround and try to make the 3rd workaround work, this is just amazing!

RedyMotion

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 12, 2021 Dec 12, 2021

For some reason, the alert(3) doesn't show up, as if it doesn't go into the for loop... Do you know why?

        // EFFECTS
        // =======
        presetPath = File(""+File($.fileName).path+"/Styles/!Styles ( IGNORE ME ).data"); // It's basically an empty preset, I changed extension from .ffx to .data
        thisComp.selectedLayers[0].applyPreset(presetPath); // Doing this so the "save an animation preset" file explorer opens at the right location

        alert(1);
        
        thisComp.selectedLayers[0].property("Effects").property("Styles").remove(); // Delete the useless .data "preset"

        alert(2);

        // Select all effects so the script can create a preset
        for (i = 1; i <= thisComp.selectedLayers[0].property("Effects").numProperties; i++) {
            thisComp.selectedLayers[0].property("Effects").property(i).selected = true;
}
        alert(3);
        // Save preset + Tell instructions
        alert("*DISCALIMER*\n\nThe script will open a window so you can save your style, make sure to save it to the location the window has opened to")
        app.executeCommand(3075);
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 12, 2021 Dec 12, 2021

Idk why and how, but I added that:

var myLayer = thisComp.selectedLayers[0]

 and replaced all the parts where it was written " thisComp.selectedLayers[0] " by "myLayer"

and it worked...

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Dec 12, 2021 Dec 12, 2021

Hm, not sure what caused this... However, I just spent a little bit of time and wrote something how I would to do it: https://pastebin.com/JCXSfrzv

 

I saved an ffx file with a simple slider and then created a binary string from it as RenderTom so wonderfully provided. See here: https://github.com/rendertom/PseudoEffect

(You can also just use the binary string from my code if you want to.)

 

Also when using applyPreset() you need to be aware that only the layer you want to apply the preset to has to be selected (all other layers have to be deselected beforehand and re-selected afterwards). I'm adding the preset to a dummy layer because all selected props would otherwise be invalidated and we couldn't re-select them afterwards which would defeat the possibility of saving the selected props. I hope this makes sense.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 12, 2021 Dec 12, 2021

Wow...

I can't thank you enough, definitely the most helpful person I've met on this app so far! 🙏

I have an other random question that has nothing to do with this, do you know how I could paste the what's inside of the clipboard? Like by by simulating the press of ctrl+v or with an other method

Just trying my luck 😂🤞

Thanks again,
Redy

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 12, 2021 Dec 12, 2021

Wait you mentionned it higher, never mind!

What was that script press the enter key tho?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Dec 12, 2021 Dec 12, 2021

Hey,

 

happy to help! 🙂

 

Yeah, you can just paste something using the AE command:

 

app.executeCommand(20)

 

Concerning the enter keypress: See the code below. In this example, I actually did it using a Visual Basic Script for Windows and not AutoIt as I mentioned before since it is easier that way. I actually stole that part from someone here on the forums to be honest (not sure where from exactly anymore though...). On Mac, the keypress is simulated via AppleScript. In the example, keypresses for enter and minus are available, although this could potentially be expanded to all kinds of other keypresses.

 

Just pass the keypress into the function as an argument (either "Enter" or "Minus") and it should work. After the simKeypress() function has been called, you can call endKeypress() which will delete the Visual Basic Script file on Windows which was just meant to be created temporarily.

 

// FUNCTION: Simulate Keypress
var keypressFile;
function simKeypress(keyStroke){
        var execStr = "";
        if (keyStroke == "Enter"){
                if (thisOS == "Windows"){
                        execStr = "ENTER";
                } else {
                        execStr = "key code 36 #return";
                }
        } else if (keyStroke == "Minus"){
                if (thisOS == "Windows"){
                        execStr = "-";
                } else {
                        execStr = "key code 78";
                }
        }
        if (thisOS == "Windows"){
                keypressFile = new File(File('~/Documents/Keypress.vbs'));
                var keypressStr = 'Set WshShell = WScript.CreateObject("WScript.Shell")\'' + '\r' +
                                  'WshShell.SendKeys "{' + execStr + '}"';
                keypressFile.open('w');
                keypressFile.write(keypressStr);
                keypressFile.close();
                if (keypressFile.exists){
                        keypressFile.execute();
                }
        } else if (thisOS == "Mac"){
                system.callSystem('osascript -e \'   tell application "System Events" to ' + execStr + '   \'');
        }
}
// FUNCTION: End Keypress
function endKeypress(){
        if (thisOS == "Windows"){
                if (keypressFile && keypressFile.exists){
                        keypressFile.remove();
                }
                keypressFile = undefined;
        }
}

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Dec 12, 2021 Dec 12, 2021

Oops, I haven't made my "thisOS" variable clear in the example. That's how I defined it:

// Determine Operating System
var thisOS;
if ($.os.indexOf("Windows") != -1){
        thisOS = "Windows";
} else {
        thisOS = "Mac";
}
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Dec 12, 2021 Dec 12, 2021

Oh well, and just one more thing I just noticed. In my previous post where I sent you my savePreset() function, I created the ffx from AE 2022 and converted it to the binary string. However, ffx files unfortunately aren't backwards-compatible, so you want to save them from an older AE version so you could use them also in other AE versions. I just created the same ffx and binary string in AE 2018 (the oldest version that I have installed). See here: https://pastebin.com/PY1XdPuS

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Dec 12, 2021 Dec 12, 2021

...the corrections don't end.^^ In the link I just sent you, the last line, of course, also has to pass the folder like this:

var dummy = createResourceFile("Dummy.ffx", dummy_bin, defaultPresetPath);
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 12, 2021 Dec 12, 2021

That's so smart!!!

Thanks, thanks, thanks and thanks!

I have small a issue tho:

I can't do the action "simKeypress("Enter");" when the file explorer to save the preset is opened, it just does it after I closed it

any fixes?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Dec 13, 2021 Dec 13, 2021

If you write:

app.executeCommand(3075);
simKeypress("Enter");
endKeypress();

 

...the keypress is simulated after the dialog, meaning after the dialog has been closed. However, you can also write:

simKeypress("Enter");
app.executeCommand(3075);
endKeypress();

 

That way the VBS file will be executed before the app.executeCommand(3075), however since the keypress will be executed independent of AE and it takes a little bit until the file is actually executed, it should happen at the same time as the file browser opens. I just tested this code successfully and the dialog will be clicked way automatically. However, in rare instances I found that the keypress doesn't work (less than 1% of cases). But since this is quite hacky, it's not guaranteed to always work and I'm not sure whether it works for everyone on every machine to honest.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 13, 2021 Dec 13, 2021

Thanks, I added

WSH.Sleep = 500

In the .vbs just so it really lets the time to after effects to open the file explorer, but that only works for windows ( vbs  )

is there a way to do that in the mac part? ( this is my last question, thank you so much for all the help )

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Dec 14, 2021 Dec 14, 2021

Hey, that's a really good idea - I haven't thought of that! 🙂

You might not even need "500", maybe it can be less so that you won't see the opening window for that long. Havent't tested it yet, though.

About the Mac thing: Hmm, so there's the "delay" command in AppleScript. However, I don't have a Mac here right now, so I can't test it. I assume it should be something like this, though:

system.callSystem('osascript -e  \'delay 0.1  \'  -e  \'tell application "System Events" to ' + execStr + '   \'');

 

If no one else can help us out here, I'll have a Mac here in maybe a week, and I'm going to test it out then.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 14, 2021 Dec 14, 2021
LATEST

I'll be able to test it soon - tysm!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines