ということで、チャットが取得できるようになれば
特定の人を見えなくしたいとか、
特定の人だけピックアップするとか、
特定のキーワードで何かが加速したり、
スーパーチャットで何かしたり、
他のアプリケーションとの連携したり
チャットを保存したい
読み上げソフトで読み上げたり
翻訳したり
など、いろいろな目的がかなうようになると思います。
今回の仕様はこんな感じです。
・名前とテキストのみを表示
・コマンドプロンプトで表示する
・”www”(半角)を含むテキストを”NGNGNGNG”に置き換える
です。
使用しているAPIについてはvideoとLiveChatMessagesを参照。
①にはAPIキー、②には今回は生放送中の動画のidを入れます。
https://www.youtube.com/watch?v=xxxxxxxxxxx
のxxxxxxxxxxxの文字列のことです。
以下がコードになります。 ※少ししか動作確認していません。
追記2018/4/29 下の方に処理タイミングを変更したコードを載せました。
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | <?php $key = "①" ; $videoId = "②" ; //ChatIdの取得 $search_api = "https://www.googleapis.com/youtube/v3/videos?part=liveStreamingDetails&id=" . $videoId . "&key=" . $key ; $search_contents = file_get_contents ( $search_api ); $search_json = json_decode( $search_contents ,true); $ChatId = $search_json [ "items" ][0][ "liveStreamingDetails" ][ "activeLiveChatId" ]; //ChatIdからliveChatにアクセス用のURL $search_api = "https://www.googleapis.com/youtube/v3/liveChat/messages?part=snippet,authorDetails&liveChatId=" . $ChatId . "&key=" . $key ; $next = "" ; $url = $search_api ; while (1) { if ( $next ) { $url = $search_api . "&pageToken=" . $next ; } $search_contents = file_get_contents ( $url ); $search_json = json_decode( $search_contents ,true); foreach ( $search_json [ "items" ] as $k => $data ) { echo $data [ "authorDetails" ][ "displayName" ]; echo PHP_EOL; echo "\t" ; $text = $data [ "snippet" ][ "textMessageDetails" ][ "messageText" ]; if ( strpos ( $text , "www" ) === false) { echo $text ; } else { echo "NGNGNGNG" ; } echo PHP_EOL; } $next = empty ( $search_json [ "nextPageToken" ])? 0 : $search_json [ "nextPageToken" ]; //pollingIntervalMillis + 500ms加算時間毎に読み込む $delay = $search_json [ "pollingIntervalMillis" ]*1000 + 500*1000; usleep( $delay ); } ?> |
注釈として
6行目はpart=liveStreamingDetailsとして、”ChatId”を取得しています。
12行目でわかるように今回も続きを読み出すために&pageToken=を使用しています。
ただし、46行目にあるように"pollingIntervalMillis"より早くAPIを投げるとエラーとなるのでそれより500ms多めに遅延させています。
29行目から411行目を変更すればいろいろな機能を持たせられると思います。
コマンドプロンプトで>chatlog.txtやファイル書き込みで保存もできます。
結果はこんな感じです。
コマンドプロンプトなのでいまいちな見た目ですが・・・残像でるし
改善点として
・絵文字も使えないのでやっぱりhtmlなどでやるべきかなぁと。でも更新処理どうしていいかわからない。。。
・チャットが激しすぎるとどうなるのだろうという疑問。1回で取得する数のデフォルトは500ですがそれ以上の激しさでも追いつくか。
・pollingIntervalMillisは勢いで変化します。激しいほど長い感じです。
自分が見たのは4秒から9秒とかでした。
取得したメッセージを一気に表示しているのでpollingIntervalMillis/pageInfo.resultsPerPage
との間隔で少しずつ出力した方が自然な感じがします。
・生放送の終了判定がありませんので自分で強制終了するか確認処理が必要かと思います。放送自体が終了してもチャットが生きてたりで動作確認が必要かも。upcoming中はとりあえず取得ができる。
-------------------------------------------------------------------------------------
追記2018/4/28
配列でバーチャルYoutuber300人程度の発言のみを抽出コードを作って生放送見てたんだけど少し抜けがある。抽出処理の時間分待ち時間削ってないし、500ms分固定でプラスしてるのもイケてないのかも。
某所のコメントログでは比べるとどちらも抜けがあるしチャットは結構きついのかなぁ
公式のサンプルをもっと見た方がよかったか。
追記2018/4/29
pollingIntervalMillisに対してフィルタ処理はそんな重くないことがわかったんで、とりあえず500ms固定を削除して待ち方を変更。
コードは以下
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <?php $key = "①" ; $videoId = "②" ; //ChatIdの取得 $search_api = "https://www.googleapis.com/youtube/v3/videos?part=liveStreamingDetails&id=" . $videoId . "&key=" . $key ; $search_contents = file_get_contents ( $search_api ); $search_json = json_decode( $search_contents ,true); $ChatId = $search_json [ "items" ][0][ "liveStreamingDetails" ][ "activeLiveChatId" ]; //ChatIdからliveChatにアクセス用のURL $search_api = "https://www.googleapis.com/youtube/v3/liveChat/messages?part=snippet,authorDetails&liveChatId=" . $ChatId . "&key=" . $key ; $next = "" ; $url = $search_api ; while (1) { if ( $next ) { $url = $search_api . "&pageToken=" . $next ; } $search_contents = file_get_contents ( $url ); $search_json = json_decode( $search_contents ,true); //時間測定開始 $time_start = microtime(true); foreach ( $search_json [ "items" ] as $k => $data ) { echo $data [ "authorDetails" ][ "displayName" ]; echo PHP_EOL; echo "\t" ; $text = $data [ "snippet" ][ "textMessageDetails" ][ "messageText" ]; if ( strpos ( $text , "www" ) === false) { echo $text ; } else { echo "NGNGNGNG" ; } echo PHP_EOL; } $next = empty ( $search_json [ "nextPageToken" ])? 0 : $search_json [ "nextPageToken" ]; //pollingIntervalMillis msの整数型を実数にしている $delay = $search_json [ "pollingIntervalMillis" ]/1000.0; do { $time = microtime(true) - $time_start ; usleep(100); //0.1ms待ち } while ( $time < $delay ); } ?> |
注釈として
51行目の待ちがないとCPU負荷が高いので挿入しています。
これで抜けがいくらか減ると思います。
0 件のコメント:
コメントを投稿