96年にはPhotoshopすら起動できなかった、この俺が。

今年、久々にアニメの撮影監督をやる案件があり、眠っていた「xtools」を復活させ、プログラム内部のメンテを初夏には終わらせたい目論みでいます。「xtools」とは自己開発のアニメーション制作補助ツールで、特に撮影業務の一式を補助するツールです。対話式の簡便なUIですが、After EffectsのコンポジションのオートビルドやQTの内容確認(もちろんスペック上の、です)など、手作業でやると煩わしい部分を代行してくれます。

言語は、AppleScript、JavaScript、ShellScriptなど、各種を混合して使っています。モジュールは共用できるようにライブラリ化し、ソフトウェアアップデートツールで、自動更新できる仕組みを作っています。また、データベースと連携機能を組み込んであり、ツールを使うと作業者も管理者も手間を軽減できる仕組みになっています。

現在の私は、アニメ業界の撮影業務とは違った作業を数多く引き受けており、xtoolsも大幅な機能拡張の時期を迎えています。また、「撮影」と言うカテゴリには当てはまらない、新しいアニメーション技法での各作業カテゴリもxtoolsに統合したい考えもあり、まずは春に旧来ツール群のプログラム内部面の大掃除を敢行する予定です。

「CBX」というコンポジションオートビルドのツールは、「素材の内容確認」「タイムシートの解析」「レイヤー配置の解析」などをおこなうので、ルーチンが複雑で大規模となり、メンテにも時間がかかります。加えて、「動く背景」素材(3D素材とは別に)に対応するなど、この10年で拡張を重ねた痕跡がメンテの障害になっていて、気が重くて放置していたのですが、そろそろ腹を括って「大メンテ」をしなければなりません。xtoolsは仕様をまとめながらコードを書いたので、つぎはぎ・増設の箇所が汚いのです。

ただ、xtoolsがあるのとないのでは、作業効率に大幅な開きが出ますし、作業事故の抑制効果も強いので、面倒で大変でも汚いコードを書き直してこまめに奇麗にしていこうと思います。それに現在は「撮ま」があって、撮影のベース部分をしっかりと固められるので、「撮ま」準拠のプログラムへと手直しする目的もあるのです。

プログラムって、アニメ業界だと今でも特殊な能力っぽく扱われますが、結局はプログラムを「やるかやらないか」だけだと思います。私が生き証人のようなもので、1996年春の初心者の頃は、同じ作業場にいた清積さん(ねこまたやさん)に頼らなければ「Macも起動できなければ、Photoshopを立ち上げる事もできなかった」のです。

96年にはPhotoshopすら起動できなかった、この俺が‥‥なのです。

プログラムは理数系の学校で授業を受けなければできない‥‥なんて、単なる思い込み、大ウソなのです。コンピュータがあれば、今日からでも始められて、身に付くものです。初めての頃は全角で「.PCT」なんて拡張子を付けてたコンピュータの右も左も解らない人間でも、プログラムを習得する事によって、自動でフォルダの内容を分析してAfter Effectsに読み込んでレイヤー配置とタイムシートを適用するプログラムが書けるようになるのです。プログラムを習得する事は、コンピュータを理解する事でもあるので、畳み掛けるようにコンピュータ全般の知識が備わっていきます。

私の考える現場は、プログラムが出来る人間が常駐しているのが「デフォルト」です。誰かが作ったソフトウェアに依存するばかりで、自分らの現場にツールを自作できる能力を持たないと、色んなものを諦めなければならないからです。xtoolsを作っていた時は苦難の連続でしたが、今では作って良かったと実感しています。ツールそのものもそうですが、「コンピュータで何ができるか」を遠く深く見通せるようになったのは、得難い知識と経験です。

googleで「フリーソフト ファイル 名前変更」なんて検索せずに、自分で名前変更ソフトを作ってみれば良いのです。「フリーソフトがあるのなら、それを使えば良いじゃん」とか思うかも知れませんが、それはすなわち、名前変更程度の事すらフリーソフトに頼らなければならない体質であり、さらにはその体質から永久に抜け出せない事でもあるのです。自分でプログラムが書けるようになると、ホントに、様々な場面で融通が利くようになりますヨ。

私は最初の頃、「を」の打ち方(=wo)が解らなくて、「を」を使わないメール本文を書いていたほどの無知な人間でした。お笑い草としかいいようがありませんが、事実です。そんな人間が、プログラムに触れて身につけていく事で、数年後にはShellコマンドを打ったり、メールサーバの仕組みが解るほどに知識を得られるのです。‥‥でもまあ、初心者の当時に、一緒に仕事をしていた清積さん(当時から作画とプログラムの両刀使い)が、私にとってのお手本になっていたのは大きいでしょうネ。


しかしまあ、そんなこんな、96年から換算すると、コンピュータと深く関わり始めて、今年でもう18〜19年か。そりゃあ、「コンピュータをもっと上手く使わなきゃ」と言うキモチになるのも仕方ない、「長い付き合い」になるんですネ。

PHPのライブラリ

PHPロゴ私はWebを構築する際、HTMLとPHPを用います。PHPはとっつきやすい言語で、JavaScriptに慣れている人なら、少々の読み替え・シフトで、すぐに使えるようになると思われます。「My Name Is Hisashi.」と「Mein Name Ist Hisashi.」くらい似ています。

私は今、「atDBx」という「アニメーション制作技術データベース」をチクチクと開発・構築し続けていますが、AppleScript用、JavaScript(ESTK)用のatDBxライブラリに続き、PHP用もそろそろ作る段階に差し掛かってきました。PHP用ライブラリを作らないと、データベース上の情報を人間の目でみる事ができないのです。情報データをWebブラウザで閲覧するには、それ相応の計画と工夫、そして実際のプログラムが必要です。

atDBxの前身であるatDBでも、PHPとの連携をおこなうライブラリは作っていたのですが、「どんなライブラリを作れば良いのか?」という基礎的な部分から手探りだったため、場当たり感満載でおよそ流用には適さない状態となってしまいました。とにかく「すぐに動作する」事が優先されたので、計画性に乏しく、無理に流用すると弊害も出そうでした。

何でもそうなんでしょうけど、最初から良い出来のものは作れませんよネ。「何が良いのか?」も解らないのですから、まずは手をつけて経験をつまないと、先には進めないのです。今のご時世は、最初から完璧なものを目指して(実は「完璧とは何か」すらわからないまま)、期待した結果を得られなければ即撤退‥‥という感じですが、技術はニジニジとした蓄積が必須なのですから、長丁場を覚悟しないとダメなんですよネ。何でも「自販機感覚」で手に入るわけじゃないのです。

今、私が取り組んでいるのは、各言語への「ライブラリの共通化」です。言語毎の文法はともかく、呼び出すサブルーチン・ファンクションくらいは共通化を図ろう‥‥というわけです。外部ファイルをそれぞれ用意しておいて、load script、readとeval、includeで各言語共通の命令系統を実現する仕組みです。以前は言語毎にバラバラだったので、コード記述時の効率が悪かったのです。

ライブラリ作成は、すなわちスクリプト作成・アプリ開発のお膳立てなので、ライブラリが存在しなければスクリプトを書き始める事もできないわけで、焦っていると「ライブラリなんて作らずに、すぐ作り始めちゃえ」となりがちです。‥‥でも、その行動が後になって、とんでもないフリクションロスやカロリー損失につながるのです。この辺の事は、同じような体験をした人なら解ってます‥‥よネ。

ライブラリを用意しておけば、実際のプログラムはスリムで明快な構造で作成できます。私のような映像制作の片手間でアプリを作る、プログラム専任ではない人間ほど、実はライブラリの構築が重要ではないか‥‥と思うのです。

After Effectsのゾンビ変数

ここのところ、作り続けていたグレーディングシステム用のパイプラインアプリですが、ほぼ完成し、あとはバグ潰しや機能改善をチクチクと地道に進めていくのみです。どんなに気を配ったつもりでも、実際に運用すれば、ポコポコと穴は出てくるものです。

After EffectsをAppleScriptで駆動する方法は、丁寧にAppleScriptとAfter Effects間でやり取りするのではなく、ESTKの命令文を作って丸投げする方法です。AppleScriptでPhotoshopを操作する際は、様々な返値を利用できるのですが、After Effectsの場合は貧相なexitCodeしか返ってきません。exitCodeは整数のみで、文字列などは扱えないので、スクリプトを実行した結果は実質受け取り不可能に等しいです。例えば、コンポジションのレイヤー名一覧を外部から取得する‥‥なんて事は通常の段取りではできないのです。

じゃあ、どうやってAfter Effectsをスクリプトで転がすかと言うと、ソケットや独自のクリップボードを使う‥‥などもありますが、環境の整備がそこそこ面倒なので、私は「変数を泳がす」方法で切り抜ける事が多いです。恐らく、一番安易で簡単です。

After Effectsの変数はゾンビのように、After Effectsが死ぬ(アプリ終了)まで生き続けるので、これを利用して、「ゾンビ変数に値を持たせたまま泳がせて」外部から上手く操作するわけです。

AppleScriptなど外部からは、変数・定数の中身ではなく、あくまで変数名だけで、転がしていきます。つまり‥‥
 
//Script 1
var _OUTPUT_COMP=app.projects.item(1);

‥‥として、変数に普通に代入しておけば、スクリプトを一旦終了しても、After Effectsが終了しないかぎりは、いきなり、
 
//Script 2
_OUTPUT_COMP.layer(1);

‥‥と書き始めても、undefinedになる事もなく、普通に取り扱い可能です。変数の中身は外界に取り出さずに、変数自体を外部からあっちゃこっちゃと転がして、上手くいった場合は0、そうでない場合は0以外をexitCodeに代入して、「result as integer = 0」でBooleanに変換し「結果報告だけを聞く」カタチにするのです。

いつまでも変数が死なないこの習性(?)を利用すれば、結構自由にAfter Effectsを「遠隔操作」で転がせるのですが、反面、変数が暴走(大袈裟ですけど)する危険性もあります。JavaScriptはDimとか宣言しなくても、おもむろに変数を使う事ができますが、ゆえに、既に前の前の前のスクリプトで使用済みの変数を、意識無しに使ってしまう可能性もあります。なので、ゾンビ変数を意識的に転がす際は、変数の名前のお約束を自分の中で定義してキッチリと運用する事が必須となります。


変数 i に10が代入されたところでスクリプト終了。


別のスクリプトで 変数 i をおもむろに使うと、既に10の値がセットされているので、結果は30。うひー。‥‥もちろん、変数 i の使用前歴がなければ「iは未定義」となってエラーです。スクリプト作成者の「管理能力」が問われる仕様ですネ。undefinedねらいの軽妙な文面でなく、しっかり変数の宣言と初期化をやっておかないと、後で弩壷にハマる仕様となっております。


‥‥ちなみに、エクスプレッションはそういう事(ソンビ)はないようで、1レイヤー1フレームごとに値はクリアされるみたいです。まあ、全てのエクスプレッション上の変数が生き残りまくってたら、わけがわかんなくなるでしょうからネ。

 

AppleScriptのcontinue

AppleScriptは、Macユーザかつスクリプトを常用している人間でないと使わないので、マイナーなアプリではありますが、その能力はあなどれません。私の自作ツールのほとんどはAppleScriptベースですが、業務の生産効率を左右するほどの影響力があります。

ただ、AppleScriptに何も不満がないわけではなく、こんなのがあるといいのにな‥‥と思う機能はそこそこあります。すごく基本的なところではループ文における「continue」です。

AppleScriptでも「continue」はあるのですが、「処理を続ける」という命令で、ループの処理を抜けて次回へスキップする内容ではありません。JavaScriptのcontinue相当はどうもAppleScriptには存在しないようです。breakはexitでイケるんですが。

要は、処理を抜ける構造が実現できれば良いので、以下のようにしてcontinueと同等の動作は実現できます。

set myList to {}
repeat with i in {1, 2, 0, 15, 2, 2.1, 2, 3}
    repeat 1 times--continue実現の為のrepeat
        set i to i as number
        if i = 2 then exit repeat
        set myList to myList & i
    end repeat
end repeat
return myList
--結果は{1, 0, 15, 2.1, 3} 
〜変数「i」が2の時はexit(break;)して、以降の処理はスキップします

入れ子のrepeat上でexitを使えば、exit以降の処理は実行されずにスキップされるので、continueと同じ働きをします。

しかしなんでしょ‥‥、行儀は悪いですよね。continue実現のために、repeatを本来とは違う目的で用いているのですから。

インクリメントとかは、単に「set i to i+1」とやればよいので、文字数の冗長さにガマンするだけで済むんですが、continue模倣の為だけにrepeatを使うのは、後になってコードを読み返した際に「何でここでrepeatを使ってるんだ?」と自分でも判らなくなりそうで、面倒でコワいです。

ちなみに‥‥。参考文中の「set i to i as number」を読んで、「なぜ、そんなクドいキャストを?」と思う人もおられるかもしれません。変数 i には当然Numberクラスが代入されていると思うわけですが、その変数 i を「is」「=」の比較演算子を用いて評価すると、実際はうまくいかないのです。AppleScriptにはありがちな動作ですネ。「item 2 of {1,2,3}(つまり2ですネ) 」は、2ではない‥‥という比較演算‥‥。でもまあ、もう16年もAppleScriptと付き合ってると、他の言語にはないクセもお馴染みなので、もはや混乱する事はあまりないです。AppleScriptが「何でヘソを曲げているのか」は大体察しがつきます。しかし、JavaScriptなどの他の言語に慣れた人がAppleScriptを使うと、「???」の連続かも知れませんネ(苦)。

翻訳中

まだ当分の間、AppleScriptにはお世話になる感じなので、現在JavaScriptの基本的なメソッドをAppleScriptに翻訳してライブラリ化しています。

AppleScriptは、「大文字を小文字に」とか「配列をスライスする」「文字列を置換する」などのよく使う操作を、一発で呼び出せません。プログラム文をガシガシ書きまくる際に、何かと面倒です。なので、.toLowerCaseや.slice、.replaceなどをサブルーチンとして作って、簡単に呼び出せる仕組みを実践中です。共通のコンポーネントとして1つのスクリプトファイル内に蓄積して、スクリプトを作る際に「load script」すれば管理も簡便です。

スクリプトのコンポーネントの扱いは、難しい事はありません。以下のようにとても簡単です。
 
file "MacHD:components:basic.scpt"〜スクリプトコンポーネントです
to myMethod_A (str)
return "こんにちは、" & str & "さん。"
end

file "MacHD:Documents:myScript.app"〜実際の自作アプリケーションです
set bsx to load script file "MacHD:components:basic.scpt"
display dialog bsx's myMethod_A ("太郎")
display dialog bsx's myMethod_A ("花子")
display dialog bsx's myMethod_A ("お集りのみな")

映像制作に使うJavaScriptのメソッドは、基本的なもので充分です。join、slice、replace、match、toUppserCaseやtoLowerCaseくらいでほとんどカバーできます。substringやsubstrなどは、sliceで代用可能でしょう。なので、AppleScriptに翻訳するメソッドもそれほど多くはならないと思います。‥‥ただ、RegExpの翻訳(というか、導入)はどうしようかな‥‥とは思っていますが。。。AppleScriptで正規表現が使えたら楽は楽‥‥ですけどネ。

メソッドは翻訳できるものの、文章表現そのものの特質までは操作できません。例えば、AppleScriptはundefinedやnullをfalseと同義に評価する機能はありませんから、制御構造はAppleScriptの流儀でおこなうほかありません。JavaScriptは未定義の変数やNaN、0なども「偽」として評価されるのが楽なんですけどね‥‥。
 
if value1 then set value2 to "OK"//AppleScriptはNG〜value1は定義していない変数なので

set value1 to 100
if value1 then set value2 to "OK"//AppleScriptはNG〜変数がbooleanではないので

set value1 to 100
set value1 to value1 is 100
if value1 then set value2 to "OK"//段取りが面倒ですが、これならOK〜誰でも読み解ける文体を重視してるんでしょうね


でもまあ、各言語の文章表現までは介入できなくても、メソッドを共通にするだけで、随分とスクリプト作成は楽になります。これもインフラの一環と言えますが、インフラを怠ると、後でとんでもない代償を払う事になりますから、根気よく地道に貯め込んでいく所存です。

ナゾの挙動

少し前から、AppleScriptの原因不明のトラブルに見舞われておりましたが、今日、ようやく「シッポ」を掴む事ができました。あくまで、シッポだけ、ですが。

トラブルとは、ドラッグ&ドロップのアプリケーションが正常に動作しない‥‥というもので、何が正常に動作しないかというと、ドロップした項目のうち数項目が無視される‥‥という内容のものです。

「またまた。単なるコード上のミスでしょ」とか思われるでしょうし、私も何度もコードを読み返しましたが、原因が掴めません。しょうがないので、「ドロップした項目数を確認する」ルーチンを組み込んでみたら、かろうじてナゾの挙動の「シッポ」を掴む事ができました。

シッポをもっとギュギュッと掴むために、ネズミ捕りのスクリプトを作ってみました。以下のコードでドロップレットを作って動作させてみたら、唖然とする結果が得られました。

on open theItems
    display dialog (length of theItems) as text
end open

変数theItemsには、ドロップした項目が代入されています。theItemsはリスト(一般的には配列と呼ばれるもの)なので、lengthで項目数を数える事ができます。

10個の項目(ファイルやフォルダ)をドロップすれば、当然、表示されるダイアログには「10」と出るはずです。しかし、トラブルが発生している環境で動作させると「7」とか「8」「9」などと数が減って表示されます。‥‥つまり、Finder操作でドロップした項目数が、on openで受け取っている項目数と食い違っているわけです。

ショック! 基盤を揺るがす大問題!

プログラムをやっている人なら、その重大さがお解りかと思います。ドロップした項目のうち、ランダムで受け渡されない項目が発生する‥‥なんて、ドロップレット作りの根幹に関わるトラブルです。

悩ましいのは、同じ動作を繰り返すと、やがて正常な数が表示される事です。10個ドロップして「8」と出た数秒後に、同じ動作でドロップすると今度は「10」と出る。ふえええ‥‥。

他でもMountain Lionは使ってるけど、こんな事、初めてだなあ‥‥と思い、自宅のMoutain Lion環境で試したら、何度やっても全く問題の無い正常な動作です。

自宅環境とトラブルが出る環境との違いは、思い当たるところ、マシンがiMac Late2012である事と、ドロップした項目がUSB3.0外付HDDの中にあるファイルだ‥‥という事くらいです。‥‥そんな事で、こげなトラブルが発生するか?

ファイルシステム上の何かがトラブっている? しかし、同じ場所に並んで同じ環境(iMac&USB3.0HDD)が2つありますが、2つとも同じトラブル見舞われているので、個体差ではないように思います。同じ構成のiMac環境で同じトラブルが出る。他のMac環境では発生しない。うーむ。具体的なような、そうでないような。

でもまあ、シッポを捕まえたので、逃がさないように手繰っていけば、トラブルの姿が見えてくるはずです。なんで、もうちょっとネバってみようと思います。

FinderのAppleScript

FinderをAppleScriptで操作する時は、そこそこ、注意というか、挙動を鑑みた扱い方が必要です。

例えば、ファイルのリネーム関連などは、「お手本通り」にやると、映像制作に必要な何千ファイルものリネームでは、全く使い物にならなかったりします。あまりにも動作が遅過ぎるのです。

Finderはファイルオブジェクトなど、いわゆる「item」にアクセスするとそのリターンまで、かなりの時間を要します。これは扱うファイルが多ければ多いほど顕著で、AppleScriptサイドが「タイムアップ」(応答が無いので、時間切れになる)するほどです。

tell app "Finder"
 set fileName to name of file "ファイルパス"
 set name of file "ファイルパス" to "_old_" & fileName
end


‥‥上記のような「お手本」的な段取りを、4,000ファイルも繰りかえしていたら、1時間以上かかる事すらあります。これを聞いて、「マシンの処理速度、遅えェ」とか言う人は、FinderやAppleScriptを知らない人。単にFinderの手続きがボトルネックになっているので、これはマシンがどんなに速くても解消される事はありません。

つまりは、Finderを通すと言う事は、「スーパーのレジ」を通す事に等しいので、4,000個の買い物をするのに、4,000回レジに並んでいたら、そりゃあ、遅くなるわ。‥‥という事ですネ。

Finderに通すのは、ゼロ回、もしくは数回に抑えて、ファイルのリネームに関しては「他で処理」するのが、お得なAppleScriptとFinderの使い方です。

例えば、4,000ファイルを収納したフォルダがあったとして、その中身を1つずつ、Finderで処理するのはNG中のNG。もしFinderを使うとしても、以下のような使い方で、「できるだけFinderにはアクセスしないように」工夫します。

set folderPath to "MacHD:TestFolder:"--フォルダのパス

tell app "Finder" to set nameList to name of files of folder folderPath--Finderへのアクセスはこの行のみ

repeat with currentName in nameList
 set newName to "_old_"&currentName
 do shell script "mv "&(quoted form of posix path of (folderPath&currentName)) & " " & (quoted form of posix path of (folderPath&newName))
end


こうするだけで、3600倍くらいの速さ(おおよそ)になります。

Finderへのアクセスは1度きり、名前のリストを取得する時だけです。後は、リピート文で、地道にシェル上でリネームしてます。やりかたはヒネりがなく、地道な内容ですが、Finderでのリネームよりは数千倍速いです。

ちなみに、文中の「posix path of」は、ファイルオブジェクトやエイリアスでなく単に文字列でも、Posix pathに変換してくれるので、重宝します。「quoted form of」は日本語や空白文字などを扱う時には必須です。

AppleScriptを使って、ファイルの操作を自動化しようと思った時、意外にFinderでの使い勝手が悪くて、もしかしたらAppleScript自体を諦めている人もいるかも知れません。たしかに、Finder経由でリネームなどしようものなら、「こんなの使えねえ」と思われても仕方なのですが、ちゃんと方法はあるのです。‥‥ご参考程度に、紹介しておきます。

QTのデュレーション取得スクリプト

色々弄っているうちに、「せっかくだからルーチンとして完成させてしまえ」と思い、前々回書いた、QuickTimeムービーのデュレーションを得るスクリプトをサブルーチンにしました。

以下。

tell application "QuickTime Player 7"
    my getQTDurationInfo(document 1, 8) 
end tell

--以下からサブルーチン

to getQTDurationInfo(_document, _offset)
   
    set _frameDuration to false
    try
        tell application "QuickTime Player 7"
            set _duration to duration of _document
            set _timeScale to time scale of _document
           
            repeat with t in tracks of _document
                if (type of t) as Unicode text is "vide" as Unicode text then
                    set _frameDuration to duration of frame 1 of t
                    exit repeat
                end if
            end repeat
        end tell
        if _frameDuration is false then return false
    on error msg
        display dialog msg--エラー時、いちいちdialogが出るのがイヤな場合はコメントアウト
        return false
    end try
   
    set _fps to (round (_timeScale / _frameDuration * 1000)) / 1000
    set _rfps to round _fps
    set _sec to _duration / _frameDuration / _rfps
   
    set _frameCount to (_sec * _rfps - _offset) as integer
    set _sec to _sec - (_offset / _rfps)
   
    return {movie_frame_count:_frameCount, movie_seconds:_frameCount div _rfps, movie_frames:_frameCount mod _rfps, movie_time_info:((_frameCount div _rfps) as Unicode text) & "+" & (characters 2 thru -1 of (((_frameCount mod _rfps) + 100) as Unicode text) as Unicode text), movie_time:(round (_sec * 100)) / 100, movie_framerate:_fps}
end getQTDurationInfo

上記ルーチンで、23.976, 24.0, 29.97NDF, 29.97DF, 30.0の5種類のフレームレートを試しましたが、全て期待した結果を返す事を確認しました。

パラメータ「_offset」はボールド(スレート)のフレーム数を入れると、尺から指定フレーム数だけ差し引いて、デュレーションを計算します。

(12+20)で23.976fps、ボールド先頭8フレのQTで試すと、

{movie_frame_count:300, movie_seconds:12, movie_frames:12, movie_time_info:"12+12", movie_time:12.5, movie_framerate:23.976}

‥‥のような結果を返します。ちゃんと8フレのボールドを差し引いた"12+12"になっていますネ。

さらに、(12+25)で29.97fpsノンドロ、ボールド先頭10フレのQTで試すと、

{movie_frame_count:375, movie_seconds:12, movie_frames:15, movie_time_info:"12+15", movie_time:12.5, movie_framerate:29.97}

‥‥のような結果を返します。これも合ってますネ。

60秒の29.97fpsノンドロは、

{movie_frame_count:1800, movie_seconds:60, movie_frames:0, movie_time_info:"60+00", movie_time:60.0, movie_framerate:29.97}

となり、期待した結果になります。QuickTime Playerの情報ウィンドウだと「0:00:01:00.06」とか表示されて混乱しますが、上記ルーチンはちゃんと60秒ジャストの尺を返します。

ちなみに、尺が(59+28)のドロップフレームのQTをルーチンで処理しても、ちゃんと59+28を返します。

日々、こうしたルーチンをストックし、スクリプトコンポーネントに書き込んでおくと、とても楽に、面倒な処理のスクリプトがスッと作れるようになります。

スクリプトコンポーネントは単にサブルーチンを記載したスクリプト書類です。load scriptでスクリプト書類を読み込み変数に入れて、中身のサブルーチンを呼び出すだけです。

set myComponent to load script [任意のファイルオブジェクト]
set theResult to myComponent's getQTDurationInfo(document 1, 8)

最近は、本業を絵作り中心に戻そうと思っていますが、やはり、スクリプトで環境を武装しておかないと、不毛な時間的ロスが発生し、巡り巡って、絵作りの時間が奪われる事になります。あまり夢中になりすぎないように、自制しながら、スクリプトやプログラムと付き合い続けていこうと思っています。

ちなみに‥‥AppleScriptをいじった事がなく、他の言語でプログラムをやる人は、

 if _frameDuration is false then return false

‥‥なんて記述を見ると、不思議に思う事でしょう。AppleScriptは、値が存在すればtrueになるわけでは無いのれす。undefinedとかをfalse扱いにしたりも出来ません。いわゆるundefined的なものは、AppleScriptにおいては、スクリプト文の構造上の欠陥と見なされます。「存在しないならfalseだよ」とは行かず、「存在しないのはスクリプト文のエラーだ」となります。‥‥めんどくさいっすネ。結構、「型にウルサイ」やつなのです。


追記:ルーチンにちょっとミスがありました。ビデオトラックを検索する部分です。

誤記「set _frameDuration to duration of frame 1 of track 1 of _document」
訂正「set _frameDuration to duration of frame 1 of t」

誤記のほうは、何のためにループ文でトラックを検査しているのか、意味の無い書き方になっちゃってますネ。見直してたら気付きました。
‥‥まあ、いわゆる「撮影上がり」はビデオトラック1つだけの事が多いので、エラーもなく完了する事も多いのですが‥‥。


Numbersのスクリプト制御

NumbersはそこそこにAppleScriptで自動制御が可能なので、使う気になれば、色々な場面で役立ちます。Numbersの関数と、AppleScriptの各種コマンド、AppleScript上で作った自作の関数などを組み合わせると、日々の作業や日常生活で特に不満を感じる事なく、便利に使えます。

表計算ソフトウェアとしてのExcelの優位性は疑う余地の無いものですが、前に書いたエディットシート程度の内容や、バーコードなどのラベル作成、当座の集計表くらいならば、Numbersで充分こなせますし、レイアウトの自由度が高く、フォントが(お金をかけずに)奇麗なのは、Numbersならでは特徴です。おそらく、Numbersの開発意図も、Excelと「ビジネス分野で競合するつもりはない」のでしょう、Excelのビジネス寄りの盲点を突いた設計思想になっていますネ。

Numbersをスクリプト制御する際のコツは、「ある程度、Numbers内で作っておく」事です。要は、Numbersの関数と協同してスクリプトを実行するわけです。例えば、行番号はNumbersで「row()-1」(1行目が見出しの場合)で自動表記するようにしておいて、コンテンツはAppleScriptで流し込む‥‥みたいな。そうしておくと、後で「この行は不要だ」と削除した時に、いちいち行番号を書き変えなくてすみます。行番号までAppleScriptで流し込むと、任意の行を削除した時に面倒な修正が必要になります。

レイアウトもスタイル(フォントや文字サイズ、字体や装飾)も、Numbersであらかじめ作っておきます。スタイルや行揃えまでAppleScriptで制御しようとすると、無駄にスクリプト作成に時間がかかります。行を追加した時などは、Numbersはスタイルを前の行の状態を継承しますので、スタイルもひな形で事前に作っておけば、AppleScriptでの手間を省けます。

ただ、スタイルは「セルに1種類」と考えて、ひな形を作る必要があります。Numbers上では、セル内で内容文を改行し、行ごと(文字ごとでも)にスタイルを使い分ける事は可能ですが、AppleScriptで単純に値を流し込むと、行頭のスタイルで全て統一されます。スクリプトに対応するひな形のデザインをおこなう事で、最小限の手間でNumbersを思いのままに自動制御できるようになります。

私は、NumbersとAppleScriptを用いて、倉庫収容物のデータベースからバーコード付きラベルを印刷したり、QTファイルのレンダリング速度のアベレージを一覧表にしたり、「手でやると面倒な」作業を自動化しています。

アニメ制作においても、制作さんからCSVファイルを提供してもらい、自分の作業内容と照合して、結果をNumbersの表に出力するような事もできます。

人間の時間は限られたもの、24時間から睡眠時間を除いた時間しか与えられていなので、コンピュータでもできるような仕事は、どんどん自動化して、人間でしか出来ない事柄に時間を費やすべき‥‥と考えているのです。

このあたりの記事は、「片手間スクリプト」的なコラムにまとめて、もっと詳しくコードとかも書いて、リファインすべきかな‥‥とは思っております。Macを使ってるんなら、AppleScriptやiWork、XcodeやObjective-Cを使わないのは、もったいないもんネ。

QuickTime Player 7 と Numbers でエディットシート

今更ながらの話題ですが、QuickTime Players 7とNumbers、そしてAppleScriptがあれば、QuickTimeムービークリップの基本事項を記した一覧表、いわゆるエディットシートを自動で作る事ができます。最近、必要に迫られて昔のスクリプトをブラッシュアップした事もあり、忘れないうちに書き留めておきます。

NumbersはMacOSXの定番表計算ソフトウェアですが、システム標準装備の奇麗なヒラギノフォントなどを用いて作表できるので、見栄えの良いドキュメントを作成できます。AppleScriptを用いて、セル内の値の書き換え、行や列の追加などが自動処理できるので、ひな形ファイルでスタイルを作っておけば、最小限の手間で、スタイル付きの読みやすくて奇麗な表を作る事が可能です。

一方、QuickTime Player 7 は、AppleScriptを用いて様々な操作を自動で処理する事ができます。フルコマ〜数コマ毎の連番書き出し、映像の変換、字幕やインデックスの挿入、映像のカット&ペースト、サイズの変更など、自動処理できる内容は盛りだくさんです。もちろん、ムービーファイルの情報取得も可能です。

Numbersはひな形ファイルをまず作ります。タイトルのテーブルを作り、一覧表のテーブルも作ります。表に名前をつけておけば、「table "お好みの名前" of sheet 1 of front document」で任意の表へとアクセスできます。セルの指定はとても単純で、1行目左からカウントしていくだけです。例えば、8列2行の最終セル〜つまり一番右下のセルは「cell 16」となります。

行を下に追加したい場合は、add row below cell [セル番号] で簡単に追加できます。例えば、先ほどの8列2行の表に行を1行追加したい場合は、add row below cell 9、または、add row below cell 16などで下に追加されます。命令自体はとても簡単。

セルの内容を書き換えたい場合は、set value of cell [セル番号] to "ほにゃらら"で書き換えられます。空欄にしたい場合はvalueを""にすれば良いですネ。

ひな形ファイルはFinder上で複製して日付でリネームするのが楽です。日付けは、do shell script "date +%y%m%d"で、容易に省略した年月日が取得できます。"130510"のような書式は、下手にdateクラスを使うより、shellのdateコマンドを使ったほうが断然楽ですネ。

表の操作が可能になれば、あとはQuickTime Player 7で取得した情報を各セルに流し込むだけです。

QuickTimeはDuration(いわゆる尺ですネ)をタイムスケールの単位で表します。タイムスケールが480だった場合は、10秒は4800という値になります。タイムスケールは大きな数値の事もあれば、24という素直な数字の事もあるので、実際のファイルから取得して計算するのが安全です。duration / time scale で秒数は取得できますが、24コマ表記にする場合は、ちょっと頭をヒネって、変換式を作ります。

ビデオそのものの情報については、「ビデオトラック」の情報へアクセスします。コーデックを知りたければ、「data format of track 1 of document 1」です。
*これはPlayer上で一番手前のドキュメントで、かつトラックがビデオトラック1つだけの時に有効なスクリプト文です。トラックが複数ある場合は、track 1 でビデオトラックを指定できるとは限りませんので、trackの種別を調べてから情報を得る必要があります。でもまあ大概、After Effectsでレンダリングした「撮影上がり」QT は、トラックは1つだけです。

ビデオトラックよりもさらに細密なframeにアクセスすると、フレームレートなどが計算できます。ただし、23.976fpsはちょっと厄介です。「例の誤差」はご多分に漏れず、QTでも発生しますので、めんどくさがらずにサックリ対応します。

QuickTimeの場合、1分につき0.06の誤差が発生し、情報ウィンドウにも本来「60秒」であるはずが、堂々と「60.06秒」として表示されます。しかし、これではNG。しかと本来の尺になるよう工夫します。例えば、以下みたいな。

tell application "QuickTime Player 7"
    set dur to duration of document 1
    set ts to time scale of document 1
    set f to duration of frame 1 of track 1 of document 1
   
    set fps to (round (ts / f * 1000)) / 1000
    set sec to dur / f / (round fps)
end tell

duration of frame 1 of‥‥の下りは、After Effectsで言う「frameDuration」ですネ。fpsはそのまま計算すると「23.976023976024」なんて数値が返るので、野暮ったいやり方ですが、下3桁に丸めています。

上記スクリプトで処理すると、60秒のムービーはちゃんと60の値を返します。60.06(60+1)とかにはなりません。

fpsは23.976ですが、実際は24(四捨五入で)で計算をし、60秒ジャストの尺が返るようにします。せめて未来の120fpsは120.0であって欲しいですが、59.94なんてレートが存在するから、やっぱりダメだろうなあ。

そんなこんなで得た情報を、Numbersの表に流し込むと、整然とした書式の一覧表が出来上がります。

ブログなので、細部の説明はかなり端折っていますが、いつか本家サイトで詳しく紹介できたらと思います。




calendar

S M T W T F S
   1234
567891011
12131415161718
19202122232425
2627282930  
<< November 2017 >>

selected entries

categories

archives

profile

search this site.

others

mobile

qrcode

powered

無料ブログ作成サービス JUGEM