M.C.P.C. (Mamesibori Creation Plus Communication)

印刷屋から五反田のWeb屋に転職したCLのブログです。

Mojolicious::LiteとAnyEvent::Twitter::Streamとenchant.jsでニコニコ動画コメント字幕風

Twitter Streaming APIっていう特定条件のツイートをだだだっと流れるように取得できるAPIがありまして、それをニコニコ動画風のコメント字幕を流してブラウザに表示させる、というのを昔作って、確か新潟のPerl勉強会で出した記憶がありますけれども、東京に引っ越し後、先日デブサミ2013に行くことが出来て、enchant.jsによるライブコーディングを拝見したところ、「字幕これで作ればあんなに苦労しなくてよかったな。」とか思ったので、

  • サーバ側
    • AnyEvent::Twitter::StreamによるTwiiter Streaming APIからの非同期入力
    • Mojolicious::LiteによるブラウザとのWebSocket非同期通信
  • ブラウザ側
    • WebSocketからの非同期通信のFIFOバッファリング
    • enchant.jsのフレーム処理による動的表現

にチャレンジしてみました。

CLCL/twitjimaku · GitHub

実行しているところは、動画で撮ったので、汚らしい部屋ですが、我慢してみてください。いい歳こいて転職すると部屋のグレードが下がるってこってすね。


Mojolicious::Lite+enchant.jsでニコニコ動画風字幕

やってみて気づいた点箇条書き

  • AnyEvent::Twitter::Streamの接続が勝手に切れてしまう件に関しては、以前書いた AnyEvent::Twitter::Streamで自動再接続処理(whileループを使わない版) - M.C.P.C. の通り、AnyEvent::Twitter::StreamをAnyEventのTimerイベントリスナーで監視する方式でカバーできます。
  • Mojolicious 2より、WebSocket通信の書き方が変わっていて、以前書いた時は過渡期だったので、Mojolicious 1/2の両方のコードを書いて切り替えていましたが、今やMojoliciousも3の時代なので、古いコードの方は書かなくてよし
  • MojoliciousのWebSocketのサポート範囲が狭い件は、先日のMojoliciousのWebSocketをRFC 6455に未対応のSafariに対応させる - M.C.P.C. (Mamesibori Creation Plus Communication)により対応。
  • ブラウザ側では、WebSocketからのデータ受信が非同期で、コメント字幕処理中にも平気で割り込まれるので、何も考えずに作ると、コメントの重複が発生していた。解決するために、FIFOバッファを用意して待ち行列を作ることにした。
  • WebSocketの非同期イベントではFIFOバッファにためることに専念、enchant.jsのフレーム進行イベントではFIFOバッファから読み出すことに専念するようにしたが、モバイル端末などではブラウザを非アクティブ時はフレーム進行イベントが発生しなくなり、FIFOバッファに溜まりまくり、その状態でブラウザをアクティブにするとFIFOバッファに溜まりまくった分が全部字幕になりブラウザが死にそうになるので、FIFOバッファの容量を決め、古いデータからあふれさせるようにする必要があった。
  • enchant.jsではコメント字幕の生成と消失を決めてしまうとあとはするすると流れていくのでらくちん。ただ、ブラウザや端末によっては30fpsのスピード稼げないことがあった。
  • 現状、morbo専用で、hypnotoadでは動かない。MojoliciousのWebSocketは通じているが、AnyEventとMojoliciousのクロスオーバーがうまくいっていないっぽい?
  • デフォルトのApacheCentOS 6)だと、WebSocketのリバースプロキシが出来ない。

さて、これなんで作ったかっていうと、8アカウントが時間に合わせてTwitterでつぶやくbot群を持っていまして、それらの発言のタイミングをリアルタイムで表示させて確認したかったからです。