|
@@ -35,52 +35,89 @@ class Main: |
|
|
|
|
|
|
|
|
print (mode) |
|
|
print (mode) |
|
|
|
|
|
|
|
|
|
|
|
# ウィンドゥの初期化 |
|
|
pygame.init () |
|
|
pygame.init () |
|
|
screen: pygame.Surface = pygame.display.set_mode ((Window.WIDTH, Window.HEIGHT)) |
|
|
screen: pygame.Surface = pygame.display.set_mode ((Window.WIDTH, Window.HEIGHT)) |
|
|
|
|
|
|
|
|
|
|
|
# 吹き出し |
|
|
balloon = pygame.transform.scale (pygame.image.load ('talking.png'), |
|
|
balloon = pygame.transform.scale (pygame.image.load ('talking.png'), |
|
|
(Window.WIDTH, 384)) |
|
|
(Window.WIDTH, 384)) |
|
|
if goatoh_mode: |
|
|
if goatoh_mode: |
|
|
balloon = pygame.transform.flip (balloon, False, True) |
|
|
balloon = pygame.transform.flip (balloon, False, True) |
|
|
|
|
|
|
|
|
|
|
|
# 音声再生器の初期化 |
|
|
pygame.mixer.init (frequency = 44100) |
|
|
pygame.mixer.init (frequency = 44100) |
|
|
|
|
|
|
|
|
|
|
|
# ニジカの “ぬ゛ぅ゛ぅ゛ぅ゛ん゛” |
|
|
noon = pygame.mixer.Sound ('noon.wav') |
|
|
noon = pygame.mixer.Sound ('noon.wav') |
|
|
|
|
|
|
|
|
|
|
|
# ゴートうの “ムムムム” |
|
|
mumumumu = pygame.mixer.Sound ('mumumumu.wav') |
|
|
mumumumu = pygame.mixer.Sound ('mumumumu.wav') |
|
|
|
|
|
|
|
|
|
|
|
# ゴートうの “クサタベテル!!” |
|
|
kusa = pygame.mixer.Sound ('kusa.wav') |
|
|
kusa = pygame.mixer.Sound ('kusa.wav') |
|
|
|
|
|
|
|
|
|
|
|
# YouTube Chat オブジェクト |
|
|
live_chat = pytchat.create (video_id = YOUTUBE_ID) |
|
|
live_chat = pytchat.create (video_id = YOUTUBE_ID) |
|
|
|
|
|
|
|
|
|
|
|
# デバッグ・メシジのフォント |
|
|
system_font = pygame.font.SysFont ('notosanscjkjp', 24, bold = True) |
|
|
system_font = pygame.font.SysFont ('notosanscjkjp', 24, bold = True) |
|
|
|
|
|
|
|
|
|
|
|
# 視聴者コメントのフォント |
|
|
user_font = pygame.font.SysFont ('notosanscjkjp', 32, italic = True) |
|
|
user_font = pygame.font.SysFont ('notosanscjkjp', 32, italic = True) |
|
|
|
|
|
|
|
|
|
|
|
# ニジカのフォント |
|
|
nizika_font = pygame.font.SysFont ('07nikumarufont', 50) |
|
|
nizika_font = pygame.font.SysFont ('07nikumarufont', 50) |
|
|
|
|
|
|
|
|
|
|
|
# Youtube Chat から取得したコメントたち |
|
|
chat_items: list = [] |
|
|
chat_items: list = [] |
|
|
|
|
|
|
|
|
|
|
|
# 会話の履歴(3 件分保持) |
|
|
histories: list = [] |
|
|
histories: list = [] |
|
|
|
|
|
|
|
|
while (True): |
|
|
while (True): |
|
|
screen.fill ((0, 255, 0)) |
|
|
screen.fill ((0, 255, 0)) |
|
|
|
|
|
|
|
|
|
|
|
# 左上に時刻表示 |
|
|
for i in range (4): |
|
|
for i in range (4): |
|
|
screen.blit ( |
|
|
screen.blit ( |
|
|
system_font.render (str (datetime.now ()), True, (0, 0, 0)), |
|
|
system_font.render (str (datetime.now ()), True, (0, 0, 0)), |
|
|
(i % 2, i // 2 * 2)) |
|
|
(i % 2, i // 2 * 2)) |
|
|
|
|
|
|
|
|
if live_chat.is_alive (): |
|
|
if live_chat.is_alive (): |
|
|
|
|
|
# Chat オブジェクトが有効 |
|
|
|
|
|
|
|
|
|
|
|
# Chat 取得 |
|
|
chat_items: list = live_chat.get ().items |
|
|
chat_items: list = live_chat.get ().items |
|
|
|
|
|
|
|
|
if chat_items: |
|
|
if chat_items: |
|
|
|
|
|
# 溜まってゐる Chat からランダムに 1 つ抽出 |
|
|
chat_item = random.choice (chat_items) |
|
|
chat_item = random.choice (chat_items) |
|
|
|
|
|
|
|
|
|
|
|
# 投稿者情報を辞書化 |
|
|
chat_item.author = chat_item.author.__dict__ |
|
|
chat_item.author = chat_item.author.__dict__ |
|
|
|
|
|
|
|
|
|
|
|
# 絵文字を復元 |
|
|
chat_item.message = emoji.emojize (chat_item.message) |
|
|
chat_item.message = emoji.emojize (chat_item.message) |
|
|
|
|
|
|
|
|
message: str = chat_item.message |
|
|
message: str = chat_item.message |
|
|
|
|
|
|
|
|
|
|
|
# ChatGPT API を呼出し,返答を取得 |
|
|
answer: str = Talk.main (message, chat_item.author['name'], histories, goatoh_mode).replace ('\n', ' ') |
|
|
answer: str = Talk.main (message, chat_item.author['name'], histories, goatoh_mode).replace ('\n', ' ') |
|
|
|
|
|
|
|
|
|
|
|
# 履歴に追加 |
|
|
histories = (histories |
|
|
histories = (histories |
|
|
+ [{'role': 'user', 'content': message}, |
|
|
+ [{'role': 'user', 'content': message}, |
|
|
{'role': 'assistant', 'content': answer}])[(-6):] |
|
|
{'role': 'assistant', 'content': answer}])[(-6):] |
|
|
|
|
|
|
|
|
|
|
|
# ログ書込み |
|
|
with open ('log.txt', 'a') as f: |
|
|
with open ('log.txt', 'a') as f: |
|
|
f.write (f'{datetime.now ()}\t{json.dumps (chat_item.__dict__)}\t{answer}\n') |
|
|
f.write (f'{datetime.now ()}\t{json.dumps (chat_item.__dict__)}\t{answer}\n') |
|
|
|
|
|
|
|
|
|
|
|
# 吹出し描画(ニジカは上,ゴートうは下) |
|
|
screen.blit (balloon, (0, 384) if goatoh_mode else (0, 0)) |
|
|
screen.blit (balloon, (0, 384) if goatoh_mode else (0, 0)) |
|
|
|
|
|
|
|
|
|
|
|
# 視聴者コメント描画 |
|
|
screen.blit ( |
|
|
screen.blit ( |
|
|
user_font.render ( |
|
|
user_font.render ( |
|
|
'> ' + (message |
|
|
'> ' + (message |
|
@@ -92,6 +129,8 @@ class Main: |
|
|
True, |
|
|
True, |
|
|
(0, 0, 0)), |
|
|
(0, 0, 0)), |
|
|
(120, 70 + 384) if goatoh_mode else (120, 70)) |
|
|
(120, 70 + 384) if goatoh_mode else (120, 70)) |
|
|
|
|
|
|
|
|
|
|
|
# ニジカの返答描画 |
|
|
screen.blit ( |
|
|
screen.blit ( |
|
|
nizika_font.render ( |
|
|
nizika_font.render ( |
|
|
(answer |
|
|
(answer |
|
@@ -114,6 +153,7 @@ class Main: |
|
|
|
|
|
|
|
|
pygame.display.update () |
|
|
pygame.display.update () |
|
|
|
|
|
|
|
|
|
|
|
# 鳴く. |
|
|
if goatoh_mode: |
|
|
if goatoh_mode: |
|
|
if random.random () < 0.1: |
|
|
if random.random () < 0.1: |
|
|
kusa.play () |
|
|
kusa.play () |
|
@@ -124,10 +164,13 @@ class Main: |
|
|
|
|
|
|
|
|
time.sleep (1.5) |
|
|
time.sleep (1.5) |
|
|
|
|
|
|
|
|
|
|
|
# 返答の読上げを WAV ディタとして生成,取得 |
|
|
try: |
|
|
try: |
|
|
wav: bytearray | None = Aques.main (answer, goatoh_mode) |
|
|
wav: bytearray | None = Aques.main (answer, goatoh_mode) |
|
|
except: |
|
|
except: |
|
|
wav: None = None |
|
|
wav: None = None |
|
|
|
|
|
|
|
|
|
|
|
# 再生 |
|
|
if wav is not None: |
|
|
if wav is not None: |
|
|
with open ('./nizika_talking.wav', 'wb') as f: |
|
|
with open ('./nizika_talking.wav', 'wb') as f: |
|
|
f.write (wav) |
|
|
f.write (wav) |
|
@@ -136,6 +179,9 @@ class Main: |
|
|
|
|
|
|
|
|
time.sleep (10) |
|
|
time.sleep (10) |
|
|
else: |
|
|
else: |
|
|
|
|
|
# Chat オブジェクトが無効 |
|
|
|
|
|
|
|
|
|
|
|
# 再生成 |
|
|
live_chat = pytchat.create (video_id = YOUTUBE_ID) |
|
|
live_chat = pytchat.create (video_id = YOUTUBE_ID) |
|
|
|
|
|
|
|
|
pygame.display.update () |
|
|
pygame.display.update () |
|
|