ほねつき備忘録

ほねつき備忘録

僕のブログです。僕のためのブログです。

YouTube LiveのチャットをMinecraftのチャット欄に持ってくる

お久しぶりです。ほねつきにく。です。ひっさびさにブログに書きたいネタが出来たのでかきます。

0.ことの始まり

最近Minecraft(1.14.4)の鯖を開けて身内で遊ぶところを配信しているのですが、どうもプレイに集中し過ぎでYouTubeのチャットを見逃しちゃうんですよね。そこで、YouTubeのチャットをMinecraftのチャット欄に持ってこれば嫌でも気づくし、プレイしている他の仲間もチャットに返答できるかなあと思いまして。早速ググってみました。

f:id:BonyChops:20191031221610p:plain

ぐぐる

f:id:BonyChops:20191031221636p:plain

いい感じのプラグイン発見

f:id:BonyChops:20191031221744p:plain

おぉ~...ん?

f:id:BonyChops:20191031221802p:plain

あっ(察し)

最新バージョン対応してませんでした...てことで、最初はphpでカキカキして作ろうと思ったんですが、予想以上にサンプルがなかったんで(サンプル乞食)Pyhonでカキカキしてみようと思います。あ、今更ですが、この記事は「YouTube LiveのチャットをMinecraftのチャット欄に持ってくる方法」なんてタイトルではございませんので詳しいやり方は載せません(めんどいんで)。ただイキりたいだけです。

 

1.YouTube Data API使う準備

blog.sky-net.pw

上記の記事を参考にしました。というよりほぼ丸パクリしました。お兄さん許して。

 まず必要なパッケージを落としましょうね。

pip install httplib2 oauth2client simplejson

で、まずはみんな大好きGCP(Google Cloud Plauform)で、YouTube Data API v3を有効にしましょう。当然、配信のときに使うYouTubeアカウントが紐付けされてるGoogle アカウントでログインしましょうね(チャンネルは後で選ぶ)

f:id:BonyChops:20191031224648p:plain

上部の検索ボックスで「YouTube」で出てくる

YouTube Data API v3を有効にしてから...

f:id:BonyChops:20191031230124p:plain

Outh クライアントID つくろうね

f:id:BonyChops:20191031230211p:plain

てきとーにつくる

f:id:BonyChops:20191031230746p:plain

認証情報をJSONで落とす

落としたら「client.json」にリネーム。

3.結局どうなったかで使うのでどっか取っといてください。

2.MC(Minecraft)Serverにコマンド受け渡しをどうするか

いろいろ考えた(3秒くらい)結果、screenで開いて入力として渡すのが一番いいかなあと。screenを知らない人にかる~く説明すると、screenは仮想端末を作れるコマンドで、こいつをつかえばSSHの通信が切れても実行し続けさせたりできます。(MC鯖作るなら必須)

そんなscreenに直接入力を送るので、当然MC鯖はscreenで立ち上げる必要があります。起動するシェルスクリプトが「run.sh」なら、

screen -S MCServer ./run.sh

 こんな感じに立ち上げてもらえばオッケー。

入力の受け渡しはこの記事を丸パクリさせて参考にさせていただきました。

jyn.jp

 

3.結局どうなったか

最終的にこんなソースになりました。(絶対有識者各位にブチブチに怒られる...)


#!/usr/bin/env python


import httplib2
import os
import time
from oauth2client import tools
from oauth2client import client
from oauth2client.file import Storage
import simplejson as json


credentials_path = "credentials.json"
store = Storage(credentials_path)
credentials = store.get()

if credentials is None or credentials.invalid:
    f = "client.json"
    scope = "https://www.googleapis.com/auth/youtube.readonly"
    flow = client.flow_from_clientsecrets(f, scope)
    flow.user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"
    credentials = tools.run_flow(flow, Storage(credentials_path))


http = credentials.authorize(httplib2.Http())
url = "https://www.googleapis.com/youtube/v3/liveBroadcasts?part=snippet&id="
url += "xxxxxxxxxxxx"
res, data = http.request(url)
data = json.loads(data.decode())

chat_id = data["items"][0]["snippet"]["liveChatId"]
print(chat_id)

pageToken = None
url = "https://www.googleapis.com/youtube/v3/liveChat/messages?part=snippet,authorDetails"
url += "&liveChatId=" + chat_id
print(url)
preDisplayName = "AAAAAAAAA"
preMessageText = "BBBBBBBBB"
os.system('screen -p 0 -S MCServer -X stuff \'say \"YouTubeLiveChatToMC\" Loaded!\\015\'')
print('screen -p 0 -S MCServer -X  stuff \'say \"YouTubeLiveChatToMC\" Loaded!\\015\'')
while True:
    if pageToken:
        url += "&pageToken=" + pageToken

    res, data = http.request(url)
    data = json.loads(data.decode())
    try:
        if preMessageText != str(data["items"][-1]["snippet"]["textMessageDetails"]["messageText"]) or preDisplayName != str(data["items"][-1]["authorDetails"]["displayName"]):
            print(data["items"][-1]["authorDetails"]["displayName"])
            preDisplayName = str(data["items"][-1]["authorDetails"]["displayName"])
            print(data["items"][-1]["snippet"]["textMessageDetails"]["messageText"])
            preMessageText = str(data["items"][-1]["snippet"]["textMessageDetails"]["messageText"])
            print(data["items"][-1]["authorDetails"]["profileImageUrl"])
            os.system("screen -p 0 -S MCServer -X stuff \'tellraw @a [\"\",{\"text\":\"[\"},{\"text\":\"YT\",\"color\":\"red\"},{\"text\":\"]["+preDisplayName+"] "+preMessageText+"\"}]\\015\'")
            print("screen -p 0 -S MCServer -X stuff \'tellraw @a [\"\",{\"text\":\"[\"},{\"text\":\"YT\",\"color\":\"red\"},{\"text\":\"]["+preDisplayName+"] "+preMessageText+"\"}]\\015\'")
    except IndexError:
        # print("かなC")
        pass

    pageToken = data["nextPageToken"]
    time.sleep(3)


 url += "xxxxxxxxxxxx"のとこは、配信するURLを入れてください(https://www.youtube.com/watch?v=90mCq_K6eT0だったら90mCq_K6eT0)

 

tellrawコマンドを飛ばすところはまじでハマりましたねえ。うまくいったときは感動しました。

とりあえずこれを「start.py」とし、1.YouTube Data API使う準備で作った「client.json」を同じディレクトリにぶちこんで、

python3 start.py

 すると...


Your browser has been opened to visit:

    https://accounts.google.com/o/oauth2/auth?client_id=*****

If your browser is on a different machine then exit and re-run this
application with the command-line parameter

  --noauth_local_webserver

 てことで上記URL...の前になんか書いてありますね

もし別のマシンのブラウザで(リンクを)開く場合、一旦終了して、以下のパラメータをつけて再実行してください

つまり僕みたいにGCP等の別のマシンで鯖を開く場合はこれ必須ですね。

python3 start.py --noauth_local_webserver

 これで起動し直して、認証して、認証コードを入力すると、「credentials.json」が作成され、取得が開始されます。取得したメッセージは、screenでかつ「-S MCServer」のパラメータをつけて起動してるMC鯖に送られ、tellrawコマンドでうまい感じに出てきます。

f:id:BonyChops:20191031234057p:plain

こんなかんじ

4.問題点

しばらく起動してると勝手に落ちてる。原因不明。いつか直す。