テスト用のダミー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年のコンピュータ映像制作での「実感」です。その「実感」から開放される手段の一つが、コンピュータによる作業の補助です。


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

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

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

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



QTの情報を取り出す(初歩)

作品制作時は、大きく2つの面のバランスで成り立っています。運用と表現。

AppleScriptで運用面を強化すると、巡り巡って、映像表現にも差が表れます。表現に割ける時間が増えるからです。

しかし、どんなに運用面を強化して、快適で鉄壁な制作現場を構築しても、それはあくまで「作品表現が豊かになる『お膳立て』が出来た」に過ぎません。理想的なワークフローを築き上げても、面白い作品を作れるか否かは、無惨な言い方ですが「作り手の映像表現の才能」次第です。

でも、ワークフローがグチャグチャだと、どんなに才能豊かな人材を集めても、ロスが大きくて、作品表現に届く前に半減してしまいます。

要は、運用と表現の両面を、磨き続けるココロが必要なわけです。

まあ、往々にして、映像表現力に自信を持つ人は運用を軽んじ、作業を回す事を重視する人は映像表現に疎くなる傾向があります。どちらに偏り過ぎてもマズいのよね‥‥と、よく自己批判します。



今回のスクリプトは、QTの扱いの基礎です。

QuickTimeムービーファイルが、どのような仕組みなのかを、AppleScriptを使って探ってみます。

AppleScriptで簡単にQTの内容を調べるには、「QuickTime Player 7」を使います。「X」じゃダメです。

QuickTime Player 7で何か適当なQTファイルを開いて、そのファイルの様子を探ります。

探り方は、以下のようなスクリプトを書いて、調べます。

tell application "QuickTime Player 7"
    properties of document 1
end tell

「document 1」とは、一番手前に表示されているムービーの事です。

すると、以下のような「ドキュメント」情報が返されます。

{video brightness adjustment:0.0, name:"f.mov", play all frames:false, current node:missing value, id:1, max time loaded:2640, resizable:normal, time:0, show detailed movie info window:false, natural dimensions:{1920, 1080}, color table:missing value, default node:missing value, show sound controls:false, show video controls:false, show movie info window:false, class:document, show hot spots:false, preferred audio balance track:missing value, fast start:false, output muted:false, poster frame time:0, href:"", pan range:{0.0, 0.0}, selection duration:0, video contrast adjustment:0.0, current chapter:missing value, sound balance:0, sound volume:256, auto quit when done:false, savable:true, pan angle:0.0, time scale:24, presentation mode:normal, bass gain:0, tilt range:{0.0, 0.0}, scale:half, treble gain:0, streaming status message:"", preferred audio gain track:missing value, playing:false, auto close when done:false, aperture:clean, auto play:false, video tint adjustment:0.0, controller type:«constant ****Quic», dimensions:{960, 540}, duration:2640, pan tilt speed:0.0, data size:389908742, field of view:0.0, play selection only:false, live stream:false, looping:false, current chapter track:{}, auto present:false, preferred rate:1.0, video color adjustment:1.0, path:"/Volumes/外付けのHDD/Render/f.mov", stored stream:false, index:1, modified:true, saveable:true, selection start:0, local playback:true, done:false, palindrome:false, current matrix:{{0.5, 0.0, 0.0}, {0.0, 0.5, 0.0}, {0.0, 0.0, 1.0}}, rate:0.0, tilt angle:0.0, language:"SystemDefault", preview:{0, 0}, streaming status code:0, presentation background color:{0, 0, 0}, selection:0, quit when done:false, close when done:false, data rate:3545923, original file:file "外付けのHDD:Render:f.mov", plugin settings:{}, display state:normal, field of view range:{0.0, 0.0}, zoom rate:0.0, load state:complete}

‥‥いっぱいありますネ。

例えば、「natural dimensions」のラベルの値を見てみると、{1920, 1080}になっています。ナチュラルディメンションとは、自然な寸法、つまりQTファイルの「素の状態の」ピクセル寸法が解るわけです。

一方、「dimensions」は、{960, 540}になっています。これはつまり、現在表示している状態のピクセル寸法です。私が1/2の大きさで表示してたので、この値になっているのですネ。

重要なのは、time scaleとdurationの項です。このドキュメントは、time scaleは「24」、durationは「2640」となっています。1秒をどのようなスケールで扱うかがtime scale、そのtime scaleに基づいてムービーの尺を表したのがdurationです。

つまり、このドキュメントの尺は「2640/24」で110秒です。今回流用したムービーファイルは、前にフリッカー参考例で出したファイルなのですが、確かに1分50秒です。After Effectsで、24.0fpsでレンダリングしたので、とても歯切れの良い簡単な数値「24」になってくれたのです。

fpsが23.976の場合は、ちょっと状況が変わってきます。「time scaleは23.976になるのでは?」と思うかも知れませんが、「time scaleは整数で扱う」事と決められているので、そうはなりません。私の手元のQTで調べたところ、

23.976fpsのtime scale → 24000

‥‥でした。ちなみに、23.976fpsのQTの1フレームのデュレーションは

duration of frame 1 of track 1 of document 1 → 1001

‥‥でした。つまり1フレームの長さが1001という設定なのです。これを計算してfpsを求めると、

「24000/1001」=23.976024

‥‥です。まあ、たしかに。末尾の「024」という端数にそこはかとない不安が残りますが、概ね‥‥。


計算しやすいように、今度は1分ジャストの23.976fpsムービーを開いて調べてみます。

23.976fpsの1分のQTファイルのdurationは、1441440でした。

これを慌てて、「duration/time scale」なんていう計算をすると、めっちゃ誤差が出ます。

1441440/24000=60.06

結果は「60.06秒」‥‥たしかに。でも現場ではあくまで60秒として扱わなければなりません。

ドロップフレームではなく、ノンドロップフレームの「ご都合」をちゃんと考慮して計算式を組み立てましょう。

こんな感じに。

duration/フレームのデュレーション/(round (time scale/フレームのデュレーション))

round」とは四捨五入の事です。今回の場合は「23.976024を四捨五入」という事ですネ。

つまり、

1441440/1001/24=60.00

で、正しいデュレーションが返ります。あくまで「ビデオ上の時間軸」の‥‥ですネ。

こんな感じで、QTから様々な情報を得て計算すると、映像制作の各場面で用いる事ができます。

しかしなあ‥‥、こういう計算をしていると、心が荒んでくるのよネ。30fpsが29.97になったいきさつ、そして、29.97のノンドロップが生まれた背景‥‥。そして、さらに23.976 (24p)や59.94 (60p)に拡大して‥‥。「29.97DF」「29.97NDF」「30.0」の3つが混在する状況って‥‥。

それらの経緯を踏まえて、今回のような「23.976と24.0の二枚舌」のスクリプトを作らなければなりません。仕方ない事とは言え‥‥ねえ。

96fpsも「どうせ」96.0fpsにはならんのでしょうね。

アソシエーションの偉いさんたち、どこかで一回、リセットしてくれませんかネ。‥‥ハードの互換性とか言ってたら、この先何百年もずっと呪いから逃れられないよ。アレな廃棄物と同じで「解決は未来の人間に任せばよい」ってか。

その場しのぎの結果オーライ。面倒な運用を延々と引きずる。‥‥プロの現場が理路整然としているのでは決して無い‥‥事の証ですネ。

4Kコンテンツ

4Kのテレビが50万を切って発売されるそうな。私のよく見るヨドバシのサイトでも宣伝しておりますネ。

ほほう‥‥。

で、コンテンツは?

まあ、これ以上は申しますまい。

最低でも、48fps、60fpsのプログレッシブのコンテンツ、それを再生できるプレーヤー等々がないと‥‥なんですが、まあ、まだ無理か‥‥。

未来のアニメーション映像に興味のある方は、たとえSDサイズでも、48fpsや60fpsでのフルモーション実験映像を作る事をお勧めします。「モーションの感覚」の世代‥‥というよりは時代の移り変わりが、少しは体感できるはずです。

とりあえず、4K、48fpsにネイティブ対応するだけでも、江戸から明治くらいの変わり方にはなるはず。

私が思うに、アニメにとっての「黒船」は、4K解像度ではなく、フレームレートなのよネ。4Kや8Kはさ、既に静止画の版権類で充分、体験済みじゃん。

今のところ、私の本命は4K96fpsです。もちろん、1秒96枚の絵、です(コマ落ちはなし)。8Kはね‥‥マシンの性能に大革命でもおきない限りは、(実験はともかく)常用など無理ですネ。

怪しい尺を知らせるスクリプト

アニメの制作現場では、作画が2コマ3コマでタイミングを作る事がほとんどで、ゆえに、カットごとムービーの尺(デュレーション)の傾向は偏ってきます。‥‥というのは、前にも書いたとおりです。

例えば、「4秒19コマ」とか、「5秒23コマ」なんていう尺は、かなり変わった尺です。なので、コンポジットを担当している作業者は、「うわ〜、妙な尺だなあ」と記憶に残ります。

しかし、記憶に無いのに、「5秒23コマ」なんていう尺が存在した場合、「何かの不具合により1コマレンダリングできてない」などの「障害の可能性」が高くなります。

今はQTでレンダリングする事が多くなったので、あまり「23コマ」などの「間違った尺」は見かけなくなりましたが、連番レンダリングではたまに発生する障害です。レンダリングが中途でエラーで止まり、再スタートした際に、1コマ欠落するのです。

まずいことに、尺の間違いはラッシュチェック(カットごとのムービーを上映してスタッフでチェックする)では見つけにくく、編集さんに渡った時点で初めて「発覚」する事がほとんどです。

間違った尺のムービーを度々、編集さんに渡していると、「いい加減な仕事しやがって」と信用を失います。なので、事前に尺間違いがないか、ちゃんと検査してから渡すのがベストです。

厳密な検査は、やはり、確固としたデータベースと照合するのが必定ですが、レンダリング時の障害から発生した類いの尺間違いは、コマ数を調べるだけでも結構「見分けられ」ます。文頭で書いた、現場の慣習による「尺の定番」が存在するからです。

今回は、尺のコマ数をチェックするスクリプトを書いてみます。現場では、実際のファイルから読み出して尺のチェックするのですが、まずは、架空の尺のリストを用意して、「検査エンジン」がうまく動くかを試してみます。

スクリプトは以下。今回はちょっと長めですが、構造自体は簡素です。

--ここから

--架空のカットの尺のリストです。実際には、QTから取得したり、連番ファイル数から取得します。
set cutList to {{cutName:"#10-c101", duration:"3+0"}, {cutName:"#10-c104", duration:"5+12"}, {cutName:"#10-c106", duration:"2+6"}, {cutName:"#10-c123", duration:"1+18"}, {cutName:"#10-c125", duration:"0+5"}, {cutName:"#10-c155", duration:"2+18"}, {cutName:"#10-c158", duration:"6+21"}, {cutName:"#10-c160", duration:"8+0"}, {cutName:"#10-c161", duration:"5+23"}, {cutName:"#10-c183", duration:"3+12"}, {cutName:"#10-c200a", duration:"2+2"}, {cutName:"#10-c200b", duration:"4+1"}, {cutName:"#10-c202", duration:"3+12"}}


--警告をおこなうための仕組みをつくります
--matchNumbersは、コマ数の番号
--dialogはそのコマ数に対するコメント
--levelは危険度レベル(level 1 を最安全レベルとして、最も危険なレベルを6としました)
set lev1 to {matchNumbers:{0, 12}, dialog:"正常と思われます.", level:1}
set lev5 to {matchNumbers:{1, 5, 7, 13, 17, 19}, dialog:"少々危険なコマ数です. 念のため尺の再確認をお勧めします.", level:5}
set lev4 to {matchNumbers:{2, 4, 8, 10, 14, 16, 20, 22}, dialog:"2コマベースならあり得るコマ数です.", level:4}
set lev3 to {matchNumbers:{3, 9, 15, 21}, dialog:"3コマベースならあり得るコマ数です.", level:3}
set lev2 to {matchNumbers:{6, 18}, dialog:"2コマ3コマ共通のよくあるコマ数です.", level:2}
set lev6 to {matchNumbers:{11, 23}, dialog:"危険なコマ数です. 尺の確認を強くお勧めします.", level:6}
set levList to {lev1, lev2, lev3, lev4, lev5, lev6}

set aColors to {{0, 0, 0}, {0, 0, 10000}, {0, 20000, 0}, {0, 20000, 0}, {50000, 20000, 0}, {50000, 0, 0}} --警告色の設定です

set numberDB to {} --0から23のコマ番号に対する、危険度レベルを設定するために、まず空のリスト「numberDB」を作ります

repeat with num from 1 to 24
    set numberDB to numberDB & {num} --「numberDB」にまず1から24で埋めます
end repeat
repeat with lev in levList
    repeat with num in matchNumbers of lev
        set item (num + 1) of numberDB to level of lev --「numberDB」に危険度レベルを当てはめます
    end repeat
end repeat
--以上で「numberDB」=各コマ番号に対する危険度レベルリストが完成しました

--いよいよ、尺をチェックして結果をテキストエディットに表示します
tell application "TextEdit" to set doc to make new document --新規書類をテキストエディットで作ります
my writeTextEdit(doc, "尺の端数をチェックしてみました!" & return & return, {0, 0, 0}) --1行目のコメントを書き込みます

repeat with dur in cutList --カットリストを順々に処理します
   
    set durationInfo to my calcFrames2(duration of dur, 24) --カットリストの尺情報を尺の分析ルーチンに投げて、結果を受け取ります
    set dispFr to (characters 2 thru -1 of ((10000 + (frames of durationInfo)) as Unicode text)) as Unicode text --フレーム総数を4ケタ表示にします(テキストエディット上できれいに表示させるため)
    set basicText to cutName of dur & tab & (displayText of durationInfo) & tab & dispFr & tab --書き込む基本情報を生成します
   
    if frames of durationInfo < 12 then --もし尺が12コマ未満だった場合
        my writeTextEdit(doc, basicText & "尺が短過ぎるかも知れません. 念のため尺の再確認をお勧めします." & return, item 6 of aColors) --‥‥のように書き込みます。警告色は「item 6 of aColors」〜つまり最危険度の色です
    else
        set myLevel to item ((framesCount of durationInfo) + 1) of numberDB --コマ番号を「numberDB」に照らし合わせて、当該の危険度レベルを得ます
        my writeTextEdit(doc, basicText & (dialog of item myLevel of levList) & return, item myLevel of aColors) --危険度別のコメントを書き込みます。テキスト色も危険度レベルに合わせた色にします。
    end if
   
end repeat

tell application "TextEdit"
    set bounds of window 1 to {20, 20, 720, 520} --最前面のウィンドウ(つまり結果を書き込んだ書類)のウィンドウ位置と大きさを見やすいように調整します
    activate --テキストエディットを最前面に表示します
end tell
--テキストエディットの表示を確認してください
--以上でメイン部分は終了です。


on calcFrames2(_durText, _fps) --前回使ったルーチンを使い回しています
    set delim to AppleScript's text item delimiters
    set AppleScript's text item delimiters to "+" as Unicode text
    set textitems to text items of (_durText as Unicode text)
    set AppleScript's text item delimiters to delim
   
    if length of textitems > 5 then return false
   
    set timescale to {1, _fps, _fps * 60, _fps * 60 * 60, _fps * 60 * 60 * _fps}
   
    set fc to 0
    repeat with i from 1 to length of textitems
        set textitem to item -i of textitems
        try
            set fc to fc + (textitem as integer) * (item i of timescale)
        on error
            return false
        end try
    end repeat
   
    set arr to {}
    set modfc to fc
    repeat with i from 1 to ((length of timescale) - 1)
        set arr to arr & modfc div (item -i of timescale)
        set modfc to modfc mod (item -i of timescale)
    end repeat
   
    set sec to (fc div (item 2 of timescale)) as Unicode text
    set frDisp to (characters 2 thru -1 of ((100 + modfc) as text)) as Unicode text
   
    return {frames:fc, durationText:(sec & "+" & (modfc as text)) as Unicode text, displayText:("(" & sec & "+" & frDisp & ")") as Unicode text, daysCount:item 1 of arr, hoursCount:item 2 of arr, minutesCount:item 3 of arr, secondsCount:item 4 of arr, framesCount:modfc, secondsText:sec, framesText:frDisp, fps:_fps}
end calcFrames2


--テキストエディットに文字を書き込むルーチンです
on writeTextEdit(_doc, _text, _color)
    tell application "TextEdit" to make new paragraph at the end of _doc with data _text with properties {font:"HiraKakuProN-W3", color:_color, size:14}
end writeTextEdit

--ここまで


AppleScript初心の場合は、読み切れないかも知れませんが、詳細な解説はいずれ。


上記スクリプトを実行すると、以下のような検査結果がテキストエディットを用いて表示されます。危険度が増すほどに、テキスト色が赤に近づいていきます。




架空ではなく、本番の作業では、上記のようには色とりどりにはならないでしょう。大体、黒か緑の文字で埋まるはずです。その中にあって、たまに赤い文字が1行あると、その行だけが異様に目立って、ユーザ(例えば撮影監督)に知らせてくれます。

コンピュータはあくまで「判断をユーザに求めてくる」だけです。意図された「5+23」なのか、意図しない「5+23」なのかは、人間が判断します。タイムシートが「5+23」だったら、「うん、そうなんだよ。中途半端な尺なんだよなぁ」と自分の中で念押しできます。

スクリプトのプログラム文を読むと、コマ番号に対する危険度レベルとコメントを設定しているのが解ります。その「からくり」通りに、スクリプトは尺を判断し、テキストエディットでユーザに告知します。

これは、「作業の内容」や「作業の慣習」をもとに、当該の様々な「値」を、プログラムで処理して判断する、初歩的なスクリプトです。こうした事をどんどん積み重ねていけば、コンピュータは、まるで介護犬のように、ユーザに色々と「尽くして」くれる存在になります。

少なくとも、私はこのようなプログラムを作業に取り入れたおかげで、格段にミスを減らし、格段に「映像表現に専心」できるようになりました。

映像作りは1枚絵を描くのに比べて、煩雑で事務的な作業が多過ぎます。‥‥で、それは減らせません。必要な雑務なのです。だったら、その雑務を「どう処理するか」を考えれば良いのです。

映像を作りたいのなら、思いのままに映像を作れるよう、環境を整えるのが「当たり前の事」です。雑務に自分の時間を搾取されっぱなしに放置しておくと、いつまでたっても本腰を入れて取り組めないのですヨ。

テキストエディットを操作してみる

少人数で映像制作をしていると、手弁当で各自が適宜制作管理して‥‥なんて考えがちですが、全くのナンセンス、「やるべき事」と真逆の行動です。少人数グループは、制作進行と呼ばれる制作を管理するスタッフが立てられない事が多いので、実は一番、その「制作」部分が甘くなり脆弱になるのです。そして、その甘さはまんま、映像のクオリティに影響します。

少人数制作ほど「誰も制作を管理していない」状況に陥り、土壇場になって「あれがない」「これが抜けてた」などの醜態をさらす事になります。プロ集団が「制作スタッフ」と呼ばれる人員を配置するのは、ちゃんと大きな意味があるのです。

私は2〜3人で作業する事がありますが、「人数が少なくて小回りが利く」のは確かにそうですが、代償として「誰も面倒を見てくれない」状況が待っています。なので、私が編み出したのが「コンピュータに面倒を見てもらう」制作手法です。まだ不完全なシステムではありますが、コンピュータに管理を委任するようになって、何よりもまず随分楽になりましたし、ミスも大幅に減りましたし、精神的にも余裕が出るようになりました。

コンピュータによる創作サポート体勢が必要なのは、まずは個人、少数人数の制作規模なのです。世間では全く逆に考えられていますが、ネ。

制作システムって、大所帯の会社が導入するものだとタカを括っていませんか。大所帯の会社は、いざとなればマンパワーでこなせますが、少人数・個人のマンパワーは悲劇的とすら表現できます。制作システムの「守護」が必要なのは、むしろ、個人や少人数なんですヨ。

ちなみに‥‥コンピュータを制作上の強い後ろ盾にする‥‥わけですから、その制作システムが「日々、何でもかんでも、いちいち手で入力しないとうまく動かない」ようでは「本末転倒」も甚だしいです。作業の中にとけ込むようなシステムでなければなりません。

現在のコンビニ・スーパーのレジをイメージすると、どういう事か、想像できるんじゃないでしょうか。面倒な作業を肩代わりしてくれるツールが、実はデータベースなどと連携して強いシステムをどんどん作っていく‥‥というのが、好ましいのです。制作システムにこき使われるようじゃアウトです。

実は、この「今さらAppleScript」は、各個人が自分なりの作業システムを作るためのきっかけになればと想い、書き綴っているのです。‥‥まあ、ちょっと遠い気もしますが、ちまたには、あまりにも文献が少ないからネ。

今回は手短に、MacOSX付属の「テキストエディット」のスクリプトをちょい、紹介します。

コンピュータが処理している様子は、人間からはまったく伺い知る事はできません。空冷ファンの音が大きくなると、「あ、大変なんだ」とか解る程度です。なので、スクリプトプログラムの文中に「見ている人間がわかるように、文字を表示する」仕掛けを作るのが一般的です。

AppleScriptで文字を表示する手段は、いくつもありますが、今回はテキストエディットを使って、遊んでみます。

以下がスクリプト文です。

--ここから

set cont to "=>
==>
-==>
- - ==>
   - - ==>
       - - ==>
      .       - - ==>
   .              .   - - ==>
             .           .    - - ==>
          .           .         .   .   - - ==>
  .            .       .           .            .   - - ==>
                  .         .                                      - - ==>
         .                          .        .       .                             - - ==>
                                 .                          .        .       .                             - - ==>
  .        .               .   .      .             .            .
.     .           .      .        .        .     .
    .           .      .     .     .
.         .    . 
.    .
"

set AppleScript's text item delimiters to "
"
set cont to text items of cont
set AppleScript's text item delimiters to ""

tell application "TextEdit"
    --activate
    set doc to make new document at the end
    set bounds of window 1 to {60, 60, 1060, 260}
    tell doc
        make new paragraph at the end of it with data item 1 of cont with properties {font:"Courier-Bold", color:{40000, 0, 0}, size:14}
        delay 2
        repeat with txt in cont
            delay 0.1
            set paragraph 1 of it to txt
        end repeat 
    end tell
end tell

--ここまで


上記スクリプトを動かすと、以下のYouTubeムービーのようになります。




‥‥まあ、これ自体に有用性はありません。しかし、文字を書き換えて動かす段取りはわかるかと思います。

次に紹介する予定の、尺のコマ数をチェックして「怪しいかどうかを告知する」スクリプトでも、テキストエディットを使います。

ではまた。

尺とフレーム数、全部入り

前回書いた「尺からフレーム数への変換」は、実際に使ってみると実用性に乏しい事がわかります。制作作業では、フレーム数から尺への変換が必要な場合もありますし、After Effectsのテキストレイヤーに流し込む際に、秒とコマの情報を別々に欲しい場合もあります。

そんな時は、自作のルーチンを強化して、機能アップを図れば良いのです。

ユーザが「00+00」「00+00+00」の書式で入力した場合と、「0000」のフレーム数を入力した場合の、2つの場面に対応できるルーチンに改良します。

「どうやってみわけんの?桁数?」「IFで分岐?」‥‥とか考えがちですが、実は何も見分けなくても、前回書いたルーチンは「フレーム数の入力に対応」しています。

前回のルーチンは、

  • 6+0
  • 0+144
  • 144
  • 3+72

‥‥のどれでも、正しく処理します。これはAfter Effectsもそうで、人間が繰り上がりを計算しなくても、自動で繰り上げを計算するようプログラムされているのです。「1+18」のカット尺にボールド8コマを足した「1+26」と入れても、ちゃんと「2+2」に変換してくれます。

要は、ベタなフレーム数を計算した後、改めて「00+00」の書式を生成するルーチンに仕立てておけば、「行儀の悪い」入力でも「清書」した値を返してくれます。

また、ルーチンが返す値も単に「フレーム数」だけでなく、様々な情報を返すように強化します。AppleScriptでは「ラベル付きリスト」とか呼ばれるデータで、今回作ったルーチンは以下の値をまとめて返してくれます。

  • フレーム数
  • 尺の汎用的な書式
  • 尺のコマ数(フレーム数)を2ケタ表示にして括弧で囲んだ表示書式
  • 日(普通はいらないよね、こんな単位)
  • 時間
  • フレーム
  • 秒の表示(端数を除いた総秒数)
  • フレームの表示(2ケタ)
  • 計算に用いたFPS

ルーチンを利用する際、上記の中から、ニーズに適合するものを取り出して使います。

で、せっかくなので、単にルーチンを走らせるだけでなく、対話式のプチ「尺とフレームの変換計算」アプリケーションに仕立て上げます。

以下がAppleScriptのスクリプト文です。

--ここから

set res to text returned of (display dialog "尺またはフレーム数を入力してください" default answer "")

if length of res = 0 then
    beep
    display dialog "入力欄が空です." with icon stop buttons {"中止"} default button 1
    return
end if

set res2 to my calcFrames2(res, 24)

if res2 is false then
    beep
    display dialog "入力した文字に問題があります." with icon stop buttons {"中止"} default answer res
    return
end if

display dialog "計算結果は以下の通りです" with icon note buttons {"OK"} default answer "尺:" & durationText of res2 & "
表示書式:" & displayText of res2 & "
フレーム数:" & frames of res2


on calcFrames2(_durText, _fps)
    set delim to AppleScript's text item delimiters
    set AppleScript's text item delimiters to "+" as Unicode text
    set textitems to text items of (_durText as Unicode text)
    set AppleScript's text item delimiters to delim
   
    if length of textitems > 5 then return false
   
    set timescale to {1, _fps, _fps * 60, _fps * 60 * 60, _fps * 60 * 60 * _fps}
   
    set fc to 0
    repeat with i from 1 to length of textitems
        set textitem to item -i of textitems
        try
            set fc to fc + (textitem as integer) * (item i of timescale)
        on error
            return false
        end try
    end repeat
   
    set arr to {}
    set modfc to fc
    repeat with i from 1 to ((length of timescale) - 1)
        set arr to arr & modfc div (item -i of timescale)
        set modfc to modfc mod (item -i of timescale)
    end repeat
   
    set sec to (fc div (item 2 of timescale)) as Unicode text
    set frDisp to (characters 2 thru -1 of ((100 + modfc) as text)) as Unicode text
   
    return {frames:fc, durationText:(sec & "+" & (modfc as text)) as Unicode text, displayText:("(" & sec & "+" & frDisp & ")") as Unicode text, daysCount:item 1 of arr, hoursCount:item 2 of arr, minutesCount:item 3 of arr, secondsCount:item 4 of arr, framesCount:modfc, secondsText:sec, framesText:frDisp, fps:_fps}
end calcFrames2


--ここまで

上記スクリプトを「アプリケーション形式」で書き出すと、いつでも尺の変換計算を確認できるプチAppができます。実行してみると、



ここに何か、尺を入力します。例えば6秒ジャストの尺を色々な書式で入力してみましょう。



結果は、



‥‥とちゃんと正確に計算しております。さらに違う書式で‥‥



‥‥とか、



‥‥などでも、やはり以下の通り、正確に計算して返します。



別の尺でも、



ちゃんと変換します。



さらには、こんな表記もイケちゃいます。



1時間0分0秒0コマ。もちろん結果は、



‥‥ですネ。3600秒は1時間ですから、バッチリ、処理できてます。


仮に、尺以外の入力をした時は、



以下のようにエラー警告をおこないます。




‥‥とまあ、こんな感じで、尺の変換ルーチンに「display dialog」のGUIをくっつけて、1つの小さなアプリケーションにする事もできます。

尺の変換ルーチンは、それそのものは何らUIを持ちませんから(というか、そのように作ったので)、対話式のアプリにしたい場合は、AppleScriptの他の機能と組み合わせてアプリを作ります。After Effectsのレンダーオートメーションと連携して、コンポジションの尺や、テキストレイヤーの内容を書き換える事も可能ですネ。

次回は、尺の変換の体勢も整ったので、「尺が怪しくないか、判断してユーザに知らせる」スクリプトを作ってみます。以下のような「素敵なお知らせ」をMacがテキストエディットを使って知らせてくれます。



AppleScriptはdisplay dialogだけでなく、テキストエディットを用いて告知板にしたり、HTMLファイルを書き出してFireFoxやSafariで表示する事もできますから、ユーザへの「お知らせ方法」の手段はそれなりに豊富です。

ではまた。

尺からフレーム数への計算

アニメ制作現場では、2コマ3コマで動きのタイミングをとる事が多いので、都合、タイムシートでの尺は「傾向が偏って」きます。

例えば、「3+12」(つまり3秒半)なんていう尺は、それこそ耳にタコができるくらいお馴染みの数値です。

そんな中、QTファイルのPDF伝票で「3+11」とか「5+23」とか言う尺を見ると、「なんかやらかしたか?」と直感します。つまり、「何かの障害で、尺が足りてない」的な「危険予測」です。‥‥まあ、危険予測と言っても、既にレンダリング済みのムービーファイルの尺なので、実際は「現物を確認する前の、状況予測」なんですけども。

シートを確認してみると、「うわー、変な尺。ほんとに5+23だよ。1コマ伸ばして6+0にしときゃいいじゃん‥‥」という珍しい状況もあったりします。しかし、そんな変な尺の大体は、レンダリングの何らかの不具合による途中終了、もしくはオペレーション上のミスの場合が大半です。

なので、カットを管理するデータベースと連携しなくても、尺を見るだけで尺の不具合を発見する事ができます。もちろん、全て発見できるわけではないですが、ソフトウェア上で発生したような障害は、大体検出できます。

つまり、レンダリングしたムービーの尺を取得して、「変なコマ数」か否かをチェックするスクリプトを作れば、作業者がいちいちファイルをチェックしなくても、コンピュータが「やばそうな尺を教えて」くれる‥‥というわけです。そうやって、コンピュータを自作ツールで「育てて」いくと、次第に「作業上のパートナー」「ヘルパー」的な役割へとコンピュータが変わってきます。

今回はまず、その土台となる、尺とフレーム数の変換スクリプトを、AppleScriptにて書いてみます。やる事自体は、そんなに難しくないのは、考えればお分かりかと思います。24コマで1秒‥‥というのを、計算すれば良いのですからネ。

アニメ現場の場合、尺は通常、1秒24コマ換算で、「秒+コマ」の書式で書きます。3秒なら「3+0」、5.5秒なら「5+12」です。

尺をフレーム数に換算するのは、例えば「5+12」の場合、

5+12

‥‥を「+」で文字列分解して、

5 12

‥‥の要素に分けます。そして、

(5x24) + 12 = 132

‥‥という計算をしてやれば良い訳です。

ちなみに、After Effectsではコンポジション設定のデュレーションの欄に、「5+12」と入れると、「5秒12フレーム(コマ)」としてちゃんと認識します。さらには、「1+30+0」と入力すると、「1分30秒0フレーム」と認識します。どこまでプラス(+)の連結を受け入れるのか、怖くてやってませんが、AppleScriptでも似た構造で処理してみます。

ちょっと図にのって、「日+時+分+秒+フレーム」という5段階まで受け入れるように作ってみました。‥‥まあ、「日」単位の需要があるとは思えませんが。

my calcFrames("5+12", 24)

on calcFrames(_durText, _fps)
    set delim to AppleScript's text item delimiters
    set AppleScript's text item delimiters to "+" as Unicode text
    set textitems to text items of (_durText as Unicode text)
    set AppleScript's text item delimiters to delim
   
    if length of textitems > 5 then return false
   
    set timescale to {1, _fps, _fps * 60, _fps * 60 * 60, _fps * 60 * 60 * _fps
}
    set fc to 0
    repeat with i from 1 to length of textitems
        set textitem to item -i of textitems
        set fc to fc + (textitem as integer) * (item i of timescale)
    end repeat
   
    return fc
end calcFrames



「on calcFrames...」以下が尺をフレーム数に変換する「自作ルーチン」です。1行目の「my ...」でルーチンを呼び出して処理させます。

1行名の「my...」のかっこ内の「"5+12"」を、「"7+0+0+0+0"」(7日0時間0分0秒0フレーム)に書き換えると、7日=1週間のフレーム数が計算できます。

ちなみに7日間のフレーム数は、1451万5200フレームみたいです。

きりがないので、「1+0+0+0+0+0」(=1年)などの6つ以上の連結の場合は、「false」(偽の値〜「もうダメよ」的な)を返すようにしてあります。

こんな感じで、「処理ルーチン」を自作して、そのルーチンに値を投げ込むと、処理された値が戻ってきます。このやり方は、スクリプトが複雑化する際に、必須となります。

箱絵のコレクション

私は、プラモデルの箱絵が小さい頃から好きで、よく模写したものでした。今も箱絵に対する愛着は変わらず‥‥というか、昔よりも増しているやも知れません。

資料用で買うプラモの他に、ノスタルジーで買うプラモもあって、その場合は、箱が今以上に痛む前に、スキャンした後に保管します。

何せ、30〜40年の月日が経っていますから、印刷の状態は様々な原因で悪化の一途を辿っております。ヤニによる汚れはまだ良いほう(拭けばずいぶん奇麗に取れるから)で、カビ、インクの退色、紙焼け、やぶれ、はがれ、etc...と、出来るだけ早急に今の状態以下にならないように対応します。

私は絵を眺めたいので、もちろん、スキャンしてデータとしても保存します。しかし、スキャンしたそのままの状態では、なかなか鑑賞に堪える画像にはなりません。とにかく、黄ばみが凄くて、絵をまともに眺められないのです。

なので、今までの本業の経験を活かして、補正作業を施して保存します。スキャンの生状態もそのまま残しますし、当然ですが、原版もファイリングして残します。

例えば、つい最近買ったF-4Eは、




‥‥のような状態を、




‥‥のようなクリアな状態に補正してコレクションしました。色温度の危うい箇所とかがありますが、「まずはこのくらいでいいか」というレベルに留めております。Photoshop形式600dpiで保存してあるので、後で気になるところは再調整できます。

スキャン直後のものを見てもらえば解りますが、特に右側の帯のところが、退色と黄ばみが激しく、これを補正するのは、中々のチャレンジではあります。




上図のような状態です。おそらく、日のあたる窓方向にこの面を向けていたのでしょう。幸い、積み重なって保存していたのか、メインのトップ絵は、あまり色あせしていませんでした。

かなり強引な力技で補正して、



‥‥のような感じに仕上げました。実は、「タン」(明るい黄土色)の色調が明るく黄色過ぎるのですが、このくらい直ってればいいや‥‥という事で、フィニッシュとしました。あくまでも自分のコレクションなんで、自分で見てて気にならなきゃ良いという品質基準ですネ。

しかし、なんだかマニアっぽい話ですが、箱の状態を見ると、前のオーナーの性格とか生活習慣が、思い浮かびます。このファントムのキットは、おそらく奇麗に積み上げられておらず、ややルーズに積まれていたのでしょう。部屋は、やや強めの光が差し込む時間帯があり、徐々に退色が進行したものと思われます。収集癖はあるものの、あまり几帳面な人ではなかったのかも知れません。黄ばみが回り込んでないですから、ヘビースモーカーではなかった雰囲気です。

一生出会うことのない見知らぬオーナーから、ショップを通じて、私に引き継がれたキット。

私は、作品にて昇華しようと思っているのです。

宇宙船ペペペペラン

私が小さい頃、家に「ドレミファブック」という音楽絵本がありまして、毎日のようにレコードをかけ、絵を眺めていました。

その中で私が好きだったのは、「ちびくろサンボ」「ないたあかおに」「はくちょうのみずうみ」「ほらふきヤーノシュ」そして「宇宙船ペペペペラン」です。

宇宙船ペペペペランは、抽象絵画のような挿絵でしたが、私は今でも明確に、その時感じたイメージを思い出す事ができます。こずるくて小器用な処世術を身につける前の、無防備かつ、ある種残酷な子供時代のほうが、抽象絵画を感じとる能力は高いのかも知れません。

筋立ては、おじいさんが街にやってきて、子供たちに「昔話のような、未来の話」を聞かせるというものです。話は、地球上が1つの国になった未来に、子供たちだけを乗せた宇宙船ペペペペランが新天地アンドロメダを目指して、宇宙を航行する‥‥と言う内容です。

宇宙船には男女同数の子供が乗っているはずだったが、実は(何かのミスで)男の子が1人多くのっており、男女が思春期を経て結婚するようになると、「弱虫ロン」が1人取り残された。ある時宇宙船に彗星が衝突し、独身で妻帯者ではないロンが船外での危険な修理を引き受ける事になった。修理が済むとすぐにロケットは発進し、ロンは宇宙に取り残され、気が狂れた‥‥という、子供の私には(今思うと)強過ぎるほどの刺激の絵本でした。


‥‥で、最近、エスペラント語の事を人から聞いて、ふと、この「ペペペペラン」の事を思い出したのです。全くエスペラント語の事を知らなかった私(古文書か何かだと思ってた)が、その成り立ちを聞いた後、ふと「ペペペペラン」はエス「ペラン」トのもじりだと言う事に気がつきました。そして、子供の頃に呼んだ「創作絵本」が何を言わんとしてたかが、瞬時にクリアになったのです。

世界に国の境がなくなり、言葉も共通になっても、全ての人間が解り合えて愛し合い幸せになるわけではない‥‥という理不尽などではなく淡々とした現実を、そっと語りかけているのでしょう。これはもっと遡って思いを巡らせれば、自己の「こっち側とむこう側の垣根」は、あらゆる個性に取り憑かれたカラダからは、取り払う事はできない‥‥と言う事ですネ。

ロンがなぜ大勢の女の子の誰ひとりからも愛されなかったのか。作中では、「弱虫」「しし鼻」という理由を上げています。おじいさんの話を聞いてた女の子が「私だったらロンと結婚するのに」とか言うと、他の子が「そしたら、また誰か他の子が余っちゃう」と言います。

恐るべし。ドレミファブック。

子供に何を語ろうとしたのか。何をインプリントしようとしたのか。

今になってしみじみ思うのは、6000万人とも言われる死者を出した未曾有の惨劇とも言えるWWIIを経た人類、その若い世代が自由や友愛に理想を掲げ(例えばヒッピームーブメントのような)、内輪でもめ混乱し、やがて挫折していく様を、この絵本の筋立てに見るのでした。

「子供たちだけで未来の新天地を目指す」というのも、確信的、示唆的です。理想を託された子供たちが、大人になって、どうなったか?‥‥という事ですネ。

この創作絵本の作者は、何か世相から、挫折感を感じとっていたのでしょうかネ。ドレミファブックは、1970年前後の出版なはずですから、例の全共闘絡みの「終盤」です。

創作絵本の中に、自由や友愛の「阿鼻叫喚」が磁気転写されたとしても、何ら不思議ではありませんし、むしろ「大いにありそう」です。

およげたいやきくんも、そんな歌でしたネ。「やっぱり、ぼくはたいやきさ。すこし、焦げある、たいやきさ。オジサン、つばをのみこんで、ぼくをうまそうに食べたのさ。」

レシピにそって、日々、大量に製造される、たいやき。ある日、たいやきは自由を求めて海に逃げ込む。しかし、海は海で、いじわるなサメはいるし、お腹も空く。ふと美味しそうな餌が漂っているのを見て、おもわずパクつく。そしたら、釣り上げられ、もとの世界へと戻されてしまう。結局は、他のたいやきの運命と同様に、オジサンに食べられて一生を終えた。チャンチャン。

なんだろう。この頃の創作家は、大人の社会での無念を、子供に訴えかけようとしてたんでしょうかネ? ‥‥で、私はその子供のなかの1人です。うーむ。

70年代は、そんな風味が数多い時代‥‥ですネ。

ファイルの分別(後)

AppleScriptでファイルの分別をする後半です。ポイントは、

  • 大量処理の場面ではFinderを使わず、高速化する
  • カット名らしき文字列を含むファイルだけを対象とする
  • 特定のファイル形式(今回はDPX)だけを対象とする

‥‥です。つまり、PSDやQT、JPEGは対象から自動的に外し、さらにはDPXファイルと言えどもカット名を含まないものも自動的に対象外とします。

そこそこ長いスクリプト文なので、まずは下記に記します。

(*

まず、手始めに‥‥

本番のファイルを使うのはマズいし、テスト用にAfter Effectsで連番ファイルをレンダリングするのもバカらしいので、「ニセの画像ファイルの連番」を作ってしまいます.

*)

set folderName to do shell script "date +%y%m%d-%H%M%S" --日付&時間の文字列を生成
tell application "Finder" --Finderに命令を開始
    activate --Finderを最前面にする
    set theFolder to make new folder at desktop with properties {name:folderName} --先ほど生成した文字列を名前にしてフォルダ(=テストの作業場所)をデスクトップに作る
    open theFolder --作ったテスト用フォルダのウィンドウを開く
end tell --Finderへの命令終了

set folderPath to theFolder as Unicode text --フォルダをパス文字列に変換する
set countOfFiles to 720 --カット毎の連番ファイル数を指定
set dummyCutNames to {"dummy_02_165_t1", "dummy_01_014_t2", "anime_12_254a_t1", "dummy_02_098_t3", "test_a_211_t3", "test_a_211_t4"} --架空のカット名を生成

repeat with dummyCut in dummyCutNames --ダミーのカットで繰り返し処理
    repeat with i from 10001 to (10000 + countOfFiles) --10001から数え始めて指定ファイル数へ繰り返し処理
        set ofa to open for access file ((folderPath & dummyCut & "_" & ((characters 2 thru -1 of (i as text))) as Unicode text) & ".dpx") with write permission --テスト用フォルダ内にカット番号+4桁連番+拡張子の名前のダミーファイルを作ってアクセス開始
        write "dummyだよん" to ofa --dummyという文字列を書き込む(テキトーな文字)
        close access ofa --ファイルへのアクセスを終了する
    end repeat --繰り返し処理終了
end repeat --繰り返し処理終了

--テストフォルダの中には、5秒前後で数千個のファイル(自動処理のテスト用の偽ファイル)が生成された、はずです.

--故意に他の拡張子のファイルも数種類混ぜてみましょう
--名前でソートした際にごちゃごちゃになるよう、わざとイジワルな名前をつけて、スクリプトの耐久性を見ましょう
repeat with dummyFile in {"A-関係ないPhotoshopファイル.psd", "B-関係ないQuickTimeファイル.mov", "s_全く関係ないJPEGファイル.jpg", "Y_消し忘れたPNGファイル.png", "0-素材のイラレファイル.ai", "testで書き出したDPX.dpx"}
    set ofa to open for access file (folderPath & dummyFile) with write permission --偽ファイル
    write "dummyだよん" to ofa --dummyという文字列を書き込む(テキトーな文字)
    close access ofa --ファイルへのアクセスを終了する
end repeat



activate --このスクリプトを最前面にして
set theResult to display dialog ((length of dummyCutNames) as text) & "カットの合計" & ((countOfFiles * (length of dummyCutNames)) as text) & "ファイルを生成しました" with icon note buttons {"ここで止めとく", "分別を処理してみる"} default button 1 giving up after 20 --処理の続行を尋ねる
tell application "Finder" to activate --Finderを最前面にする(処理の様子を見せる)
if button returned of theResult is "ここで止めとく" then return --ユーザが中止を選択した場合は処理を中止


(*


これより以下がフォルダごとの分別処理です.
回りくどいトリッキーな事をしているように見えますが、「できるだけFinderを大量のファイルに関与させない」工夫ゆえです.

*)

set cutNameSliceStart to 1 --カット名を抜き出す開始番号(アンダースコアで区切った配列のスタート)
set cutNameSliceEnd to 4 --カット名を抜き出す終了番号(アンダースコアで区切った配列のエンド)
set nameExtension to ".dpx" as Unicode text --収拾するファイルの拡張子を設定
set AppleScript's text item delimiters to "_" as Unicode text --ファイル名のリスト分解に備える

set tryCount to 0 --検索ファイルのカウント
repeat --無限の繰り返し
    set tryCount to tryCount + 1 --検索ファイルのカウントを1つ増やす
    try --エラー発生を見越して(故意にエラーを発生させる)
        tell application "Finder" --Finderに命令
            set theFile to file tryCount of theFolder --分別のきっかけとなるファイルを指定
            set theFileName to (name of theFile) as Unicode text --ファイルの名前を取得
        end tell --Finderへの命令終了
    on error --ファイルを検索し終えた場合にエラーが出る
        activate --このスクリプトを最前面に呼び出して
        display dialog "処理が終了したようです.
       
ちゃんと分別されたか、Finderのウィンドウで確認してみてください.

分別対象以外のファイルはそのまま残っています." with icon note buttons {"OK"} default button 1 giving up after 15 --処理終了を報告する
        exit repeat --無限ループから脱出
    end try --故意エラーへの対応終了
   
    if theFileName ends with nameExtension then --もしファイルが対象ファイル形式だったら
        set nameArray to text items of theFileName --ファイル名をリスト(配列)分解
        set fileNameCheckIsOK to length of nameArray > cutNameSliceEnd --ファイル名が規定を満たすかをチェック
        if fileNameCheckIsOK then --もしファイル名が規定を満たす場合
            set tryCount to tryCount - 1 --検索ファイルのカウントを1つ戻す(カウントの空滑りを防止)
            set cutName to (items cutNameSliceStart thru cutNameSliceEnd of nameArray) as Unicode text --カット名をファイル名から抽出する
            do shell script "mkdir " & quoted form of POSIX path of (folderPath & cutName) --フォルダをシェルで作る
            do shell script "mv " & (quoted form of POSIX path of (folderPath & cutName)) & "_*" & nameExtension & " " & quoted form of POSIX path of (folderPath & cutName) --対象ファイルをカット名フォルダに移動する
        end if --ファイル名チェックの「もし」の範囲、ここまで
    end if --対象ファイル形式の「もし」の範囲、ここまで
end repeat --無限ループの範囲、ここまで

set AppleScript's text item delimiters to "" --リスト分解の設定を初期値に戻す

tell application "Finder" to activate --Finderを最前面にする

return tryCount --検索ファイルの最終カウントを結果として戻す


コメントを入れたおかげで、余計、長く感じられますが、まだシンプルなほうだとは思います。やっている事が、単にファイルの分別ですからネ。テスト用の偽物ファイルを作るところからやっているので、長くなっているのですネ。

動作中のスクリーンショットは、こんな感じ。

スクリプトを実行すると、デスクトップに日付のフォルダが自動生成され、その中に数秒後、テスト用のダミーファイルが大量生成されます。

5040個の連番ファイルと、故意に混ぜた関係のないファイル6個。変更日でソート表示されてるので、並びはバラバラですが、ウィンドウ下部の項目数に注目してください。





…実際に作ったのは、上記の通り、5040+6で5046ファイル。

「分別を処理してみる」ボタンをクリックすると、数秒後‥‥

‥‥のような感じで、思惑通り、カット名を持つ連番ファイルだけが、分別されました。イジワルな名前の混在にもメゲず、ちゃんとカット名連番だけを見分けて、新規フォルダを作って格納しています。

種類でソートすると、こんな感じ。

めでたく、終了。5046項目のごちゃまぜファイルが、数秒で、スッキリ、13項目に整理されました。


たとえ、以前にレンダリングしたQTファイルや、とりあえず置いといたJPEGファイルがあっても、「カット名を含む、DPX」以外は処理対象から外すので大丈夫なのです。

また、作品や話数がごっちゃになっていても、「カット名の命名規則に準じて」ファイルを選別するので、問題無いのです。

スクリプトの文中に目を通すと、AppleScript独特の表現もちらほら見えます。「AppleScript's text item delimiters」なんてのは、その最たるもので、私はこれが面倒でイヤなんですが、要は「テキストの要素を分解する文字」の事です。これを操作すると、文字列を任意の文字で分解できるようになります。

ファイルを分別するくだりは、目の前にあるものを処理して、もし対象外のものだったら、一歩進む‥‥という、何とも可愛い動作にしてあります。一歩進む‥‥とは、「自分のいる位置のカウントを1つ足す」という事ですが、AppleScriptには「++」なんてシャレたものはないので、set その変数 to その変数+1 みたいにして、地道に書きます。

Finderは言わば窓口。そこに大量の物品を持ち込んでもパニックになるだけです。窓口で簡単な手続きを済ませたら、後は頼りになるバックヤードでドカンと大量処理するのです。

しかし、AppleScriptに馴れていない人が、上記スクリプト文を読んでも、理解できないかも知れません。コメントだけ読んで、流れを汲んでもらえればと思います。文中の細かい説明はまたいずれ。

今回はダミーファイルまでも作るデモ的なスクリプトですが、文中後半の「ファイル分別ルーチン」を抜き出してちょっと手直しすれば、汎用性があって何度でも使い回しのできる、連番分別アプリケーションに育てる事ができます。

次回は、似たようなスクリプトを使って、「作業者にツッコミをいれる」スクリプトを作ってみます。データベースを使わなくても、スクリプト自身が判断して、「ほんとに、その尺で合ってる?」とユーザに確認してくるのです。

ではまた。


calendar

S M T W T F S
     12
3456789
10111213141516
17181920212223
24252627282930
31      
<< December 2017 >>

selected entries

categories

archives

profile

search this site.

others

mobile

qrcode

powered

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