Posted at

サーバーサイドエンジニアのハッカソンの乗り切り方


このドキュメントの目的

ハッカソンという限られた時間の中でのサーバーサイドエンジニアの乗り切り方を伝授したい。


このドキュメントを書いた理由

私自信が徹夜がしんどくなってきたので、ハッカソンが辛いというのがある。

美味しい食事も用意してくれていたりして大変ありがたいのだが、寝不足がたたると、消化能力が落ちる。レッドブルでさえも栄養がありすぎて、吸収できない。若手に伝授したい。

最後は当時使ってたメモをそのまま貼り付けている。


私の立ち位置

ハッカソンの中では基本的にはサーバーサイド。Webプログラミングが多かった頃とは違って、スマホアプリのハッカソンでは、役割の一部でしかない。ただ、それでもサーバーサイドエンジニアは大事。


スマホアプリハッカソンでのサーバーサイドの役割

SPAJAMなどは、スマホアプリのハッカソンなので、一番大事なのはスマホ側のネイティブアプリなのだが、スマホは「Phone」でもあるので、コミュニケーション機能は大事。そうなるとどっかにDBがあって、それを読み書きする機能は必要。

イマドキはFireBaseなどのサーバレスアーキテクチャもでてきて、いよいよサーバサイドエンジニアリングが必要ないケースもでてくる。

だからサーバサイドエンジニアは「FireBaseでもできないよほど面倒くさいこと」をやらないと存在意義がない。


お題「サーバーサイドで360度動画を作りたい」

SPAJAM2016では、360度動画を作った。なんやかんやで優勝というありがたい賞を頂いた。

そんな中で、どうやってサーバーサイドを並行して作っていくかということを説明したい。


シナリオ


  1. ユーザーAは動画を録画してアップロードする
    2.ユーザーBは動画を録画してアップロードする

  2. サーバはユーザAとBの動画をマージして360度動画にする

これが大まかな流れ。普通の動画から360度動画への変換がミソ。そのプログラムを一晩で作り切る。あがるー。


処理の流れ

どうやって360度動画を作るのか。


  1. 動画をパラパラの静止画と音声に分ける

  2. パラパラの静止画を360度のための天地の余白を付ける

  3. その静止画を複数人で並べる
    4.複数人で並べたらパラパラを元の動画に戻す

  4. 先に分けた複数人の音声を合成する

  5. 360度動画にするためのメタデータを付与する

こういう手順。一つ一つの単品作業はやればできる。

動画系はffmegを丹念につかう。

音声系はsoxというコマンドを丹念につかう。

一番のポイントは、「単一のプログラムにしない」ということ。

ハッカソンだからというのもあるが、バラバラに進めることで、作業分担もできるし、問題の切り分けもシンプル。

別プログラムになることで、rubyとPythonの混在も可能。各エンジニアが得意な言語で作れる。

ffmpegやsoxコマンドは、ターミナル上で実行するチュートリアルの、inputとoutput のデータを差し替えていくだけ。

中間ファイルの嵐にはなるのだが、外からは分からない。どんくさくても構わない。

並行稼動をするときには、ユニークなテンポラリのディレクトリを作ればOK。

そんなの当たり前だよ!という意見もあるかもしれないが、ImageMagicなら、各言語にバインディングされたライブラリが提供されていたりするんだけど、そういうの要らない。外部コマンド呼び出しでいい。

ということで、動きとしてはこうなる。


  • ffmpegのオプションを試す

  • 出力データをみる

  • やりなおす

  • うまくいったら、それをラッパーのシェルスクリプトに組み込む。

この繰り返し。

こういうサイトを参考にプログラムに組み込む前に手元で試す。

https://qiita.com/matoken/items/664e7a7e8f31e8a46a60


ここから先は手元で試した結果

こういうのを一晩でガーッと作って、朝くらいに合体させる。


ファイルの情報を表示

ffmpeg -i  20160702_204326.mp4 


フレームレート15で切り出し

ffmpeg -i 20160702_204244.mp4  -r 15 -f image2   jpeg/%06d.jpg


mp4をmp3に変換してオーディオのみ抽出

ffmpeg -i 20160702_204244.mp4 -acodec libmp3lame -ab 256k mp3/20160702_204244.mp3


フレームレート15で切り出し

ffmpeg -i data/a.mp4  -r 15 -f image2   data/jpeg/a_%06d.jpg

ffmpeg -i data/b.mp4 -r 15 -f image2 data/jpeg/b_%06d.jpg
ffmpeg -i data/c.mp4 -r 15 -f image2 data/jpeg/c_%06d.jpg


足りないコマを足す

ruby pad_frame.rb


ファイルを結合する

ruby merge_jpeg.rb 


余白を作る これで成功

mogrify -resize 960x960 -gravity center -background "#000000" -extent 960x960 data/merged/*.jpg


960×960の3人の合成の連番jpegを動画に合成

ffmpeg -f image2 -r 15 -start_number 1 -i data/merged/%06d.jpg -r 15 -an -vcodec libx264 -pix_fmt yuv420p silent.mp4


音声のみとりだし

ffmpeg -i a.mp4 -acodec libmp3lame -ab 256k audio/a.mp3

ffmpeg -i b.mp4 -acodec libmp3lame -ab 256k audio/b.mp3
ffmpeg -i c.mp4 -acodec libmp3lame -ab 256k audio/c.mp3


音声を複数つなげる

sox -m data/audio/a.mp3 data/audio/b.mp3 data/audio/c.mp3 data/audio/merged.mp3


音声とムービーを結合 (オプションなし)

ffmpeg   -i silent.mp4 -i data/audio/merged.mp3    2d.mp4


メタデータを注入する

python spatial-media-master/spatialmedia -i 2d.mp4 injected.mp4


以下検証に使ったコマンド


バラしたものを戻しただけ(単体で検証)

ffmpeg -f image2 -r 15 -start_number 1 -i data/kensho/a_%06d.jpg -r 15 -an -vcodec libx264 -pix_fmt yuv420p video.mp4