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