職場の人の結婚パーティでやったあれこれ

Standard

結婚パーティという大炎上案件が先ほど無事に終わったので、やったことを書きます。
デジタルなことをがっつりお手伝いしました。@ononoさん、@k13styleさん、ボク(@bugcloud)でやってみたいことをいろいろ詰め込んでみたので、これからなんかやる人の参考になればと。
 

やったこと

  • パーティの受付で、お客さん1人1人の動画を撮影してアニメーションGIFに。WEBサイトにアップして、会場内のプロジェクターでスクリーンに投影。
  • ↑のGIFを使ってくじ引き。当選者発表ムービーにGIFを合成。
  • アキラくん(新郎)人形にプロジェクションマッピング。しゃべる人形こわい。
  • 式で撮った写真をウェルカムムービーに。
  • おめでとうムービー。サプライズでアイさん(新婦)のおばあちゃんからのメッセージつき。
  • アキラTシャツ
  • アキラ風船 200個

 
ボクは上2つをやりました。
 

パーティ受付時に、お客さん1人1人の動画を撮影してアニメーションGIFに。

これはもくもく開発会@鎌倉で作ったiPhoneアプリです。このパーティ専用のiPhoneアプリを作りました。撮影した動画をアニメーションGIFに変換してサーバーにアップロードてくれるいい子です。
↓な感じのアニメーションGIF。
gif
100+人の写真を撮れるのか心配だったんですけど、3人で意外にもまわりました。
 

WEBサイトにアップして、会場内のプロジェクターでスクリーンに投影。

↑のアプリで作ったアニメーションGIFを受け付けるサーバープログラムと、それを表示するWEBページを作りました。よく結婚パーティでポラロイドで写真を撮ってボードに貼ってたりするんですけど、あれの写真が動く版です。
http://uploader.あきら.com/gif_images
会場のみんなの見える化wみたいなのけっこうおもしろかったです。前日の夜に@ononoさんと@k13styleさんの意見でアニメーションを再生 → 逆再生のループになるようにアプリを改修したんですが、正解だったなと。いい感じに楽しそう感でました。
 

GIFを使ってくじ引き。当選者発表ムービーにGIFを合成

アップロードされたアニメーションGIFをランダムに抽出するプログラムを書いてくじ引き。事前に@ononoさんが撮影した動画に当選した人のGIFを合成しました。ペラ1の当選結果ページを作って、JavaScriptで動画に合成しています。
↓な感じ
http://bugcloud.com/develop/akira/01/
 
ブラウザのキャッシュで会場にいない人に当たるっていうハプニングがありましたw
 
 

反省とまた機会があれば改善すること

  • とにかく当日の準備時間ない。会場に1時間前に到着するも店に入れてもらえず30分前に会場入り。20分後にはお客さんが入ってくるというドタバタ感。司会の人にだいぶ助けてもらいました。
  • 事前の打ち合わせ足りてない。大人ってそう簡単にみんな集まれない!
  • 会場でシュミレーションしときたい。
  • もっとデザインにこだわりたい。時間さえあれば。
  • 当日のオペレーションでいろいろなんとかなる。基本的にみんな祝に来てるので優しい。
  • 新婦の名前.新郎の名前.com みたいな日本語ドメインはかなりオススメ(nginxで日本語ドメインを設定する方法は → http://qiita.com/bugcloud/items/680c2ced3a268953da6c)

 

感想

身近な人のために書くコードは気持ちがいいよ!
 
 
さいごに
アキラさんアイさん、ご結婚おめでとうございます。
末永くお幸せに。

動画にリアルタイムで合成やフィルタをかけられるSeriously.jsがすごい

Standard

職場の人の結婚式2次会という炎上案件で使ったSeriously.jsというライブラリがやばい。
https://github.com/brianchirls/Seriously.js
 

Seriously.js demo from bugcloud on Vimeo.

 
これ、動画中の赤い色を検出して切り抜く(ブルースクリーン的なやつ)と、動画にASCIIフィルタをかけたやつを重ねてるんですけど、これが↓みたいな短いコードでできます。既存のプラグインを組み合わせるだけでもいろんなことできそう。
 

<!DOCTYPE html>
<html dir="ltr" lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>.dev</title>
    <style>
      video, #canvas, #canvas-ascii {
        left: 0;
        top: 0;
        height: 480px;
        width: 640px;
        position: absolute;
        z-index: 0;
      }

      video {
        display: none;
      }

      #canvas {
        z-index: 1;
      }
    </style>
  </head>
  <body>
    <video id="main-video" autoplay></video>
    <canvas id="canvas" width="640" height="480"></canvas>
    <canvas id="canvas-ascii" width="640" height="480"></canvas>
    <script src="js/jquery.min.js"></script>
    <script src="js/seriously.js"></script>
    <script src="js/effects/seriously.ascii.js"></script>
    <script src="js/effects/seriously.chroma.js"></script>
    <script src="js/site.js"></script>
  </body>
</html>
# setup cross browser functions
window.URL = window.URL || window.webkitURL
navigator.getUserMedia =
  navigator.getUserMedia ||
  navigator.webkitGetUserMedia ||
  navigator.mozGetUserMedia ||
  navigator.msGetUserMedia

class Site
  constructor: () ->
    @$video = $("#main-video")
    @video = @$video.get 0

    @seriouslyAscii = new Seriously()
    @sVideoAscii = @seriouslyAscii.source "#main-video"
    @canvasAscii = @seriouslyAscii.target "#canvas-ascii"
    @ascii = @seriouslyAscii.effect "ascii"
    @ascii.source = @sVideoAscii
    @canvasAscii.source = @ascii
    @seriouslyAscii.go()

    @seriously = new Seriously()
    @sVideo = @seriously.source "#main-video"
    @canvas = @seriously.target "#canvas"
    # set up chroma
    @chroma = @seriously.effect "chroma"
    @chroma.screen = "rgb(125 ,2, 25)"
    @chroma.clipWhite = 0.65
    @chroma.clibBlack = 0.2125
    @chroma.weight = 0.1
    @chroma.source = @sVideo
    @canvas.source = @chroma
    @seriously.go()

    unless navigator.getUserMedia
      @getUserMediaFallback()
    else
      navigator.getUserMedia { audio: false, video: true }, @getUserMediaCallback, @getUserMediaFallback

  getUserMediaFallback: () ->
    alert "Your browser dosen't support 'navigator.getUserMedia'"
  getUserMediaCallback: (stream) =>
    @video.src = window.URL.createObjectURL stream

$ ->
  _site = new Site