プレゼンへのコメントをリアルタイムにスライドの上に流す話

あらすじ

夏ですね、暑いですね。世間ではこの時期流しそうめんをやったりするのかもしれませんが、僕は手元にそうめんがないので、別の何かを流していきたいと思います。ということで、今回の記事は、プレゼンへのコメントをリアルタイムでスクリーンに流すツールを作って使ったメモです(某科目の学科紹介プレゼンにて使用)。

プレゼン中にコメントを流すというアイデア自体は、1年か2年の頃に見た弊学での「ちびLT」という勉強会(?)でとある先輩が開発・紹介していたものが元なので、オリジナルではないですが、自分でも作ってみたくなったのでやってみました。しかし、当時の先輩がどのように作ったのかわからなかったので、とりあえずいろいろ調べたり考えてやってみたので、その過程をメモします。ちなみに最終的にはComet(Python, JavaScript) on Adobe Airで良い感じにやりました。

開発が始まるまでの流れ

くどいようですが、やりたいことは「PowerPointプレゼンテーションのスライド上を、聴衆のコメントが流れていく」ということです。したがって、

  1. 聴衆がコメントを打ち込む画面
  2. コメントを画面上に流す何らかの仕組み

の2つが必要になります。1については、ひとまず適当なwebアプリのページを作って、URLを黒板かスライドにでも書いてアクセスしてもらい、コメントを打ってもらえば良いか、という感じで後回しにし、2の方に先にとりかかりました。思いついた当初はだいぶ楽観的で、
「まあ、PowerPointだし、Excelみたいにマクロあるっしょ(おもむろにAlt + F11を押す)。ほらVBA書けるやん、良い感じにDOMのデータ取ってきてテキストオブジェクト作ってアニメーション当てれば行けるっしょ~」
と考えていた時期が僕にもありますた。実際、VBAではInternetExplorerを起動してDOMの操作もでき、さらにreadyState(サイトのロードステータス)を扱った処理もできるようでした(※1)。また、検索の途中で面白そうな資料も発見しました(※2、いつかVBAやらないといけなくなった時にまた見たい)。

でもやっぱり?

そうはいってもreadyStateはブラウザによって実装のされ方が違うらしく、その影響なのかVBAから使う際の良さみが浅い感じでした。また、開発期間もあまり長くない状況で使い慣れない言語を使うよりは”い つ も の”でどうにかしたい気持ちが強くなり、その方向へ転換してグーグリングを継続しました。というかPowerPoint VBAとExcel VBAで若干言語仕様が違って、PPT VBAの資料が圧倒的に少ないのがだいぶ辛かったです。さて、ここからようやく開発本編です(僕の記事は前置きというか無駄話が長いことであまりにも有名)。

い つ も の

やっぱりWebベースで全部やりたくなるんですよ。その願いを叶えてくれたのが、「Adobe Air」でした。恥ずかしながら存在自体を今回の開発時まで知らず、「へーこんなのあるんだー」「Flashと何が違うんや…」「でもActionScriptで開発しないといけないんじゃないの…?」などいろいろ疑問がありました。実際はAir SDKをダウンロードすることで「HTML + JavaScript」で開発ができるので、VBAの沼にはまりかけた時に比べればだいぶ気は楽でした。後はやるだけ。
ただ当初WebSocketで通信できないかなと思ってたんですが、AirではWebSocketがサポートされておらず、独自のSocketAPIが…(※3)とあったので、今回はSocketを捨てて「Comet」方式で実装することにしました(逃げ)。以下の図は全体のイメージをまとめたものです。Cometでファイルの変更を監視し、変更差分を画面に投げます。

ユーザーからのインプットが画面を流れるまで

開発環境

OS: Windows7
言語: Python(2.7.11) + JavaScript(jquery(v1.12.4))

核となるコードを書く

PHP+JSでのCometの実装(※4)を参考に、ファイルの差分をJSONで返すPythonのコード(こんなのしか思いつかなかったのでもっと良い書き方あったら教えて下さい)。

1
2
3
4
5
6
7
8
9
10
11
12
prevLines = int(form["prev"].value)
while True:
nowLines = sum(1 for line in open(LOGFILE))
if prevLines != nowLines:
ret = []
for i in range(0, nowLines - prevLines):
ret.append(linecache.getline(LOGFILE, nowLines - i))
break
time.sleep(1)
linecache.clearcache()
print json.dumps({"ret": ret, "prev": nowLines})

と、それを投げたり良い感じにするJS側のコード。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var firstFlag = true;
var prev = 0;
function cometCheck() {
$.ajax({
url: "./cgi/comet.py?prev=" + prev,
type: "get"
})
.done(function(data) {
var json = JSON.parse(data);
prev = json.prev;
//起動時にもログが読み込まれてくるが、それは表示しない
if (firstFlag) {
firstFlag = false;
}
else {
for (var i = 0; i < (json.ret).length; i++) {
nicoscreen.add(json.ret[i], "white", "48pt");
}
}
})
.fail(function() {
//do something
})
.always(function() {
cometCheck();
});
}

JSコード中のnicoscreen.add関数ですが、これはニコニココメント風にwebページの画面上にに文字を流すjqueryのプラグイン(※5)があったので拝借し、少し中身を改造して使わせていただきました。以下動作確認時のスクリーンショットです(左側が入力用のユーザーが見るページ、右側が拡張ディスプレイに表示したPowerPointスライドと、その上を流れるコメント)。

実際に使った入力画面からのコメントが、画面を流れる様子を確認

なにもないところを文字が流れているように見えるんだけど…?

これについてはAdobe Airの力でして、Airのアプリを書く際はまずxmlを書くんですが、その中でウィンドウを透明にしたり、フルスクリーンモードをオンにしたりなど設定ができます。また、詳しくはHTML + JavaScript開発者用ドキュメント(※6)を読めばわかりますが、簡潔に言うとSDKにJSを拡張するJSが入っていて、そいつを読み込んでAir JSなコードを少し書くとAirアプリのウィンドウを最前面に配置したりできます。

作ってみての感想など

最初からVBAじゃなくてWebの方法にあたりをつければよかった(VBAでしばらくはまり、Webベースに切り替えてから2~3日で作ったので)です。まあでもこんな機会でもなければVBA(ましてやPowerPoint VBA)を触る機会がない(ような気がする)ので良い経験にはなったかな、と思うようにしてます。
実際に使ってみて受けが良かったのかは正直よくわかりませんが、コメント書き込んでもらえて良かったです(誰もPC開いてない or コメント書いてくれないケースを想像すると…())。今後このツールを使う機会があるかは謎ですが、同じようなことをしようと考える方の参考に少しでもなれれば幸いです。以上です。

参考にさせていただいたサイト

※1 VBAのIE制御入門 | IE操作の自動化
※2 こじらせVBA - SlideShare
※3 Adobe Flash Platform * AIR でサポートされていない WebKit の機能
※4 PHPとjQueryでCometっぽいモノを実装する
※5 NicoScreen.js:画像や動画の上に、ニコニコ動画のような文字を流すことが出来るjqueryプラグイン
※6 Adobe Air用HTML開発ガイド