[After Effects] 割と初めてまともにAEでスクリプト書いた

もう8月も半ばですね。とんでもなく早いですね。
5月に正式に回に移ってから3ヶ月半も経ちました。嘘だろ。
少年老い易く、、なんて言いますが、おっさんはもっと老い易い。世知辛い。

さて、タイトルの通り以外の何者でもないのですが、先日の仕事で必要になってAE用にスクリプトを書きました。
AEのスクリプトなんて、大昔、確かAE6.5(CSじゃないやつね)とかでスクリプトが付いた直後ぐらいにちょろっといじったことがあった気はしますが、まともに仕事で使ったのは初めてです。
よく考えたらJavaScriptも2000年代前半とかに仕事でちょいちょい使ったことがあったぐらいで、ほとんど触ったことがありませんでした。

そんな感じの状態ながら、まぁなんとかなるだろ、ぐらいのノリで触ってたのですが、思った以上に苦戦しました。

その際に気になったことなど、作業中のメモをこっちにも軽くメモっておきたいと思います。


今回作ったツールは、某案件で作成したAEPとそのフッテージをまとめて全部アーカイブするためのツールです。つまりファイル収集を全カット分一気に実行するツールです。
多分こういうのはその辺に落ちてるんじゃないかと思って軽く探したんですが、見つからなかったのとせっかくなら書いてみたいと思ってたので自作してみました。

※AEでのスクリプティングもJavaScriptもどっちも初心者なので何か間違ってる箇所とかあれば優しくご指摘いただけるとスーパーありがたいです。先輩方、よろしくお願いします。

というわけで以下つらつらと。

・AEPファイルの中身にはapp.projectを通してアクセス。
→これはAEというよりもAdobeのスクリプト全般に対して言えることなんでしょうかね。ESTKからスクリプトを実行する際はアプリケーションが明確になっていないと実行できません。AEからESTKを立ち上げた場合は問題ないのですが、単独でESTKを立ち上げた場合はAEとの接続が出来てないので要注意です。
#pragmaみたいな感じで設定する方法ありそうな気もするんですが、どうなんでしょう?

・プロジェクトの全てのアイテムを取得
app.project.items
 →フォルダやcompやfootageなどの区別無く全部返ってくる。階層も全部無視。とにかく全部返ってくる。

・プロジェクトの中のアイテムの数
app.project.items.length
app.project.numItems
 →どちらも同じ。と、この辺で気づき始めたんですが、JavaScriptってメソッドとして実装せずにプロパティとして持たせるほうが一般的なんですかね?
  nameぐらいはプロパティで良いんですが、lengthってなんとなくメソッドの方がしっくり来る気がするんですが、、気のせいですかね?

・ESTKのコンソールに文字列を出力
$.writeln(str)
 →JavaScriptってprintがない(というかガチでプリントしちゃう。プリンタから。)のでalert使いまくってた過去を思い出して懐かしくなりました。余談でした。

・app.project.items[i]としてアイテムを取る際、iは1から。
 →0からだとエラー返ってきちゃうので要注意。

・フッテージのパスは、String(app.project.items[i].file)として、fileオブジェクトをStringにキャストしてやると取れた。
 →app.project.items[i].file.toString()でも大丈夫なはず。書き終わってから気づいた。。

・AEではファイルパスが /c/hoge/test.txt みたいに、スラッシュでスタートされる。ドライブレターにコロンもつかない。
 →なかなか見慣れない、なんちゃってUNIXみたいなパス表記ですね。

・ファイルの有無はFile.exitsを使用する。
 var f = new File(file_path);
if (!f.exists) {
//ファイル無かったときの処理…
}
 みたいな感じで書ける。

・Fileオブジェクトに存在しないドライブのパスを突っ込むと、/c/からのスタートになる。(例えば/k/hoge/test.txt、みたいなパスをつっこんだもののKドライブがないと、/c/k/hoge/test.txt、という感じになる。)
 →テストしてる時に気づいたので一応。

・footageの連番、静止画の判断方法
 →app.project.items[i].frameRate == 0 なら静止画、そうでなければ連番。
  →と思ったんですが、他に方法ねーのかな?と思ったらこちらで非常に丁寧にまとめられていました。感謝!

・連番、静止画ではreplaceの際に使用するmethodが違うので要注意。
  →app.project.items[i].replace(new_path)とすると静止画、app.project.items[i].replaceWithSequence(new_path, true)とすると連番。(第2引数はアルファベット順にするとかどうとかなので理由が無い限りtrueでOKのはず。)
   →第2引数をtrueにすると、例えばパス分けされた素材が同じフォルダに何種類も入っている際、ひとつなぎになって読まれてしまうので、デフォルトはflaseの方が良いかも。

・array.slice()が便利。Pythonみたいにマイナスインデックスも使える。
 →slice(-1)などとするとそのインデックスの値だけ取得出来、slice(1, 5)とすれば、arrayの[1]から[4]までが返ってくる。
  例えば、[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].slice(1, 5)とすれば[1,2,3,4]が返ってくるし、[0, 1, 2, 3].slice(-1)なら[3]が返ってくる。
  注意点として、sliceで取得した値は全て配列で返ってくるので、単一要素だけ取り出したい場合はslice(-1)[0]とかにしないとだめ。

・正規表現はRegExpオブジェクトをnewするか、Perlとかみたいにスラッシュで区切る書式を使用する。
 →詳しくはGoogle先生に聞きましょう。
 →ドライブの変更程度なら、RegExp使わずともstringで
  app.project.items[1].file.toString().replace(“/z/”, “/w/”);
  って感じでもOKです。

・JavaScriptの正規表現では貪欲なマッチングがデフォルトになっている。
 →キャンセルするには \w+? の様に?をつけてやる必要がある。
  参考リンク

・javascriptでの桁あわせが見つけられませんでした。
 →なので無理やり以下のように対処しました、、けど、、大丈夫かこれ?www
  (“0000000000” + num).slice(-digits)
 num = 15, digits=4だとすると、0015と返ってくる。
 つまり”000000000015″の下4桁だけ返す感じ。
 とんでもなく間抜けくさいけど一応出来てたwww

・app.project.itemsのFootage Objectのファイルパスを取る際、エンコードされた文字列が返ってくる。
 →これを読める形に直すには、decodeURI(str)を使用すると良い模様。
  参考リンク

・AEのFootageオブジェクト、連番ファイルかどうかを判断するには画像の拡張子ぐらいからしか行えませんでした。無理やりなんとかしましたが、、どうやるのが本来はスマートなんですかね?

・AEからフォルダを作成するには、以下みたいな感じでいけました。
var dir = new Folder(path);
dir.create();
 →とても簡単です。ちなみにPythonで言うと、os.makedirs(path)と同じ感じで、そこのパスまでのディレクトリを全部作ってしまうので、使い方に注意が必要かもしれません。

・現段階ではこのスクリプトリファレンスが最新みたいでした。CC版も探したのですが、見つかりませんでした。

とこんな感じでしょうか。
いつもの事ながらつらつらとまとめる気もなく書いてみました。

JavaScriptでまともなツール作るの初めてだったんですが、なんとも自由度の高い言語ですね。
普段一番触ってるのは間違いなくPythonなんですが、Pythonの書式を制限して見た目を美しく保つ、みたいな思想は一切感じられませんでした。
何をやるにも何通りも書き方があって、恐ろしくふにゃふにゃした言語という印象です。決して悪い意味ではないんですが。

今回あれこれ書いてみてちょっとだけ勘所がつかめたので、また機会あればちょいちょいツール書きたいなと思いました。

じゃあの。

コメントを残す

メールアドレスが公開されることはありません。