音に合わせたコンポ配置をタイムリマップで楽にする話

まつらいです。

最近作成した*Lunaさんの「コンシーテッド・ボーイ」のピアノソロ部分等、「特定の短いコンポジションを大量に使用したい」場合というのが、AE使いには稀によくあることかと思います。主には波紋のようなエフェクトだったりとか。
それのスマートめな組み方を考えてみましたので、書き残しておきます。

続きを読む 音に合わせたコンポ配置をタイムリマップで楽にする話

同人会計レコーダー(仮)について

今回のアプリは、イラストレーターの桜木蓮さんから「毎回計算が苦手で会計が大変なのでなんとかしたい」とのお話を受け、簡単に会計記録ができることを目的に作りました。

おおまかに、

  • 代金計算
  • 会計記録&ターゲット調査
  • CSV書き出し
  • 複数人編集

の機能を備えています。

このアプリは「一人で使うならオフラインでも使える」ことを前提に設計されており、サーバーでのデータ保存などは一切行っていません。
複数人編集においても、データをサーバーに保存せずに実装しています。

とりあえず試してみたいという方は、[CONFIGからダミーを入れる]を押してから始めてください。

代金計算

  • 選択したアイテムの合計金額を出します。複雑な足し算でも即座に対応できるでしょう。

  • アイテム追加はメニュー左のADDから行います。

  • アイテムの選択解除は長押しで行います。
  • アイテムの削除は2本指タップで行います。

会計記録&ターゲット調査

  • 全ての会計履歴を記録し、その日の総売上であったり実際に買ってくれた人数、各アイテムそれぞれの頒布数なども記録します
  • 同時に、購入者情報登録のチェックを入れることにより、買った人の性別/年代を記録することも可能です。
  • この機能はCONFIGからオフにすることが可能です。

CSV書き出し

  • ブラウザに保存したデータを、ExcelやGoogleSpreadsheetで読み込み可能なcsv形式のファイルとして書き出すことができます。
  • 半年後の自分のために大切に保管しましょう。

複数人編集

  • 売り子が複数人いる場合などに備えて、複数人で同時に記録できるモードを用意しています。
  1. まずはアイテムの登録を完了させてください。
  2. configから複数人編集のチェックをオンにし、共有キーと名前を入力して接続してください。
  3. 接続ボタンの下に現れる共有用リンクをコピーし相手に渡してください。相手側はそのリンクから名前を入れ、接続します。
  4. データを共有したい側から「相手へ共有」のボタンを押すことで、相手側にデータが送信されます。
  5. 以降、会計記録時に手元のデータがサーバーに送信され、おなじkeyを持っている人のデータが全て更新されます。

github:
https://github.com/matsurai25/cashier

AfterEffectsでMIDIにあわせた映像作りができるスクリプトを作った話

PutOnNote

上のツイートのように、AfterEffectsにMIDIファイルを読み込み、音楽との正確な連携を行うためのスクリプトを作成しました。
選択中のアイテムをMIDIにあわせて配置したコンポジションを作成します。

ダウンロードはここから

使い方

  1. 複製したいコンポジションを選択した状態で実行
  2. MIDIを選択する
  3. MIDIに合わせてコンポジションを置きまくったコンポジションが幾つか作成される
  4. 位置など細かい変更を加えたい場合はapplyTargetOptionを変えると良い

使用上の注意

  • 全パート入のMIDI等を読み込むと非常に重くなることが予想されるので、DAWや何かでパート分けしてから読み込んだほうがイイです。
  • 適宜ソースコードを書き換えて使用して下さい。
  • 使用報告は不要です。あれば喜びはします。
  • 使用に関する責任は負いません。

respected


音と完全に同期した映像を作るために「ムゲンノツバサ」の歌詞すべてや、「星屑オーケストラ」のピアノソロ以降にあるような、MIDIを読み込んでAfterEffects上に反映させると言うものを、自分でom_midi(ヌルとスライダーを生成して、MIDI情報をエクスプレッションでとりやすくしてくれる)をフォークして何度か行なってきました。

QiitaでたまたまJavaScriptでMIDIファイルを解析してみるの記事を見たこともあり、改めて「音に対してアイテムを配置する」というスクリプトを、練習中のCoffeeScriptで自作してみることにしました。

MIDIの全トラックの音を読み込みますので、かなり重くなることが予想されます。
DAWやらドミノやらでMIDIを編集してからやると良いかもです。

配置の位置やスケール、コンポジション分けをする数などはソースコードをみてちょいちょい変えてみてください。

やっぱり音と完全にあった映像はよい。ProcessingとかopenFrameworksとかも手を出してAEに突っ込んでみたい。

ソースは以下のgist
できれば強い人に改善して欲しい・・・

https://gist.github.com/matsurai25/2a1d96a3c6ee7217cfc5

ムゲンノツバサを支える技術

まつらいです。
今回、ハヤブサ氏の4曲目「ムゲンノツバサ」のPVを作成するにあたって、非常に多くの時間とこだわりを持って作成いたしました。
その手法と意図を書き残すことによって、どこかの誰かの助けとなればと思い、テキストで残しておくことにします。

ちなみにこの曲です。

目次

使った表現の解説

  1. ライトリーク
  2. Element3D
  3. Plexus
  4. Particular
  5. Mir

スクリプトによる効率化

  1. 【おまけ】よく使うスクリプトの紹介
  2. 色管理を効率化
  3. コンポ名による値の管理
  4. 文字コンポを歌詞の文字種分だけ複製
  5. タイムリマップで文字アニメーションを自動化
  6. 【おまけ】AfterEffectsプロジェクトをGitHubで管理する話

順番に解説していきます。


使った表現の解説

あの表現ってなんていうんだろう。どう作ってるんだろう的な話。
この辺の単語を使うとAE中級者っぽく見えます。
いずれも細かい言及はせずに、こういうので作れるんだなー程度に書いていきます。

01. ライトリーク

この動画のキモ。最近流行りのライトリークさん。今回はmBurnsという素材集を導入した直後ということもあり、全編においてライトリーク祭になっております。
トランジションとして使うときは、素材を描画モードスクリーン等で加えていって真っ白になるタイミングで画面を切り替える感じです。
色付けとして使うときは描画モード覆い焼きカラーにして上に重ねたり、デュレーションを縮めて早めに点滅させるようにしたりしています。
色味は素材のまま使ってることが多いですが、一部彩度/色相をつかって調整しています。

(Twitchと同じで数年後には「あぁ〜〜〜2015ねん〜〜」って表現になる気がします)
参考:[link] バカ・アフター 雑記 After Effects 間違ったエフェクト辞典 3巻

02. Element3D

AE上で3Dモデルが使えるようになるプラグイン、Element3D。最近v2が出たようですが僕のは旧バージョンのままです。
ワイヤーフレーム表示でも結構かっこよくなるので多用しています。
オルゴール自体のモデルはフリーの3Dモデルを使っています。(テクスチャだけちょっといじってます)
最初はBlenderでガッツリ作ってたのですが、あんまり美しくならなかったので・・・

.mtlをBlenderでpngとして書き出してPhotoshopでちょっと改変(Falconnect文字入れ、地味にモールス信号で模様入れ)して使用しています。
その途中で試しに最高の空をテクスチャにしてみたところ綺麗になったので、点滅させる感じでいろんなテクスチャやワイヤーフレームを表示する形になりました。

03. Plexus

空間A(グリッド)

Plexusで作るグリッド的な空間。
お手軽にデジタルな感じを作れるので良い。

具体的にはPlexusでPrimitive Object->Cubeを配置してポイント数を増やし、Renderer->Linesで上下左右の線を加えています。
Particularと同じくレイヤーで完結していて、他の3Dレイヤーと合わせて上下関係出すには難しいので、使用する際は基本的に単色or背景だけにして誤魔化しています。

空間B(いつもの)

いつもの。よく見るやつ。
とりあえずPlexusを買ったら一度はやるやつ。などなど。

Renderer->LinesEffector->Noise->Positionでいい感じの値を指定するといい感じに出来ます。
今回の場合はRSMBのブラーがいい感じに効くようにかなりZ軸広めに散らかして動かしまくってます。

今回自分の中で綺麗にできて嬉しかったシリーズその一。
Plexusのパス読み込み機能などを駆使して翼を作ります。

フリーのシルエットサイトAllSilhouettesから翼のパスを拝借しました。
AIからパスをコピー、Plexusのレイヤーに貼り付けマスクとし、Paths Objectで指定したマスクを読み込んでポイント数を調整、Effector->Noise->Positionでブラします。
Ctrl+Dで複製し、片方にEffector->Noise->Colorで色をランダムにし、Renderer->Beamで一方向の線を描きます。
もう片方にRender->Trianglationで適度に三角形を置き、先程のレイヤーを上からスクリーン等で重ねて完成です。

色変更とBeam+スクリーンの組み合わせは一気にデジタルな感じが出て強いので、今後も活用したいですね。

ハート

今回自分の中で綺麗にできて嬉しかったシリーズその二。
詳細は割愛。

ハートはフリーのOBJをOBJ Objectで読み込んでいます。
wireframeの部分は普通にポイントを置いてRenderer->Linesで。
元のモデルのポイント数が多くあまり綺麗にできなかったので、BlenderのモディファイアDecimateを使用してポリゴン数を減らしてます。
シェイプレイヤーのグラデーションを使って色味を調整。ピンク→灰色→水色になるように調整。
それにOpticalFlaresを加えて完成です。

地味に炎を合成してますがあってもなくても変わらないレベルなので割愛

04. Particular

動画後半になるに連れ、画面上に飛んで来る羽。画面上に常に動きを出せるので豪華に見えます。

Trapcode Particularで羽を飛ばしてます。羽の素材はシルエットデザイン様より。
遠景用のレイヤー近景用のレイヤーで2つ用意。それぞれパーティクルに羽を設定し、windの値を制御して左上に飛ぶようにします。前のほうが動きが早くて大きい。
また、Particularの仕様なのか、タイムリマップで過度に遅くすると各パーティクルの上下が反転する現象がある(?)ので、一度透過AVIで書きだしたものをAEのピクセルモーションで補完していたりします。なぜなんだ・・・

05. Mir

Mirで作る雷の表現。
詳細はバカ・アフターさんが書いてるこちらの記事で。
[link] Trapcode Mirを使った雷 at AEP Project

今回の場合は雷と同時に数フレームの間背景の露出を上げ、前景のキャラの露出を下げて、臨場感を出すようにしています。
参考にしました→あの、少し ドラゲナイwwドラゲナイww とこがあるんだけど – ニコニコ動画:GINZA

見てたら思いつきました

筆っぽい表現

同じくMirで作る筆でバッと書いたような表現。
上の雷を更に縦に引き伸ばして作ってます。

色は基本的に後述のランダムな色を使ってますが、どうしても「唐突に画面に出てきた」感が否めずに、最初数フレームにライトリークで白飛びを入れていたりします。
具体的にはCメロ明けの小サビ。

以上でエフェクト主体の話は終わりです。
なんかの助けになれば幸いです。なるのか?
細かい説明とか欲しいところあれば、Twitterでこの記事のリンクと一緒に言及してくれれば拾います。

ここから先はめんどくさくて面白い話をします。

スクリプトによる効率化

よく使うスクリプトの紹介

  • MarkerConductor : BPMにあわせてマーカーを打ってくれます。音合せには必須です。
  • CurrentTimeSnapShot : ワンクリックで現在位置のpngを書き出します。共有に便利。
  • sceneSplitter : マーカーに合わせてシーンごとにコンポを切ります。
  • RepositionAnchorPoint : 位置を移動させずにアンカーポイントを真ん中に移動できます。
  • AddOpticalFlares : いい感じにOpticalFlaresを配置してくれます。つよい。

色管理を効率化・ランダムカラー

動画内で使用したい色は、予め配色含めしっかり決めておきたい派です。
さらにもし後々色の変更があった時に、全部の色を一発で変えたい

そう思って、最近は全部エクスプレッションで管理するようになりました。
僕が動画内で多用している、一定の色をランダムでパカパカするやつもエクスプレッションで実装して、一つの色として使用しています。

// ■ 使い方(名前等は一例)
// 1.「_global」コンポジションを作る。
// 2.テキストレイヤーを作り、このエクスプレッションをコピペ、レイヤーを「exp」という名前に変更。
// 3.使いたい色の場所でエクスプレッションを開き、
// -> ランダムな色
//    eval(comp("_global").layer("exp").text.sourceText.value); // 読み込み
//    randomColor(time,3); // 出力
// -> 特定の色
//    eval(comp("_global").layer("exp").text.sourceText.value); // 読み込み
//    colors.red; // 出力()


// 使う色を宣言する
var colors = {};
colors.darkblue = color16("103896");
colors.yellow = color16("FFE900");
colors.green = color16("1dbdcd");
colors.lightblue = color16("8ceff5");
colors.pink = color16("e22d6e");
colors.gray = color16("363636");
colors.blue = color16("205cde");
colors.orange = color16("FFA541");
colors.white = color16("ffffff");

// 16進数を100分率のrgba配列に
function color16(rgb){
  c = 1/255;
  red =parseInt(rgb.substring(0, 2), 16);
  green =parseInt(rgb.substring(2, 4), 16)
  blue =parseInt(rgb.substring(4, 6), 16)
  return [c*red,c*green,c*blue,1];
}

// 指定した色の数をカウント
function countColors(obj){
    var colorsCount = 0;
    for(var j in obj){
        colorsCount++;
    }
    return colorsCount
}

// keyの配列を作成
function getColorsKey(obj){
    var colorsKey = [];
    for(var j in obj){
        colorsKey.push(j)
    }
    return colorsKey
}

// timeを受け取って順番に色を変える
// frameがある場合はそのフレームごとに色を変更
function randomColor(time,frame){
    if(typeof(frame) == "undefined") {
        frame = 1;
    }
    var t = Math.abs(timeToFrames(time, fps = 1.0 / thisComp.frameDuration, isDuration = false))
    var keys = getColorsKey(colors);
    var size = countColors(colors);
    var num = Math.floor((t / frame) % size);
    return colors[keys[num]]
}


余裕が有るときに使いやすいようにリファクタリングします。

参考aep:[DL]matsurai25_色管理の例.aep

コンポ設定による値の管理

セリフの背景ウィンドウが同じ動きだけどサイズだけ変えたいなーと思い、コンポジションの横幅縦幅から自動でリサイズするように設定。
コンポジション自体を複製してサイズを変更することで、中のアニメーションのアスペクト比を保ったままスケールを変更できるようにしました。

//こんな感じで取得できます
w = thisComp.width;
h = thisComp.height;

文字コンポを歌詞の文字種分だけ複製


今回特に力を入れた事に、テキストレイヤーのアニメーションではできないことを如何に実装するかというのがあります。

結果、
① 文字を一文字だけ表示するアニメーション付きのコンポジションを作成し、
② その文字にコンポ名から切り出した文字を入れるようにし、
③ 後説のタイムリマップ法で使う

という使い方になりました。えげつない。

とりあえず歌詞文字分のコンポジションを手で用意するのは面倒だったので、下記のようなスクリプトを作成しました。
これでコンポジション名に任意の文字を入れ、それを内部から参照して表示しています。


// コンポジションを選択した状態で実行、文字列を1文字ずつ分解して、その文字数分だけコンポジションを複製して"prefix"+letter+"suffix"の形で保存 var Lyrics = "空を見上げ僕らは夢見た あの鳥のような翼を 夏の陽炎が君を消した あの空に行ってしまったの? 残された手紙握り締め 今決めた 君を探すため空へ飛ぶんだ 作りかけの翼が大空へと羽ばたく時 きっときっと叶うだろう 僕たちが描いた夢が 空の上の世界できっと君は待ってるから 無限の夢翼に乗せ いつの日か飛んでみせる 難しい本片手に作る この空を飛べる翼を 雨上がりの空架かった虹 今君もどこかで見てる? 君への思いを握り締め さあ時は満ちた走り出せ 翼を広げ 小さなこの翼が大空へと今羽ばたく 高い高いこの景色を なあ君も見ていたんだろ? 空の上の世界へあと少しで辿り着ける 無限の夢翼に乗せ 届けるよこの気持ちを 荒れ狂う空 折れた翼 僕は空を飛べないの? 霞む意識に響いた少女の声 「解き放て ムゲンノツバサ」 天使のような翼が 光纏い僕を包む 青い青い空の下で また君に出会えた奇跡 夢を乗せた翼が たとえ幻だとしても 夢幻の彼方の世界へ 君となら飛んで行ける".split(''); var prefix = "letterA_"; var suffix = "_light"; // forEach使えないので使えるように // Production steps of ECMA-262, Edition 5, 15.4.4.18 // Reference: http://es5.github.com/#x15.4.4.18 if ( !Array.prototype.forEach ) { Array.prototype.forEach = function( callback, thisArg ) { var T, k; if ( this == null ) { throw new TypeError( " this is null or not defined" ); } var O = Object(this); var len = O.length >>> 0; // Hack to convert O.length to a UInt32 if ( {}.toString.call(callback) != "[object Function]" ) { throw new TypeError( callback + " is not a function" ); } if ( thisArg ) { T = thisArg; } k = 0; while( k < len ) { var kValue; if ( k in O ) { kValue = O[ k ]; callback.call( T, kValue, k, O ); } k++; } }; } var activeItem = app.project.activeItem; var letters = []; var flag; letters.push(Lyrics[0]); for(var i = 0; i < Lyrics.length; i++){ flag = true; for(var j = 0; j < letters.length; j++){ if(Lyrics[i] === letters[j]){ flag = false; } } if(flag){ letters.push(Lyrics[i]); } } if ((activeItem == null) || !(activeItem instanceof CompItem)) { alert("コンポジションを選択した状態で実行しよう"); }else{ letters.forEach(function(_){ var curComp = activeItem.duplicate(); curComp.name = prefix+_+suffix; }) }

タイムリマップでアニメーションを自動化

いちいち各レイヤーにキーフレームなんて打ってられるか!!!

ということで、6秒のコンポではじめと終わりのアニメーションだけ作成して、コンポのインポイントとアウトポイントから自動で判定
全てにおいて使いまわしが効きます。

アニメーションのコンポジションを作成したら、使いたいコンポジション側に配置、タイムリマップを使用可能にして以下のエクスプレッションをコピペ。

2015/12/15 更新しました
2016/01/03 ちょっと読みやすく更新

// タイムリマップでアニメーションを自動化

// options
var originDuration = 6; //自動化したいコンポジションの本来の秒数
var effectSpeed = 2; //何倍の早さで動かすか

var fps = 1.0 / thisComp.frameDuration
var fadeTime = (originDuration/2) / effectSpeed; // エフェクトの移行時間
var ignoreFrame = 1/(fps*effectSpeed); //フレームの端数(一応)
var retval;

if( time >= outPoint - fadeTime ){
  // レイヤーの終わりの処理
  retval = originDuration - (outPoint-time) * effectSpeed - ignoreFrame;
}else if( time <= inPoint + fadeTime ){
  // レイヤーのはじめの処理
  retval = (time - inPoint) * effectSpeed;
}else{
  // 途中では値を固定する
  retval = (originDuration/2) - ignoreFrame;
}

// return
retval;

これはAEオフでyama_ko大先生が話していたタイムリマップを使った値の一元管理の話を元に作成しました。
yama_ko大先生のAEオフでの公演はこちら→【AEオフ2015】キーフレーム補完計画

【おまけ】AfterEffectsプロジェクトをGitHubで管理する話

今回、SourceTreeを使って作業中のプロジェクトをGitHubで管理するということを行ってみました。
これを行うことで、下記のような恩恵を受けることができます。

  • コミットログによる進捗の共有 : イラストレーターや音源制作者など他のメンバーへの進捗共有が可能です
  • 別端末での作業 : 限界はありますが、外出先でスクリプトの調整などを手軽にできます
  • 作業の公開 : 作成したAEPをそのまま公開し、意見をもらったりできるかもしれません
  • 公開による作業の透明化 : 自分の作業が他人にも見える状況になるので、ライセンスをちゃんとまとめたり、コンポを綺麗に作ったりという意識が生まれるかもしれません

参考までに : https://github.com/matsurai25/Mugen-no-Tsubasa (AEPも落とせます)

なぜSourceTreeかというと、AEで作業をしているWindows環境でのCUI使用に慣れないからです。

最後に

というわけで、ムゲンノツバサを作る上でやっていたことを改めてちゃんとまとめ直してみました。
意味のわからないところ多々あると思いますが、参考になれば幸いです。

昨年末からちゃんとエンジニアっぽいことをするようになり、段々とエクスプレッションやスクリプトも書けるようになってきました。
あかつきみさき氏的なAEスクリプターになれるように頑張ります。

宣伝

  • Bricks : イラストレーター向けの個人サイトをツイッターから更新できる感じで作ろうという企画。
    はじめにテストも兼ねて使ってくれる人を募集中。協力者にはデザインもその人用に開発します。
  • dm-checker : 同人音楽イベントをうまいことやろうというアレ。

同人音楽イベントチェックツール、「dm-checker」を公開しました

以前作成したM3Viewerから発展して、「dm-checker」として新たにツールを作成しました。
フォローからの取得以外に、タグ検索やレコメンド機能、マップ表示なんかも付けてます。

続きを読む 同人音楽イベントチェックツール、「dm-checker」を公開しました

タイムリマップを使ったフォントアニメーションについて

まつらいです。

以前AEオフの時にyama_koさんが「タイムリマップを使った一次元管理」の中でタイムリマップの有用性について話していたので、今回はそれを使ってアニメーションの複製をしてみます。

今回作るのはこのアニメーションです。

今作っている映像用に作った諸々ですが、せっかくなのでチュートリアル的なのを公開。

ついでに最近ハマってるランダムに色を変更しながら表示、みたいのも作ります。

続きを読む タイムリマップを使ったフォントアニメーションについて