Youtube LiveStreaming APIで配信のコメントを取得する

はじめに

読み上げをYoutubeの配信中にもやりたいなーと思ってコメントの取得方法調べたら結構面倒なのでメモ

大まかな流れとしては
配信先のURLからライブのIDを取得 -> ライブのIDからチャットのIDを取得 -> チャットIDを使ってチャットの取得
といった感じ
ライブのIDからチャットのIDを取得するAPIにOauth認証が必要だったりで結構面倒

環境

  • Python3

APIキーを用意する

この辺は他のAPIと同じなので他のサイトの方を見たほうがわかりやすいです.

いつも通りGoogle Cloud Platformへ行き新しくプロジェクトを作成し,APIの中から「YouTube Data API v3」を有効にしておく.
その上で認証情報 -> Oauth同意画面と進み必要な項目を埋めておく.(最低限サービス名だけ埋まっていれば良い)
認証情報の画面まで戻り認証情報を作成 -> OauthクライアントIDを選択する.
アプリケーションの種類は「その他」にして進める.名前は適当に決める.
作成するとIDとシークレットが表示されるが後でダウンロードするjsonに入ってるのでOKをクリックして閉じる.
OAuth 2.0 クライアント IDの部分に今回作成したキーがあるはずなのでこれを右端のアイコンからダウンロードしておく.
今回はclient.jsonとしてダウンロードしておく.

ライブラリを用意する

httplib2とoauth2clientを使うのでこれらを入れておく.

1$ pip install httplib2 oauth2client

認証する

一度目はお馴染みのOauth認証画面に飛ばされるが一度認証すると不要になるのでその辺込みでこんな感じ
client.jsonがさっき落としてきた認証情報でcredentials.jsonが認証済みの情報.

 1import httplib2
 2from oauth2client import tools
 3from oauth2client import client
 4from oauth2client.file import Storage
 5
 6credentials_path = "credentials.json"
 7if os.path.exists(credentials_path):
 8    # 認証済み
 9    store = Storage(credentials_path)
10    credentials = store.get()
11else:
12    # 認証処理
13    f = "client.json"
14    scope = "https://www.googleapis.com/auth/youtube.readonly"
15    flow = client.flow_from_clientsecrets(f, scope)
16    flow.user_agent = "なんか適当に入れる"
17    credentials = tools.run_flow(flow, Storage(credentials_path))

本当はもう少しシンプルに書ける.

 1credentials_path = "credentials.json"
 2store = Storage(credentials_path)
 3credentials = store.get()
 4
 5if credentials is None or credentials.invalid:
 6    f = "client.json"
 7    scope = "https://www.googleapis.com/auth/youtube.readonly"
 8    flow = client.flow_from_clientsecrets(f, scope)
 9    flow.user_agent = "なんか適当に入れる"
10    credentials = tools.run_flow(flow, Storage(credentials_path))

LiveChatIdを取得する

LiveChatIDはLiveBroadcasts: listを使うことで取得できる.
Web上でも試せるので一度試しておくと良い.
配信のURLが
https://www.youtube.com/watch?v=xxxxxxxxx
の場合実際のコードはこんな感じ.

1http = credentials.authorize(httplib2.Http())
2url = "https://www.googleapis.com/youtube/v3/liveBroadcasts?part=snippet&id="
3url += "xxxxxxxxx"
4res, data = http.request(url)
5data = json.loads(data.decode())
6
7chat_id = data["items"][0]["snippet"]["liveChatId"]
8print(chat_id)

コメントの取得

コメントの取得はLiveChatMessages: listから出来る.
どうもStreamingAPIとかは提供されてないっぽいので毎回リクエストを投げるしかなさそう?
pageTokenクエリを使うと前回との差分を取得出来るのでこれを使ってコメントの重複は避けられる.

 1pageToken = None
 2url = "https://www.googleapis.com/youtube/v3/liveChat/messages?part=snippet,authorDetails"
 3url += "&liveChatId=" + self.chat_id
 4
 5while True:
 6    if pageToken:
 7        url += "&pageToken=" + pageToken
 8
 9    res, data = self.http.request(url)
10    data = json.loads(data.decode())
11
12    for datum in data["items"]:
13        print(datum["authorDetails"]["displayName"])
14        print(datum["snippet"]["textMessageDetails"]["messageText"])
15        print(datum["authorDetails"]["profileImageUrl"])
16
17    pageToken = data["nextPageToken"]
18    # time.sleep(3)

連続で回し続けるのはどうなんだろうと思ったので適当にwaitをかけると良いと思う.

おまけ

GUI化してみた

追記(2021/01/11)

こちらの件でマシュマロが来ていたのですがすぐに返し損ねてしまったので何かありましたらTwitterのDM開けておりますのでそちらでコメントいただければ対応できます。

参考記事

後ろの2つはコードサンプルなので読むと雰囲気がわかる.