ExtendScriptで困ったことのメモ(Adobe)
ExtendScriptで困ったことのメモ
概要
AfterEffectsをはじめとしてAdobe製品では、ExtendScriptというスクリプト言語を利用することができます。
これによって、GUIを作成したり作業を自動化したりといった色々な便利なことができる。。。はずですが、公式/非公式問わず情報が少なかったり、スクリプト自体の更新がされていなかったり、そもそも使い勝手が悪かったりと色々と困ることが多いです。
今回は、ExtendScriptで困ったことのメモをつらつらとまとめていこうと思います。
ExtendScriptとは
ExtendScriptはAdobeアプリケーション共通で使えるスクリプト言語です。
JavaScriptを拡張して作成された言語なのですが、元になっているJavaScriptの仕様はECMAScript 3、なんと1999に策定されたものだそうです。
また独自実装などもあり現代のJavaScriptとは異なる部分が多々あるため、似て非なるものと考えた方がよさそうです。
デバッグについて
ExtendScriptはコンソールが使えない
ExtendScriptでは、コンソールが使えません。
console.log("Hello World");
// エラーが発生する。
お手軽に変数の中身を確認するにはalertを使うしかありません。
alert("Hello World");
ExtendScriptでリモートデバッグを行う
変数の中身を確認するのにalertを使うしかないと言いましたが、流石にこれでは使い勝手が悪いです。
10行以上のスクリプトを書く必要がでた場合は、以下の記事を参考にデバッグを行える環境を構築した方がいいです。
ドキュメントが充実してないので、書き方がわからない場合に変数の中身を見ながらそれっぽいプロパティを自力で探すなど、しょうもない泥臭い作業も多いです。
そのことを考えると、一定以上の規模のスクリプトを書く場合はデバッグ環境は必須です。
ExtendScriptの文法
for-each文が使えない
ExtendScriptでは、for-each文が使えません。
代わりにfor文を使う必要があります。
const,letが使えない
ExtendScriptでは、const,letが使えません。
全部varで宣言する必要があります。
Adobe独自の配列は1から始まる
通常の配列は0から始まりますが、Adobe独自実装オブジェクトの配列は1から始まります。
for文などで0から開始させるとエラーが発生することがあるので、その場合は1から開始する必要があります。
// ioはファイルパス。既に作成されている前提とする。
var importProject = app.project.importFile(io);
// エラーが発生する。
importProject.item(0);
importProject.item(1);
importを使えない
ExtendScriptでは、importを使うことができません。
代わりに #include 構文を使う必要があります。
import { hoge } from "./hoge";
// エラーが発生する。
#include "./hoge";
ちなみに、importと同じように動的に #include する方法はないみたいなので、相対パスと絶対パスを使い分けて頑張りましょう。
$ オブジェクトという謎の存在
ExtendScriptでは、グローバルオブジェクトとして $ オブジェクトが存在します。
このオブジェクトには、アプリケーションの情報やスクリプトの実行環境などが格納されているようです。
何が取れて何が取れないかは、試してみるなりデバッグするなりで確認するしかないので頑張りましょう。
alert($.os);
$.getenv("PATH");
プロパティの取得は文字列で行う
ExtendScript 独自のオブジェクトでは、プロパティの取得は文字列で行う必要があります。
更に、特定のプロパティを取得するのにどのような文字列が必要かはドキュメントにも載っていないので、試行錯誤が必要です。
// layer はコンポジションのレイヤー。既に作成されている前提とする。
effect = layer.Effects.addProperty("ADBE Linear Color Key2");
effect.property("ADBE Linear Color Key2-0001").setValue([0, 0, 0]);
コード例の「ADBE Linear Color Key2」などの文字列は頑張って検索しましょう。
普通定数クラスとかありません?
どうしても見つからない場合は、GUIで操作を行ってスクリプトでプロパティを持つオブジェクトを取得、デバッグで中身を確認して必要な文字列を取得するという迂遠な方法もあります。
再帰関数が使えない
ExtendScriptでは、再帰関数が使えない...はずです。
どこにも情報がないので確信をもって言えませんが、再帰的な処理を記述すると構文エラーが発生します。
関数の再帰呼び出しを行う代わりに配列をstackとして使うなどの工夫が必要です。
試してみたら使えました。使えるときと使えないときがあります(?)
デフォルト引数が使えない
ExtendScriptでは、デフォルト引数が使えません。
関数の引数に値が渡されなかった場合、undefinedが渡されるので、その場合の処理を記述する必要があります。
function hoge(arg) {
if (arg === undefined) {
arg = 0;
}
alert(arg);
}
hoge();
その他
スクリプトの実行場所
スクリプトの起動方法によって、スクリプトの実行場所が変わります。
- ファイル> スクリプト > スクリプトファイルを実行
指定した場所での実行 - ファイル> スクリプト > スクリプトファイルをインストール
Program Filesのスクリプトフォルダにコピーされて実行
これのせいで、スクリプト内での相対パスの扱いが難しくなります。
includeは絶対パスのみで指定する、スクリプトのインストールは行わない などの対策が必要です。
jsxはBOM付きUTF-8で保存しよう
ExtendScriptは、BOM付きUTF-8で保存しないと文字化けやエラーが発生することがあります。
コメント部分を削除したらエラーが解消する...という怪現象に悩まされたこともありますが、BOM付きUTF-8で保存することで無事解決しました。
特に身に覚えのない構文エラーが発生した場合は、一度保存形式を確認してみるといいかもしれません。
ドキュメントが...ある!
Adobeの公式ドキュメントには、ExtendScriptの情報があまり載っていません。
しかし、なぜか有志の方が作成されたまとまったドキュメントが存在するので、感謝しつつ参考にしましょう。
AfterEffects以外のアプリケーションの場合はわからないので、各自調べてください。
エラーが不親切
ExtendScriptでエラーが発生した場合、エラー行が全然違うなどエラーの内容が不親切なことが往々にしてあります。
特にExtendScript独特の構文エラーの場合はlinterも注意してくれるものがないので、エラーが発生した場合は一つ一つ確認していくしかありません。
自分がやる解決方法としては include やコードのコメントアウトでエラー原因の切り分けを行っていくことが多いのですが、他にもいい方法があれば教えてください。
chatgptを使おう
普通のプログラミングであれば、検索してわかることをChatGPTに聞いてコピペをするのはあまり褒められたことではないという風潮があります。
が、ExtendScriptの場合は情報が少ないので、ちょっと調べて出なければChatGPTにガンガン頼ってコピペしていくべきだと思います。
一回で出なくても何回か試していると正しい出力が得られることがあるので祈りながら頑張りましょう。
まとめ
ギョームで少しだけExtendScriptを触る必要があったのでその供養として書いてみました。
あまりまとまった内容ではないですが、あるあるを感じてもらったり入門者の助けになれば憤死しそうになりながらもExtendScriptに取り掛かった甲斐があったかなと思います。
2024年にもなってこんなものに入門する必要はないです。
Adobeは後続の言語を整備するなりドキュメントをちゃんと作るなりちゃんと頑張ってください
Discussion