Copy link to clipboard
Copied
Hello folks, I need your help!
I use the Convert Audio to Keyframes command in my script, but I've stumbled upon a strange and annoying thing. The corresponding command ID is changing unpredictably from one AE version to another. The most disappointing thing is that it changes even from one minor version to another. I've tested it in every AE version I could get my hands on. Also, I added IDs from the command IDs lists gathered by David Torno (thanks for your tremendous work David!).
OS | AE Version | Command ID |
---|---|---|
Win 7 SP1 64-bit | CS6 (11.0.0.378) | 5015 |
Win 7 SP1 64-bit | CC (12.1.0.168) | 5014 |
Mac OS 10.8.5 64-bit | CC (12.2.1x5) | 5014 |
Mac OS 10.9.5 64-bit | CC 2014 (13.0x214) | 5015 |
Win 7 SP1 64-bit | CC 2014 (13.2.0.49) | 5015 |
Mac (?) | CC 2015 (13.5.0.347) | 5018 |
Win 7 SP1 64-bit | CC 2015 (13.7.1.6) | 5021 |
Mac OS 10.9.5 64-bit | CC 2015 (13.7.2x3) | 5015 |
It looks like starting from CC 2015 it begins to change unpredictably from one minor version to another, which really freaks me out.
I could run the command this way:
app.executeCommand(app.findMenuCommandId("Convert Audio to Keyframes"))
but it's not an option since I need my script to work with other language versions of AE.
The only possible solution I see is to gather the full list (as full as possible) of AE versions and the command IDs. This is why I ask for your help.
Could you run this code in your Script Editor to get the command ID (it will be shown in the JavaScript Console):
app.findMenuCommandId("Convert Audio to Keyframes")
Then please post your OS version, AE version and the command ID.
I need your help badly, otherwise I'm stuck!
Thank you!
1 Correct answer
Since the ID changes so frequently, I find it easier to collect the name in all languages than collecting all IDs.
EN: Convert Audio to Keyframes
DE: | Audio in Keyframes konvertieren |
FR: | Convertir les données audio en images clés |
IT: | Converti audio in fotogrammi chiave |
ES: | Convertir audio en fotogramas clave |
JA: | オーディオをキーフレームに変換 |
KO: | 오디오를 키프레임으로 변환 |
RU: Конвертировать аудио в ключевых кадров |
Now you can call app.findMenuCommandId() on each of them until one of them returns a val
...Copy link to clipboard
Copied
AE version | Command ID |
---|---|
CC 2017 (14.0.1.5) | 5028 |
CC 2015.3 (13.8.1.38) | 2057 |
CC 2015 (13.5.0.347) | 5022 |
CC 2014.2 (13.2.0.49) | 5019 |
All for Win 7 SP1 64-bit.
That's kinda weird..
Copy link to clipboard
Copied
Thanks for checking it on all those versions
That's insane!
Copy link to clipboard
Copied
Since the ID changes so frequently, I find it easier to collect the name in all languages than collecting all IDs.
EN: Convert Audio to Keyframes
DE: | Audio in Keyframes konvertieren |
FR: | Convertir les données audio en images clés |
IT: | Converti audio in fotogrammi chiave |
ES: | Convertir audio en fotogramas clave |
JA: | オーディオをキーフレームに変換 |
KO: | 오디오를 키프레임으로 변환 |
RU: Конвертировать аудио в ключевых кадров |
Now you can call app.findMenuCommandId() on each of them until one of them returns a valid ID. This way, you don't have to again look for new IDs when the next Ae version will be released.
Copy link to clipboard
Copied
Thank you Mathias for your fast and very helpful response. Actually, I thought about using this approach, but I gave up on it because I can't know for sure what is the language of the current version of AE. I don't know how I missed the fact that I can iterate through all languages until one of them returns a valid ID. Thanks for pointing that out!
I have to ask one more thing. Where did you get this menu command name translated into all those languages?
I'm asking because I found the way to get all of them and it turned out that in Russian it is called differently ("Преобразовать аудио в ключевые кадры" instead of "Конвертировать аудио в ключевых кадров"). So I thought is it possible that this menu item can be called differently in different AE versions? That would be even more insane 😃
For those who might need it, you can get a specific menu command name by finding it in Adobe documentation:
https://helpx.adobe.com/after-effects/using/assorted-animation-tools.html
Then add a language code to the link like this:
https://helpx.adobe.com/de/after-effects/using/assorted-animation-tools.html
Btw, you can see the full list of all available languages on 404 error page by providing a missing language code. For example xx: https://helpx.adobe.com/xx/after-effects/using/assorted-animation-tools.html
Then hover an 'Adobe Support' link in any language and you'll see an available language code.
Copy link to clipboard
Copied
One more thing to be aware of - Capitalization Matters!
This menu command is called Animation > Keyframe Assistant > Convert Audio To Keyframes in the Adobe documentation https://helpx.adobe.com/after-effects/using/assorted-animation-tools.html
But app.findMenuCommandId("Convert Audio To Keyframes") won't work, it returns 0.
Only the right spelling with 'to' instead of 'To' works app.findMenuCommandId("Convert Audio to Keyframes").
So you can't be sure for 100% that this approach gives you a predictable result in all languages until you check all of them =\
Copy link to clipboard
Copied
About your last remark: The string to be used for app.findMenuCommandId() is the one that appears in the GUI menu inside After Effects, not the one in the docs!
Xavier
Copy link to clipboard
Copied
Yes, I understand that. There is no easy way to switch a UI language in AE and even if I could do that, I couldn't copy a menu item name. So the only way is to copy-paste those names from docs and hope that Adobe spelled them correctly (like they didn't with English docs unfortunately). If there are any other ways to make it more predictable and reliable, please let me know.
Copy link to clipboard
Copied
Agreed that this menu command stuff is very very cumbersome, especially for scripts that are meant to be shared (which script isnt?).
There are so many post on this topic. Incredible.
I wish (for sure i'm not the only one) app.findMenuCommandId(str_command) could accept english independatnly of the app language, a bit like thisLayer.transform.position works in any language.
May someone with great power read this.
Copy link to clipboard
Copied
>I wish (for sure i'm not the only one) app.findMenuCommandId(str_command) could accept english independatnly of the app language
or, give all the menu commands match names...
Dan
Copy link to clipboard
Copied
True Dan.
The "idea" for english is that the english dictionnary is already available in all languages (given that ae can be forced to use english language), hence it should be very easy to implement a findMenuCommandId() function that accepts english input, say app.findMenuCommandId(text, useEnglish), useEnglish is false: use current language dict, useEngllish is true, use the english dict. It could be there tomorrow without effort.
Xavier
Edit: but agreed that match names would be a lot neater.
Copy link to clipboard
Copied
Plus one to the request above. That would be really handy instead of remembering all those ID numbers.
Copy link to clipboard
Copied
I got those names directly from an Adobe developer. But the trick with using the documentation in different languages is very nice (although not 100% reliable).
Copy link to clipboard
Copied
I use those names in my Auto Lip-Sync since years and don't get any complains, so they should be correct.
Copy link to clipboard
Copied
Actually I'm a native Russian speaker and I see that the menu name spelled wrong in your example. On the other hand the name in the Adobe docs seems correct to me. I will try to find someone to ask how it is called in UI in Russian.
It might be that you have not so many clients from Russia. Also, AE users from Russia often prefer English version of the software, especially professional ones. That might be the reason why you have no complaints on this matter from Russian users. However, all the names in other languages which you gave above correspond to those presented in the documentation. Actually, googling one of them (in Korean) allowed me to find this trick 😃
I found two more languages in those docs, it's Portuguese / Brazil (br) and Chinese (cn). The docs in Italian are also there, but there is no hints at it on the 404 page.
One more huge benefit of using this technique is that a script can process errors and take actions accordingly if there are any. If none of available translations fits, the script can send a message to a user and suggest him to switch to the English version or contact support.
Using IDs directly on the other hand gives no chance to know if anything goes wrong. AE just run a wrong menu command which leads to an unpredictable action. That's it.
Copy link to clipboard
Copied
Agreed that matchnames would be nice, but command ID's were never meant to be a user feature and was mostly an in house testing setup that got left in like a few other functions. The PNG saving function being another one that is not supported officially. Since new features are added to AE all the time they can easily bump an enumerated value for the new addition. Like blendingmodes and such. This is why each version of AE can vary as you have found out Nemo. So it has always been a gamble to use command ID's in public scripts. They do come in handy for tasks that have not been implemented into ExtendScript natively, but can not be relied upon as a final solution unfortunately.
Copy link to clipboard
Copied
While on the same subject... does the menu command ID of "Convert Expressions to Keyframes" also this erratic? Or is it safer to use it (at least right now)? I didn't check it yet but if someone has the IDs of this command for the different versions I will be delighted!
Thanks in advance
Roy.
Copy link to clipboard
Copied
Finally I came up with the following solution.
Declaring the menu command names in various languages
sv.commandNames = [];
sv.commandNames["Convert Audio to Keyframes"] = [
"Convert Audio to Keyframes",
"Audio in Keyframes konvertieren",
"Convertir les données audio en images clés",
"Convertir audio en fotogramas clave",
"Converti audio in fotogrammi chiave",
"Converter áudio em quadros-chave",
"Преобразовать аудио в ключевые кадры",
"オーディオをキーフレームに変換",
"오디오를 키프레임으로 변환",
"将音频转换为关键帧",
];
sv.commandNames["General..."] = [
"General...",
"Allgemein...",
"Général...",
"General...",
"Generali...",
"Geral...",
"Общие...",
"一般設定...",
"일반...",
"常规...",
];
sv.commandNames["Close"] = [
"Close",
];
And so on... If you don't know a menu command name in other languages and it's not so crucial to executing your script, you may provide an English name only. At least it will work well in English versions.
Actually it was a kind of an investigation to get all of those names =). I was looking for screenshots of AE interface in other languages, because it's not easy to comprehend where a description text stops and starts a menu command in a hieroglyphic language help.
Still, I'm not sure if it will work well, because I saw numbers next to menu command names in some language versions.
Here goes the function, which receives a name in English and return an ID if found any.
// Get a Menu Command ID by Name (Multilingual)
function getCommandId (name, showAlert) {
showAlert = typeof showAlert !== 'undefined' ? showAlert : false;
var id = 0;
var namesArr = sv.commandNames[name];
for ( var i = 0; i < namesArr.length; i++ ) {
if ( id = app.findMenuCommandId(namesArr) )
return id;
}
if ( showAlert == true )
alert("Menu command ID is not defined. Please switch to the English version of After Effects or contact support: " + sv.emailSupport, "Multilingual Support Error", true);
return false;
}
If getting a menu command ID is crucial for your purposes, you can stop the script.
Also, you can set the second parameter to true to show an alert to a user which explains what's going on.
if ( commandId = getCommandId("Convert Audio to Keyframes", true) )
app.executeCommand(commandId);
else if ( ! commandId )
return "Multilingual Support Error"; // Stops The Script
If you don't care about stopping the script in case there is no ID found, I just run it like that.
if ( commandId = getCommandId("General...") )
app.executeCommand(commandId);