AfterEffectsでSkipFrameを指定するScriptUIを作ってみた

前回の記事で『AfterEffectsで設定したフレーム分スキップして出力する方法』というのを書きました。


@naritasayjingさんから教えて頂いた方法でも十分だったんですが、

AEのスクリプトというか

ScriptUI の勉強も兼ねて

SkipFramesをUI上で確認&セットできないかな~と調べて、しばらく格闘していました。

 

そして、ようやくそれっぽいものができました!


上記の画像のレンダーキューとかの右側のReloadボタンがついてるのが今回作った

ScriptUI です。

レンダーキューの増減があったらReloadボタンを押して下さい。

あとは設定したいキューのところに設定したいスキップ数を入れればいいだけです。

 

まだ欠点があります。

1,プロジェクトファイルを開いたら、このスクリプトのウィンドウも開き直さないといけない。

2、スクロールバーの挙動があまりうまく行っていない。

 

本当の理想はレンダーキューの増減したのを取得、

もしくはそれを監視してReloadボタンを押さなくて自動で変更できればなぁと思っていますが

こちらは上記2つよりもさらにハードルが高そうな気がしています…(;´Д`)

 

下にスクリプトを貼っておきますので、

もし上記問題の解決方法などお分かりになる方がいらっしゃいましたらご教授頂けると助かります。

 

使う方いらっしゃるか分かりませんが、一応このjsxファイルのDLリンクも貼っておきます。

ちなみにCS5とCCでの動作は確認しましたが他のバージョンでは未確認です。

 


function createUI(thisObj) {
    
    var activeItem = app.project.activeItem;
    var win = (thisObj instanceof Panel) ? thisObj : new Window("palette", "RenderSkipFrameSetting",  [ 0, 0, 120, 400 ] );
    //minimumSizeを指定してないとboundsで取得できる値が想定外の数値になる
    win.minimumSize.height = 400;
    win.minimumSize.width = 120;
    var winTop      = win.bounds.top;
    var winBottom = win.bounds.bottom;
    var winLeft      = win.bounds.left;
    var winRight    = win.bounds.right;
    
    var reloadButton = win.add("button", [0 , 0 , 100 , 20 ] , "Reload" );
    var winTxt1Arr = new Array();
    var winTxt2Arr = new Array();
    var winIptArr  = new Array();

    if (activeItem != null ) {
                var RQ = app.project.renderQueue;
                var RQCount =  RQ.numItems;
                
                var scrollBar = win.add("scrollbar", [ winRight - 30 , win.bounds.top + 30  , winRight - 10  , winBottom ]);
                scrollBar.jumpdelta = scrollBar.bounds.height ;
                scrollBar.maxvalue = RQCount;
                scrollBar.maximumSize.height = winBottom;

                //RenderQueueのカウントが0からではなく1から始まってるので i = 1 でまわす。そのため範囲もRQCount + 1
                for (var i = 1; i < RQCount+1 ; i++){
                    winTxt1Arr[i] = win.add("statictext", [winLeft + 5   ,  40 + 50 * (i -1) , winLeft + 110  , 60 + 50 * (i -1) ] ,"RenderQueue_" + i );
                    winTxt2Arr[i] = win.add("statictext", [winLeft + 15 ,  60 + 50 * (i -1) , winLeft + 75    , 80 + 50 * (i -1) ] , "Skip Frame :" );
                    winIptArr[i] = win.add("edittext"     , [winLeft + 75 , 60 + 50 * (i -1)  , winLeft + 110  , 80 + 50 * (i -1) ] , RQ.item(i).skipFrames );
                    //なんとなく文字色をAEのオレンジとあわせる。そのままだと見えづらいので背景も黒くする
                    winIptArr[i].graphics.foregroundColor = winIptArr[i].graphics.newPen(winIptArr[i].graphics.PenType.SOLID_COLOR, [204/255, 150/255, 0/255],1); 
                    winIptArr[i].graphics.backgroundColor = winIptArr[i].graphics.newBrush( winIptArr[i].graphics.BrushType.SOLID_COLOR , [ 0/255, 0/255, 0/255, 1 ] , 1 );
                    winIptArr[i].name = i;
                    //中央に揃える
                    winIptArr[i].justify = "center"; 
                    
                    winIptArr[i].onChange =  function(){
                         //入力された数字かどうかチェック(Nan はnot a Numberの略)
                        if (isNaN(this.text) == true ){
                            alert("数値を入力して下さい");
                            this.text = RQ.item(this.name).skipFrames;
                        }else{
                            RQ.item(this.name).skipFrames = parseInt(this.text, 10);
                        }
                    }
                }

            //=================================================================================
            //↓リロードボタンを押したときの処理
            reloadButton.onClick = function(){ 
                //表示しているものを一度removeする( 配列を空にするだけだと表示が残るのでremove )
                for ( h = 1; h < winTxt1Arr.length ; h++){
                    win.remove( winTxt1Arr[h] );
                    win.remove( winTxt2Arr[h] );
                    win.remove( winIptArr[h] );
                }
                
                //removeしただけだと配列の数が変わらないので空にする
                winTxt1Arr = [];
                winTxt2Arr = [];
                winIptArr = [];
                
                var RQCount2 =  RQ.numItems;
                
                for ( j = 1; j < RQCount2 + 1 ; j++){
                    winTxt1Arr[j] = win.add("statictext", [winLeft + 5   ,  40 + 50 * (j - 1) , winLeft + 110  , 60 + 50 * (j - 1) ] , "RenderQueue_" + j );
                    winTxt2Arr[j] = win.add("statictext", [winLeft + 15 ,  60 + 50 * (j -1)  , winLeft + 75    , 80 + 50 * (j - 1) ] , "Skip Frame :" );
                    winIptArr[j] = win.add("edittext"     , [winLeft + 75 , 60 + 50 * (j - 1)  , winLeft + 110  , 80 + 50 * (j - 1) ] , RQ.item(j).skipFrames );
                    //なんとなく文字色をAEのオレンジとあわせる。そのままだと見えづらいので背景も黒くする
                    winIptArr[j].graphics.foregroundColor = winIptArr[j].graphics.newPen(winIptArr[j].graphics.PenType.SOLID_COLOR, [204/255, 150/255, 0/255],1);
                    winIptArr[j].graphics.backgroundColor = winIptArr[j].graphics.newBrush( winIptArr[j].graphics.BrushType.SOLID_COLOR , [ 0/255, 0/255, 0/255, 1 ] , 1 );
                    winIptArr[j].name = j;
                    //中央に揃える
                    winIptArr[j].justify = "center"; 
                    
                    winIptArr[j].onChange =  function(){
                        //入力された数字かどうかチェック(Nan はnot a Numberの略)
                        if (isNaN(this.text) == true ){
                            alert("数値を入力して下さい");
                            this.text = RQ.item(this.name).skipFrames;
                        }else{
                            RQ.item(this.name).skipFrames = parseInt(this.text, 10);
                        }
                    }
                }
            }
            //=================================================================================
            //↓スクロールバーを動かしたときの処理
            scrollBar.onChanging = function(){
                if (scrollBar.enabled == true){
                    //スクロールバーに合わせてテキストを移動させていく
                    for(var k = 1; k < winTxt1Arr.length ; k++){
                        winTxt1Arr[k].location.y = -1 *  (this.value * (win.minimumSize.height - win.bounds.bottom + 120 ) / 20 )+ 40 + 50 * (k-1);
                        winTxt2Arr[k].location.y  = -1 *  (this.value * (win.minimumSize.height - win.bounds.bottom + 120 ) / 20 )+ 60 + 50 * (k-1);
                        winIptArr[k].location.y  = -1 *  (this.value * (win.minimumSize.height - win.bounds.bottom + 120 ) / 20 )+ 60 + 50 * (k-1);
                        //各テキストの位置がグループの上を超えたら非表示にしていく
                        if ( winTxt1Arr[k].location.y  < win.bounds.top + 20 ) {
                            winTxt1Arr[k].visible = false;
                            winTxt2Arr[k].visible = false;
                            winIptArr[k].visible  = false;
                        }else{
                            winTxt1Arr[k].visible = true;
                            winTxt2Arr[k].visible = true;
                            winIptArr[k].visible  = true;
                        }
                    }
                }
            }
            //=================================================================================
            //↓ウィンドウサイズを変更したときの処理
            win.onResize = function(){
                var b = this.bounds;
                 //ウィンドウの幅が120以下だったらスクロールバーを非表示にする
                 if (this.bounds.width > 120){
                    scrollBar.visible = true;
                    scrollBar.bounds = [ this.bounds.right - 30 , this.bounds.top + 30 , this.bounds.right - 10  , this.bounds.bottom ];
                }else{
                    scrollBar.visible = false;
                }
                //スクロールバーの高さがテキストたちの高さ×数以上だったらスクロールバーを使えないようにする。
                //その際にバーが動いてる場合があるので一番上に戻して、非表示になっていたテキストたちを表示する
                if(scrollBar.bounds.height + 40 >= winTxt1Arr.length * ( winTxt1Arr[1].bounds.height + winIptArr[1].bounds.height) ){
                    scrollBar.value = 0;
                    scrollBar.enabled = false;
                    for(var l = 1; l < winTxt1Arr.length ; l++){
                        winTxt1Arr[l].visible = true;
                        winTxt2Arr[l].visible = true;
                        winIptArr[l].visible  = true;
                        
                        winTxt1Arr[l].location.y =  40 + 50 * (l-1);
                        winTxt2Arr[l].location.y  = 60 + 50 * (l-1);
                        winIptArr[l].location.y  = 60 + 50 * (l-1);
                    }
                }else{
                    scrollBar.jumpdelta = scrollBar.bounds.height;
                    scrollBar.enabled = true;
                }
                this.bounds = b;
            }
    }
}
createUI(this);


参考にさせて頂いたサイト様

・ScriptUI の基本コントローラ一覧|おいしいAS3
http://ameblo.jp/synchro-vision/entry-10551376768.html

・Up Box ~CS2 & CS4 Scriptなど。。。。
http://curryegg.blog.shinobi.jp/

・ScriptUI for dummies | Peter Kahrel
http://www.kahrel.plus.com/indesign/ scriptui .html

・AEスクリプトGUI篇 誰もalert()なんて読みやしねぇよバァ~カ - たこなぐりの日々
http://d.hatena.ne.jp/Takomaru/20120719/1342689821


あとは、JavaScriptToolsGuideなどを読んでました。