2018年5月26日土曜日

YouTubeの生放送のチャットを使ってアンケートを行う


追記
youtubeライブに2021年ごろ?に便利なアンケート機能が追加されました。
追記終わり

さてタンバリンさんのツールが動いているのを見ました。
あれは過去のコメントも保存しているようですね。それどうだろうなぁ?
アンケート機能があるようですね。便利そうですね。
じゃあYouTubeの生放送のチャットを使ってアンケートを作ってみましょ


ニコニコのようなアンケート機能が視聴者には匿名ですしやりやすい思うのですが、
YouTubeにはそのような機能はないのでお試しに作ってみました。

検索すると、YouTubeでアンケートカードというものもあるらしいですが、
生放送には対応していないのかな?誰か作ってそうですけどねぇ




仕様は、
・投票項目を入力できる
・投票開始ボタンが押されてからのチャットのみを投票の対象とする
・アンケート中に投票数が確認できる
・IDで同じ人からの投票を弾く(途中で投票先の変更はダメ)
・投票終了時の結果を円グラフで表示する。
※スーパーチャットには今回未対応

苦労した所は、
ほんとはしちゃいけないだろうけど、PHPのコード部分に無限ループする部分があります。
ブラウザがChrome
かつ
sessionを使用した場合
スクリプトが終了していないのと次のページ遷移できない
という問題があるようで解決に時間がすごくかかりました。
(IE,FireFoxは停止しなくても遷移しました。)
解決策として正しいかわからないですが、
window.stop();
によってブラウザの中止ボタンの機能によりスクリプトを停止して解決してます。
そしたら今度は、IEがwindow.stop()関数に対応していないので使用ブラウザの判断をして
回避しています。
これでIE,Chrome,FireFoxで動いているのを確認しました。

3ページ分のコードをいつものフォルダ(C:\xampp\htdocs)に配置して
ブラウザ上で
http://localhost/vote1.php
とすれば使用できます。
いままでのやってきたことを組み合わせたようなもんです。


外見はこんな感じです。
見れば動きはなんとかくわかるでしょう。
1ページ目
例は雑に1文字ずつになっていましが、ちゃんと指定できます。
これは投票先を「あ」「い」「う」にしています。
本来は好きなお菓子の名前などちゃんとしたものを入れましょう。
2ページ目
投票項目が見えるようにしています。
この画像の動作では「あ」「い」「う」のワードを含むチャットを「投票した」
としていますが、
一致でもいいし、
投票項目のワードが長いと入力が大変だと思い「#1」~「#3」でもコードをいじればできます。(数字だけでもいいでしょう)
何も表示されないと寂しいのでチャットと現在の投票数を表示しています。
アンケートを打ち切る場合は投票終了ボタンを押します。

3ページ目
HighChartsを使いアンケート結果が円グラフで表示されます。
それぞれの結果を%と票数も全部載せです。
再びアンケートをやる場合は1ページに目から開始してください。




コードです。
1ページ目


form部分だけなので注釈はありません。
php部分が1行もないのにファイル名がphpですね。。。


2ページ目
①にはAPIキー、②には今回は生放送中の動画のidを入れます。
https://www.youtube.com/watch?v=xxxxxxxxxxx
のxxxxxxxxxxxの文字列のことです。






注釈として
7行目から22行目あたりがスクリプトを停止して3ページ目へ遷移させる部分です。
48行目から59行目あたりが1ページ目の入力を分解して投票項目を作成しています。
空の行を無視します。
94行から下は基本的にはチャット表示のコードの改造です。
130行目あたりは、APIが初回の入力はボタンを押したものの過去のチャットとなりますのでスキップする処理です。
142行から145行あたりは、一致するか、含むにするか、#nの一致にするかです。
好きなコードを選んでください。
148行目から156行目はまだ投票していないIDでの投票一致の場合、票として数えているところです。

3ページ目



注釈として
Highchartsの円グラフの例 を改造し、2ページ目の結果を入力としています。
33行目でPHPから_SESSIONのデータを受け取り、
それを68行目から78行目で使用しています。



ちゃんと勉強せず、行き当たりばったりで作っているから苦労する。
いままでのコードもformやhead、bodyの対応がよくなかったようだ。
WEB系の基本勉強してないものなぁ。

2018年5月18日金曜日

マウスのチャタリングを確認する

 マウスが壊れてシングルクリックがダブルクリックになったり、ドラッグ中に離した判定になったりすることがあるじゃないですか。でも指が疲れているせいか本当に壊れいてるかはっきりなしないことがありますよね。


そこで Highcharts(グラフ)を使って可視化してみました。JavaScriptを使いマウスイベントをグラフに反映します。いつも通りやりかたは雑いです。
画像の赤い部分でマウス操作するとグラフに反映されます。
コードを少し変更すればクリックとダブルクリックが確認できます。

押してしばらくして離すを繰り返した結果が以下です。
[追記:ためしにブログ上においてみました]

 マウスダウン(押す)すると青の点が1になり、マウスアップ(離す)と黒の点が2になります。
上記の図だと離したときにチャタリングおこって意図していない結果になっています。

左ボタンを確認したら、


マウスのプロパティを左きき用にして右ボタンを確認してもいいでしょう。
(変更せずとも反応しますが、右クリックだとメニューが出るのでイベントを拾えているか不安…)
下記がコードです。htmlファイルとして保存してブラウザで表示すれば使えます。
外部のリソース(Highcharts)を使っているけどいいんかな?




注釈として、
マウスのイベントとタイマーのイベントが重なっても大丈夫なようにリングバッファでイベントの時間を格納しています。
イベントのタイミングでグラフに直接反映できればいいのですが、JavaScriptよくわからないのであきらめました。
23行目から33行目をコメントアウトして35行目から46行目を反映させればクリックとダブルクリックのイベントに変更できます。
70行目から88行目、ダウンもアップも同じ数が発生するようにしています。そうしないとX軸は全部のポイントを表示するようにしているためその対策です。
※アップとダウンはペアなので問題ないが、クリックとダブルクリックは困る。
またX軸の時間は可変なので時間がながい細かい部分がみづらくなります。対策はあきらめました。
101行目 値ありから0にすぐ戻しているため、デフォルト設定だとマークが近すぎでません。その対策で0を設定しています。
ちなみに今回は線ありでやっていますが、線の幅を0にするとマークだけになります。


ブログで直接実行もできるけどやめとこ。
マウスの調子が悪いので思いつきで作ってみました。明らかに壊れてるわ

2018年5月16日水曜日

片鱗が見えたかなぁ

昨日のタンバリンさんのyoutubeコメント拾いマシーン(名前前回と違うじゃん)の部分を見て思ったこと。

更新がうまくっている部分を見ていると
2秒で4コメントぐらい追加されているように見える。
 ・一度API投げて保存したコメントを吐き出しているとしたら、人気バーチャルユーチューバーさんの場合ピークでは170コメント/9.5秒(実測)なので処理量としては追いつかない。
 ・停止したときにアイコンは違うけど名前とコメントが同じ人が表示されているからなんかバグっている。
ということがわかりますね。

 2秒毎にAPIを投げているということはなさそう。なぜならpollingIntervalMillisを無視することになるのでwarningを出てコメントを取得できない。保存したコメントを少しずつ出しているのでしょう。

 発言から動作テスト時は動いていたみたいですが限定公開でリスナーなしでやっていたのかもしれませんね。その場合はコメントが多い生放送してるときと差があります。
 pollingIntervalMillisは5秒以下で短いですし、最初のAPIでだいたい過去のコメント75ぐらいが一気に取得してしまいます。
 放送を見る限りpollingIntervalMillisが動作テスト時と違い長すぎて止まったと勘違いしたってことはなさそうです。
  適切なpollingIntervalMillisをwaitしてAPIを使用しているのか、それとコメントを保存している部分に不具合があるような気がしますねぇ。


Unityは見栄えがいいなぁ。アイコンも丸くなっているし。フィルタしてキーワードのだけ表示じゃなくて全部保存してから検索って形なのかしら 。

テスト時と実際の時の差異によるバグってなんかわくわくしますね。

2018年5月11日金曜日

YouTubeチャットで視聴者参加のためのツールを考える

5/8の某生放送でバーチャルユーチューバーのマネージャーのタンバリンさんが言っていたYouTubeのコメント欄で視聴者参加できるWPP1システム?というやつを想像で作ってみる。
PHPじゃなくてもっと立派なものだろうと思うけどね。
PHPほんと動的につかいづらい
っていうか、上位のバーチャルユーチューバーってチャット欄が人数に対して、速すぎて読めなくない


参加者を募る(キーワードを決めてそれをコメントした人のみを抽出)

参加者のコメントのみを表示する
っていう機能があればよさそう。

初期画面


モード1:決めたキーワードをコメントした人だけが表示される(今回のコードではキーワードを含むにしている。本来は一致だろう)
例はキーワードの所に「あ」を入力しkeyボタンを押した場合。
「あ」を含むコメントした人だけが表示されている。


 アイコン、ID(青字)、名前(赤字)、コメント(黒字)の順に表示されるので、青字のIDをコピーしてIDに入力しIDボタンを押す。


モード2:対象IDの方のみチャット が表示される
対象ボタンを押した先に遷移します。(入力欄が空白の場合は初期画面に遷移)

 コードは以下の通り。①にはAPIキー、②には生放送中の動画のidを入れます。
https://www.youtube.com/watch?v=xxxxxxxxxxx
のxxxxxxxxxxxの文字列のことです。
今回はアイコンも表示したいのでブラウザで無理やり表示してます。
ブラウザで「http://localhost/modoki.php」と入力。





注釈としては、
7行目から16行目で文字の装飾と画像のサイズを指定しています。
サイズを指定してそれっぽく表示 。うまくできなくてえらい時間がかかった。
24行目。PHPの処理は無限ループでまわしているため処理が終了しません。
ブラウザ上の場合は30秒でタイムアウトの処理により停止するようなので60分に延長しています。
26行目から43行目(組込み系のコードだと空のelse書くものだけど忘れた)がボタンを押した場合の処理です。
ボタンが押された場合、どのボタンが押されたかと二つのテキスト入力の値が$_POSTに格納された状態で再度同じPHPが呼び出されます。
( 18行目で自身を呼び出すように設定しています。)
62行目 file_get_contenstsでwarninngが返った時の対策に@をつけてみましたが、
これで対策うまくいってるのかなぁ
73行目 キーワードを含む場合のチェック。キーワードと一致に変更するなら両者を==で比較する
85行目 対象IDかをチェック
106,107行目 ブラウザ上の場合、通常PHPの処理すべてが終了しないと表示されないが、無限ループ(55行目)なので途中の状態を表示するための関数呼び出しです。
92行目から101行目がコメントとアイコンの表示部分。IDはモード2で出力しなくていいかも。
追記:2018/5/12
スーパーチャットには$data["snippet"]["textMessageDetails"]["messageText"]は存在しない。本当は対応が必要。共通としては$data["snippet"]["displayMessage"]とすると楽だと思うがスーパーチャットの場合「¥1,000 from 名前 : ”コメント”」のような構造なのでキーワードの一致で判定しにくいので場合わけが必要だろう。
[snippet][type] でsuperChatEventならば[snippet] [superChatDetails][userComment]を$text。textMessageEventならば["snippet"]["textMessageDetails"]["messageText"]で一致判定がOK。あと、98行目は重複しているのでいらない。
思えば取り込み後に削除されたコメントも保持してしまう。既に削除されているならば上記の判定で無視できるはずだ。その辺は運用で対応。

やりたいことはこんな感じだろうけど、右クリックで対象者選択とかもっと使いやすいのだろうなぁ。配布したりするのだろうか。
PHPって不向きだと思う。
本当はモード1にID表示なくして何番の人か指定でIDを保存していた配列から出力したかったけどPHPの処理が無限ループで完了しないからPOSTに渡せなそうなのであきらめたり、レイアウト関係がむずかしくてあきらめたりと妥協しまくって。このコード量でそれでも1日かかった。まぁ自分C言語の人なので。