テスト用のダミーQTファイルを自動作成

現在の現場は、静止画連番ではなくQuickTimeが主流となっているようです。今まで、限界値の低いAVIを使ってみたり、遠回りしてきたよねえ‥‥。

しかし、また連番の時代がくるかも知れませんよ。特に劇場は。‥‥QuickTimeも結構(良い意味でも悪い意味でも)枯れてきてますからネ。

さて今回は、「各種、自動処理に用いる」ダミーのQTファイルを、AppleScriptとESTKの連携で、自動作成してみようと思います。今までは、空のファイルを偽素材として生成していましたが、今回はちゃんとしたQuickTimeフォーマットの「架空カットのQTファイル」を作ります。

使うのは、FinderとAfter Effects。

After EffectsではESTK〜JavaScriptを用いて、

  • プロジェクトの作成
  • コンポジションの作成
  • ボールドとなるレイヤーの作成
  • 実映像となるレイヤーの作成
  • レンダーキューへの追加

‥‥を、AppleScriptの助けを借りながら、自動処理します。

今回も長い文なので、早速、以下に記します。

--ここから

property COMPOCOUNT : 30

set AppleScript's text item delimiters to "" --text item delimitersを初期値にリセット

tell application "Adobe After Effects CS6"
    DoScript "app.exitCode=0;"
   
    DoScript "if(app.project.renderQueue.rendering){app.exitCode=-1;}"
    if result as integer < 0 then return --もしレンダリング中なら中止
   
    DoScript "if(!app.project.close(CloseOptions.PROMPT_TO_SAVE_CHANGES)){app.exitCode=-1;}"
    if result as integer < 0 then return --もしAfter Effects上でプロジェクトが開いていて、ユーザが閉じるのを拒否した場合は、中止
   
    set res to text returned of (display dialog "カットを作る数を入力してください" with icon note default answer (COMPOCOUNT as text)) --コンポジションを作る数(100くらいまでが適当でしょうかネ)
    try
        set res to res as integer
    on error msg
        beep
        display dialog "数は半角数字のみ、200以下の数値で入力してください" with icon stop buttons {"中止"}
        return
    end try
    if res > 200 then
        beep
        display dialog "200以下の数値で入力してください.

200以上のカットが必要な場合は、プログラムを修正する必要があります." with icon stop buttons {"中止"}
        return
    end if
   
    set COMPOCOUNT to res
end tell

tell application "Finder" --レンダリング先をFinderで作ります
    set folderPath to make new folder at desktop with properties {name:"テストQT_" & (do shell script "date +%y%m%d-%H%M%S")}
    --open folderPath
    --set bounds of window 1 to {900, 20, 1600, 460}
end tell

set compoPreset to {compoWidth:1920, compoHeight:1080, fps:24, boldFrames:8, user:"ezura", renderSettingsName:"16bit-23.976fps", outputModuleName:"ProRes422(HQ)", outputPath:folderPath as Unicode text}

set title_scene to "ani_05_" --カット名のタイトルとシーン *もしアンダーバーで各要素を区切らない命名規則ですと、エクスプレッションとの兼ね合いにより、うまく動きませんのでご了承ください
set cutList to {}
set durList to {}
set contList to {}

repeat COMPOCOUNT times --コンポジションの内容物を、指定の数量で作ります
    repeat
        set cutN to 1000 + (random number from 1 to 300)
        set cutN to (characters 2 thru -1 of (cutN as text)) as text
        if title_scene & cutN is not in cutList then exit repeat
    end repeat
    set cutList to cutList & (title_scene & cutN)
    set dur to (random number from 1 to 8) * (fps of compoPreset) + (item (random number from 1 to 12) of {0, 0, 0, 2, 6, 8, 12, 12, 12, 18, 21, 22}) + (boldFrames of compoPreset)
    set durList to durList & dur
    set contList to contList & (item (random number from 1 to 4) of {"(-.-)", "(^v^)", "(*_*)", "(~_~)"})
end repeat
cutList & durList & contList

tell application "Adobe After Effects CS6"
    DoScript "var aep=app.newProject();"
   
    repeat with i from 1 to COMPOCOUNT --以下ESTK中心のスクリプトです.AppleScriptも手助けします.
        DoScript ("//各種設定を変数に書き込みます
var fps=" & fps of compoPreset & ";
var w=" & ((compoWidth of compoPreset) as Unicode text) & ";
var h=" & ((compoHeight of compoPreset) as Unicode text) & ";
var cutName='" & item i of cutList & "_t" & (random number from 1 to 3) as Unicode text) & "';
var dur=" & ((item i of durList) as Unicode text) & ";
var boldFr=" & ((boldFrames of compoPreset) as Unicode text) & ";
var dispDur=dur-boldFr;

//新規コンポジションを作ります--尺は一旦コンポを作ってから改めて適用します
var comp=aep.items.addComp(cutName,w,h,1,1,fps);
comp.duration=Math.floor(dur/fps)+currentFormatToTime(dur%fps, fps, true);

//ボールドの背景を作成します
var sldLayer=comp.layers.addSolid([0.75,0.75,0.75],'BOLD',comp.width,comp.height,comp.pixelAspect,currentFormatToTime(boldFr, fps,true));

//カット名表記--エクスプレッションを''にしてオフすると、カット名と尺の表記になります
var textLayer=comp.layers.addText(cutName+'¥r('+String(Math.floor(dispDur/fps))+'+'+((String(dispDur%fps+100)).slice(1))+')');
setTextContents(textLayer,'Arial Black',comp.height/6,[0,0,0],0,ParagraphJustification.CENTER_JUSTIFY,[comp.width/2,comp.height/20*7],¥"thisComp.name.split('_').slice(0,3).join('_');¥",[0,sldLayer.outPoint]);

//テイク番号と尺の表記--名前の都合がエクスプレッションと合わない場合は、オフにしてもよいかと
textLayer=comp.layers.addText('');
setTextContents(textLayer,'Arial Black',comp.height/9,[0,0,0],0,ParagraphJustification.CENTER_JUSTIFY,[comp.width/2,comp.height/5*2],¥"n=thisComp.name.split('_');f=timeToFrames(thisComp.duration-outPoint,fps=1/ thisComp.frameDuration,true);'¥¥rTake '+n[3].slice(1)+'¥¥r('+(Math.floor(f/fps))+'+'+(String(100+f%fps)).slice(1)+')';¥",[0,sldLayer.outPoint]);

//作業日と作業者の表示
textLayer=comp.layers.addText('" & (do shell script "date +%y.%m.%d¥¥ %H:%M:%S") & "'+'¥rby " & user of compoPreset & "');
setTextContents(textLayer,'Arial Black',comp.height/15,[0,0,0],0,ParagraphJustification.CENTER_JUSTIFY,[comp.width/2,comp.height/5*4],false,[0,sldLayer.outPoint]);

//本映像のBGベタを作成します--ランダムで色を変えています
var bgLayer=comp.layers.addSolid([" & (((random number from 3 to 9) / 10) as Unicode text) & "," & (((random number from 3 to 8) / 10) as Unicode text) & "," & (((random number from 3 to 8) / 10) as Unicode text) & "],'BOLD',comp.width,comp.height,comp.pixelAspect,comp.duration);
bgLayer.inPoint=sldLayer.outPoint;
bgLayer.outPoint=comp.duration;

//本映像の顔文字
textLayer=comp.layers.addText('" & (item i of contList) & "');
setTextContents(textLayer,'Arial Black',comp.height/2.7,[0,0,0],0,ParagraphJustification.CENTER_JUSTIFY,[comp.width/2,comp.height/5*3],false,[sldLayer.outPoint,comp.duration]);

//本映像のタイムシート&タイムコード
textLayer=comp.layers.addText('TC');
setTextContents(textLayer,'Courier',comp.height/14,[0,0,0],0,ParagraphJustification.CENTER_JUSTIFY,[comp.width/2,comp.height/6*5],¥"f=timeToFrames(t=time-inPoint,fps=1/thisComp.frameDuration,true);Math.floor(t)+'+'+String(f%fps+101).slice(1)+' | '+timeToCurrentFormat(t,fps,false,thisComp.ntscDropFrame);¥",[sldLayer.outPoint,comp.duration]);

//レンダーキューに追加します--以下の2,3行目をアクティブにすると設定したプリセットを適用するようになります
var rqItem=aep.renderQueue.items.add(comp);
//rqItem.applyTemplate('" & renderSettingsName of compoPreset & "');
//rqItem.outputModule(1).applyTemplate('" & outputModuleName of compoPreset & "');
rqItem.outputModule(1).file=File('" & outputPath of compoPreset & "'+rqItem.outputModule(1).file.name);

//テキストレイヤーの内容を操作する自作ファンクションです--もっと多機能にできると思いますが、今回はこのくらいで...
function setTextContents(_textlayer,_font,_fontsize,_fillcolor,_strokeWidth,_justification,_position,_expression,_inOutPoint){
    _cont=_textlayer.property('Source Text').value;
    _cont.resetCharStyle();
    _cont.font=_font;
    _cont.fontSize=Math.round(_fontsize);
    _cont.fillColor=_fillcolor;
    _cont.strokeWidth=_strokeWidth;
    _cont.justification=_justification;
    if(_expression){
        _textlayer.property('Source Text').expressionEnabled;
        _textlayer.property('Source Text').expression=_expression;
    }
    _textlayer.property('Source Text').setValue(_cont);
    _textlayer.position.setValue([Math.round(_position[0]),Math.round(_position[1])]);
    if(_inOutPoint){_textlayer.inPoint=_inOutPoint[0];_textlayer.outPoint=_inOutPoint[1];}
}"
       
    end repeat
   
    display dialog (COMPOCOUNT as text) & "カットのレンダリングの準備が整いました!" with icon note buttons {"OK"} default button 1 giving up after 5 --この行をコメントアウトするといちいち報告しなくなります
   
    --DoScript ("aep.renderQueue.render();") --この行をアクティブにすると自動でレンダリングがスタートします
   
end tell

--ここまで



う〜ん、ブログに書き込んでみると、なんだか長い。しかし、内容は結構、コンパクトで単純ですヨ。

この文の解説も、またいずれ。(本陣のWeb(現在準備中)で、になると思います)

AppleScriptで、「共通のコンポジット仕様」「架空のカット名」「架空の尺」「本映像に描く絵文字」を設定・生成し、After EffectsのESTKに流し込みます。構造は、ただそれだけ、です。

実際に動作中の動画は以下の通り。スクリプト作成途中のキャプチャなので、若干内容が違いますが(上記スクリプトでは作るカット数を対話式に改善してあります)、ほぼ内容は同じです。



出来上がったファイルはこんな感じです。




ボールドの8コマを足した尺で、本映像部分はランダムに顔文字と背景色を変えています。After Effectsでは一切オペレーションをせず、ダミーのカットがいくらでも生成できます。

実際に書き出したムービーは以下のような感じです。






「これが出来る‥‥と言う事は、あんな事も、こんな事も‥‥」と想像できるんじゃないでしょうか。

実際、私の作業のスタンダート(旧来方式互換での)は、シートと素材の準備が整えば、「素組み」に近い状態までは自動で処理して、カメラワークと映像処理から「人の手」で始めます。まあ、厳密には「シートファイルを作るのも人手」なんですが、そのシートファイルの解釈もスクリプトで自動処理してキーフレームに反映させています。

コンピュータが作業者の雑務を担当する事により、作業者本人は、今まで以上の作業時間を獲得でき、より一層高度な映像表現が可能となる‥‥のです。


こういう類いの自動化を聞くと反射的に「嫌悪感」を感じる人はいるかと思います。

私が思うのは、例えば、手でマウスを操作して「レンダーキューに追加」する事は、どれだけ重要か?‥‥という事です。何かその手作業の行為で、精神性でも高められるんでしょうか?

私だったら、「After Effects上での指を疲労させる行為」は、出来る限り「映像表現に使いたい」ですネ。

些末な1つ1つの雑事が、結果的に作業者・映像表現者を疲労させる。‥‥私の16年のコンピュータ映像制作での「実感」です。その「実感」から開放される手段の一つが、コンピュータによる作業の補助です。


同時に思うのは、「自動処理を導入する覚悟と度胸のある現場」は、「乱作乱造」の状態には陥りにくい‥‥という事です。自動処理を導入するには、計画性が必要です。‥‥その事だけでも、お判りですネ?

付け焼き刃的に、自動処理なんか導入できないんですヨ。実際にやってみれば解ると思うけど。

アニメ業界の乱作乱造は「ワークフローを破壊する」性質のものなので、自動処理システム自体が「まず導入が困難」です。

自動処理システムが整然と機能する「理性的」な現場は、乱作乱造には陥りにくいのです、実は。




calendar

S M T W T F S
1234567
891011121314
15161718192021
22232425262728
293031    
<< October 2017 >>

selected entries

categories

archives

profile

search this site.

others

mobile

qrcode

powered

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