LoginSignup
8
8

More than 5 years have passed since last update.

【AfterEffects】エクステンションとWebSocketでMIDIのイベントを受け取って遊ぶ

Last updated at Posted at 2017-02-25

PhotoshopをMIDIで操作する端末等を見ていたら面白そうだったので、とりあえずAfterEffectsもMIDIを受け取って制御してみることにします。

AE前提で書いていますが、基本的にはエクステンションの無いようなのでAE以外のAdobe製品でも使えます。

必要なもの

  • AfterEffects
  • Node.js v6以下 (fsまわりを使用しているMIDIライブラリの関係)
  • nanoKONTROL2 ¥4000円ぐらい

全体図

今回は、Node.jsでMIDIを聴いてイベントを出すwebSocketサーバーを立てて、それをエクステンションで受け取る形で実装します。

2017-02-25.png

ソースはこちらで公開しています。
https://github.com/matsurai25/zxp-midi

server

const app    = require('http').createServer();
const io     = require('socket.io')(app);

app.listen(39393);
io.on('connection', function(socket) {
  // 接続された
  console.log('connection established');
});

Node.jsでサーバーを建てます。

const Korg   = require('./korg.js');
const korg   = new Korg();

let timer;
// 全イベントを聴く
korg.on('*', function(event, value) {

  // フェーダーのイベントが送られ過ぎないように、setTimeoutで
  // イベント後一定期間内に再度イベントがった場合はそのイベントを無視するようにしている。
  if (timer !== false) {
      clearTimeout(timer); // setTimeoutを解除
  }

  timer = setTimeout(function() {
    // webSocketでイベントを送信
    io.emit('midi-event', {
      time:moment().format('HH:mm:ss'),
      type:event.split(':')[0],
      channel:event.split(':')[1],
      value:value
    });
  }, 50);
})

スクリーンショット 2017-02-26 0.56.19.png

MIDIイベントを受け取ってソケットで送ります。
korg.jsではkorg-nano を少々変更し、nanoKONTROL2のMIDIマッピングを受け取っています。
今回のフェーダーではイベントが送られすぎてしまってAE側の動作が重くなってしまったので、setTimeoutで短期間にイベントが送られすぎることを制限しています。

extension

スクリーンショット 2017-02-26 0.57.21.png

AdobeのエクステンションではHTML+jsで色々作ることが出来ます。
つまりはフロントエンド領域の諸々が使えます。

とりあえずなんか良い感じに開発できるセットを作っているので、今回はこちらを使用します
https://github.com/matsurai25/adobe-html5-panel-template

jade/scss等のコンパイル、manifestファイルの設定、zxp署名と書き出しとか出来ます。

vue.js

今回はどんなイベントが来たかをサクッと見るために Vue.js を使用しています。
https://jp.vuejs.org/
日本語ドキュメントがあり、わかりやすいです。

const Vue = require('vue/dist/vue.common.js'); // Vue
const io = require('socket.io-client/dist/socket.io.js');

module.exports = () => {
  const socket = io('http://localhost:39393');
  var app = new Vue({
    el: '#app',
    data: {
      messages: []
    },
    created: function() {
      socket.on('midi-event', (data) => {
        console.log(data);
        this.$data.messages.unshift(data);
      });
    }
  });
};

new Vue()に色々渡してリストレンダリングとイベント設定をします。
createdで指定した関数がマウント完了時に実行されます。
socket.on(key, function)で、指定のkeyのソケットが送られてきた時の処理を行います。
これは受け取ったjsonをとりあえずunshiftmessage配列に入れていっています。DOM側は自動的に更新されます。

    #app
      .message(v-for='message in messages')
        .time
          | {{ message.time }}
        .type
          | {{ message.type }}
        .channel
          | {{ message.channel }}
        .value
          | {{ message.value }}

DOM側ではこんな感じに指定しておきます。
スタイルはscssで良い感じにあてます。

エクスプレッション

スクリーンショット 2017-02-26 1.07.28.png
_sliderというコンポジションを作成し、layerというレイヤーを作成、そこにスライダー制御をいっぱい付けて、それをすべてのレイヤーで参照するようにします。

var s = comp('_slider').layer('slider').effect('slider:'+n)(1);

とかで値を取得できます。

スクリーンショット 2017-02-26 1.06.46.png
とりあえず良い感じに見れるようにしたもの。

スクリーンショット 2017-02-26 1.10.53.png

var k = comp('_slider').layer('slider').effect('slider:1')(1);
effect("色相/彩度")(7)+index*20 + 5*k;

適当に●をいっぱい置いて、色相エフェクトをフェーダーで制御してみます。

aepをこちらに置いておきますので、ご自由にご利用下さい(CC2014)
https://github.com/matsurai25/zxp-midi/blob/master/AE_MIDI_SLIDER_sample.aep

完成

感想

  • エクステンションまわりの記事少ない・・・。
  • manifest.xmlに不要なjsx読み込みが書いてあるとCSInterfaceが動かないという問題にしばらく悩まされました。
  • AE側でリアルタイムに値を制御したかったのですが、いちいちスクリプトを噛ませて実行するとやはり速度に難ありという印象。
  • 選択されているプロパティの数値を上げるとかのショートカットキーがあれば、そちらを再現してあげればよさそう。
  • スクリプトのショートカット割りあてが結構面倒な印象があるので、これとnanoPADを使って良い感じにすれば、結構業務効率向上しそうですね。
  • スクリプトはグローバルを共有しているので、EventEmitterとかをglobalに入れてsocketを通知してあげれば、他のスクリプトでも購読できて良さそう(by かれおばなさん)

以上です。

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8