Integrate replaychat into livechat

This commit is contained in:
taizan-hokuto
2020-01-02 19:35:58 +09:00
parent 48b6f2c24e
commit 7766a39c9c
6 changed files with 372 additions and 26 deletions

View File

@@ -14,9 +14,24 @@ from .. exceptions import (
logger = config.logger(__name__)
from .. import util
class Parser:
def parse(self, jsn):
URL_LIVE = "live_chat/get_live_chat?continuation="
URL_REPLAY = "live_chat_replay/get_live_chat_replay?continuation="
def __init__(self):
self.mode = 'LIVE'
def get_contents(self, jsn):
if jsn is None:
return {'timeoutMs':0,'continuation':None},[]
if jsn['response']['responseContext'].get('errors'):
raise ResponseContextError('The video_id would be wrong, or video is deleted or private.')
contents=jsn['response'].get('continuationContents')
return contents
def parse(self, contents):
util.save(json.dumps(contents,ensure_ascii=False,indent=2),"v:\\~\\test_",".json")
"""
このparse関数はLiveChat._listen() 関数から定期的に呼び出される。
引数jsnはYoutubeから取得したチャットデータの生JSONであり、
@@ -27,7 +42,7 @@ class Parser:
Parameter
----------
+ jsn : dict
+ contents : dict
+ Youtubeから取得したチャットデータのJSONオブジェクト。
pythonの辞書形式に変換済みの状態で渡される
@@ -38,19 +53,19 @@ class Parser:
+ chatdata : list[dict]
+ チャットデータ本体のリスト。
"""
if jsn is None:
return {'timeoutMs':0,'continuation':None},[]
if jsn['response']['responseContext'].get('errors'):
raise ResponseContextError('動画に接続できません。'
'動画IDが間違っているか、動画が削除非公開の可能性があります。')
contents=jsn['response'].get('continuationContents')
#配信が終了した場合、もしくはチャットデータが取得できない場合
# if jsn is None:
# return {'timeoutMs':0,'continuation':None},[]
# if jsn['response']['responseContext'].get('errors'):
# raise ResponseContextError('動画に接続できません。'
# '動画IDが間違っているか、動画が削除非公開の可能性があります。')
# contents=jsn['response'].get('continuationContents')
'''配信が終了した場合、もしくはチャットデータが取得できない場合'''
if contents is None:
raise NoContentsException('チャットデータを取得できませんでした。')
cont = contents['liveChatContinuation']['continuations'][0]
if cont is None:
raise NoContinuationsException('Continuationがありません。')
raise NoContinuationsException('No Continuation')
metadata = (cont.get('invalidationContinuationData') or
cont.get('timedContinuationData') or
cont.get('reloadContinuationData')
@@ -60,6 +75,23 @@ class Parser:
if unknown:
logger.debug(f"Received unknown continuation type:{unknown}")
metadata = cont.get(unknown)
metadata.setdefault('timeoutMs', 10000)
return self._create_data(metadata, contents)
def _create_data(self, metadata, contents):
chatdata = contents['liveChatContinuation'].get('actions')
if self.mode == 'LIVE':
metadata.setdefault('timeoutMs', 10000)
else:
interval = self._get_interval(chatdata)
metadata.setdefault("timeoutMs",interval)
"""アーカイブ済みチャットはライブチャットと構造が異なっているため、以下の行により
ライブチャットと同じ形式にそろえる"""
chatdata = [action["replayChatItemAction"]["actions"][0] for action in chatdata]
return metadata, chatdata
def _get_interval(self, actions: list):
if actions is None:
return 0
start = int(actions[0]["replayChatItemAction"]["videoOffsetTimeMsec"])
last = int(actions[-1]["replayChatItemAction"]["videoOffsetTimeMsec"])
return (last - start)