当サイトにはアフィリエイト広告が含まれます。なおレビューは私の感想を書いており、内容を指示するご依頼はお断りしています

スクリーンショットから会話ログを効率的に抽出!AIを活用したゲームセリフの自動文字起こし

ゲームプレイ中に登場する印象的なセリフや、物語を深く理解するための会話ログを保存したいと考える方は少なくないでしょう。しかし、これらの会話を手動で文字起こしする作業は、時間と労力を要します。

本記事では、この非効率な作業を改善し、ゲームの会話ログを効率的にテキスト化するためのツールをご紹介します。AI技術を活用することで、スクリーンショットから瞬時にセリフを抽出し、データとして活用可能な形で保存することが可能になります。


本ツールの開発背景と目的

ゲームコンテンツの分析、考察、あるいはファン活動の一環として、ゲーム内のキャラクターのセリフ対話の記録は非常に価値のある情報となります。しかし、従来の文字起こし方法には以下のような課題がありました。

  • 手作業による膨大な時間的コスト: 大量のセリフを一つ一つ手入力するのは、非常に時間がかかります。
  • 集中力の維持とヒューマンエラー: 長時間の作業は集中力の低下を招き、入力ミスや誤字脱字の原因となります。
  • データ活用における非効率性: テキストデータとして整理されていない場合、後からの検索や分析が困難になります。

これらの課題を解決し、より快適で生産的なゲーム体験を提供するために、AIによる自動文字起こしツールの開発に至りました。このツールは、ゲーム実況者ゲーム攻略サイト運営者ゲーム開発者、そして熱心なゲーマーの皆様にとって、強力なサポートとなることを目指しています。


本ツールの主要機能

本ツールは、主に以下の二つの機能を提供します。

  1. 特定のゲームウィンドウの自動スクリーンショット撮影機能: 本ツールは、指定したゲームウィンドウ(例: LonelyScreenなどのミラーリングツール)の画面を自動でキャプチャします。これにより、手動でのスクリーンショット撮影の手間を省き、安定した画像取得を実現します。 撮影された画像ファイルは、指定されたディレクトリに自動的に保存されるため、ファイル管理の負担も軽減されます。
  2. 撮影画像からのAIによる会話ログ自動文字起こし機能: この機能は、OpenAIが提供する高度なAIモデル(GPT-4o)を活用し、キャプチャされた画像内の会話テキストを認識し、文字起こしを行います。 文字起こし結果は、キャラクター名メッセージ内容を明確に区別したJSON形式で出力されます。これにより、ブログ記事への埋め込み、データベースへの格納、データ分析など、多岐にわたる用途での利用が容易になります。


ツールの導入と利用方法

本ツールは、Windows環境において、シンプルな操作でご利用いただけます。デスクトップにショートカットを配置すれば、ゲームプレイ中にワンクリックで文字起こしを実行することが可能です。

1. .batファイルの準備と保存

まず、以下の内容を含むscreenshot.batファイルを作成し、任意の分かりやすい場所に保存してください。例えば、Pythonスクリプトと同じフォルダや、C:\Tools\GameLogTranscriber\のような専用フォルダが推奨されます。

@echo off
python "screenshot.py" --output "images/" --dialog --delete-screenshot-after-dialog

このバッチファイルは、Pythonスクリプトを実行するためのものです。--dialogオプションは文字起こし機能の有効化を、--delete-screenshot-after-dialogオプションは文字起こし完了後に元のスクリーンショット画像を自動で削除する機能を示します。

2. Pythonスクリプトの準備

次に、以下のscreenshot.pyおよびmy_openai.pyの2つのPythonスクリプトを準備してください。

import pyautogui
import time
import os
import datetime
import argparse
import mss
from my_openai import MyOpenAI
from dotenv import load_dotenv
from PIL import Image

def lonely_screen_screenshot(output_dir="./screenshots/"):
    os.makedirs(output_dir, exist_ok=True)
    try:
        window_title = "LonelyScreen AirPlay Receiver"
        
        with mss.mss() as sct:
            try:
                lonelyscreen_window = pyautogui.getWindowsWithTitle(window_title)[0]
                
                monitor = {
                    "top": lonelyscreen_window.top + 110,
                    "left": lonelyscreen_window.left + 10,
                    "width": lonelyscreen_window.width - 20,
                    "height": lonelyscreen_window.height - 175
                }
                
                timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
                screenshot_filename = os.path.join(output_dir, f"lonelyscreen_game_mode_{timestamp}.png")
                
                sct_img = sct.grab(monitor)
                img = Image.frombytes("RGB", sct_img.size, sct_img.bgra, "raw", "BGRX")
                img.save(screenshot_filename)
                
                print(f"スクリーンショットを保存しました: {screenshot_filename}")
                return screenshot_filename

            except IndexError:
                print(f"LonelyScreenのウィンドウ(タイトル: '{window_title}')が見つかりませんでした。起動状態を確認してください。")
            except Exception as e:
                print(f"pyautoguiによるウィンドウ取得中にエラーが発生しました: {e}")

    except Exception as e:
        print(f"mssによるスクリーンショット中にエラーが発生しました: {e}")
        print("mssが環境に対応していないか、別の問題が発生している可能性があります。")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="スクリーンショットを撮ります")
    parser.add_argument("-o", "--output", type=str,
                         help="出力ログファイルのフルパス (例: ./screenshots/)。")
    parser.add_argument('--dialog', action='store_true', help='文字起こしを行う')
    parser.add_argument('--delete-screenshot-after-dialog', action='store_true', help='文字起こし後にスクリーンショットファイルを削除するかどうか')
    args = parser.parse_args()
    output_dir = './screenshots/'
    if args.output:
        output_dir = args.output

    screenshot_filename = lonely_screen_screenshot(output_dir)

    if args.dialog:
        load_dotenv('.env')
        OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
        
        dialog_dir = output_dir + 'dialog/'
        dialog_file = dialog_dir + "dialog.log"
        os.makedirs(dialog_dir, exist_ok=True)

        my_client = MyOpenAI(OPENAI_API_KEY)
        dialog_json = my_client.get_dialogue_from_image(image_paths = [screenshot_filename])
        dialog = ""
        for line in dialog_json:
            record = line['message'] + '\n'
            if (line['character']):
                record = line['character'] + ": " + record
            dialog += record

            
        with open(dialog_file, 'a', encoding='utf-8-sig') as f:
            f.write(dialog)

        if args.delete_screenshot_after_dialog:
            try:
                os.remove(screenshot_filename)
            except Exception as e:
                print(f"警告: 画像ファイルの削除に失敗しました: {screenshot_filename} → {e}")
import openai
import os
import json
import time
from datetime import date, datetime
import base64
import re


class MyOpenAI:
    def __init__(self, api_key: str):
        if not api_key:
            raise ValueError("APIキーは必須です。")
        self.api_key = api_key
        openai.api_key = self.api_key

    def _encode_image_to_base64(self, image_path: str) -> str:
        with open(image_path, "rb") as image_file:
            return base64.b64encode(image_file.read()).decode("utf-8")


    def get_dialogue_from_image(self, image_paths):
        user_input = '''以下のjson形式で文字起こしをしてください
【出力形式】
[
    {
        'character': キャラ名,
        'message': セリフ
    },
    {
        'character': キャラ名,
        'message': セリフ
    },
]
'''
        system_content = "スクリーンショットの内容を文字おこししてください"
        messages = []
        content_block = [{"type": "text", "text": user_input}]
        if image_paths:
            for path in image_paths:
                if os.path.exists(path):
                    image_data_url = self._encode_image_to_base64(path)
                    content_block.append({
                        "type": "image_url",
                        "image_url": {"url": f"data:image/jpeg;base64,{image_data_url}"}
                    })

            messages.append({"role": "user", "content": content_block})

        response = openai.ChatCompletion.create(
            model="gpt-4o",
            messages=messages,
            temperature=0.8
        )
        print(f"応答内容: {response['choices'][0]['message']['content']}")

        cleaned_text_data = response['choices'][0]['message']['content'].replace("```json", "").replace("```", "").strip()
        match = re.search(r'\[.*\]', cleaned_text_data, re.DOTALL)
        if match:
            cleaned_text_data = match.group(0)
        else:
            cleaned_text_data = "[]"
        
        try:
            response_json = json.loads(cleaned_text_data)
        except json.JSONDecodeError as e:
            print(f"警告: JSONデコードに失敗しました: {e}")
            print(f"試行された文字列: {cleaned_text_data}")
            return []

        return response_json

それぞれのスクリプトの主な役割は以下の通りです。

  • screenshot.py:ゲーム画面のスクリーンショット撮影と、取得した画像をAI処理モジュールへ渡す役割を担います。
  • my_openai.py:OpenAI APIを利用し、画像データからの文字起こし処理の中核を担います。

3. デスクトップにショートカットを作成する

本ツールをワンクリックで利用するために、デスクトップにショートカットを作成します。

  1. デスクトップの何もない場所を右クリックし、「新規作成」から「ショートカット」を選択します。
  2. 「項目の場所を入力してください:」の欄に、手順1で保存したscreenshot.batファイルのフルパスを入力します(例: C:\MyScripts\screenshot.bat)。入力後、「次へ」をクリックします。
  3. 「このショートカットの名前を入力してください:」の欄に、「ゲーム会話ログ文字起こし」など、分かりやすいショートカット名を入力し、「完了」をクリックします。
  4. (任意)作成したショートカットアイコンを右クリックし、「プロパティ」から「アイコンの変更」を選択することで、任意のアイコンに変更できます。

導入に必要な環境と留意事項

本ツールをご利用いただくにあたり、以下の点にご留意ください。

  • Python実行環境: お使いのPCにPythonがインストールされている必要があります。
  • 必須ライブラリ: pyautoguimssなどのPythonライブラリが必要です。これらはpip installコマンドで簡単に導入可能です。詳細は各Pythonスクリプトの冒頭をご参照ください。
  • OpenAI APIキー: AIによる文字起こし機能を利用するためには、OpenAIのAPIキーが必須となります。APIキーの取得には費用が発生しますが、その利便性は十分に投資価値があるかと存じます。APIキーは、セキュリティの観点から.envファイルに設定することを強く推奨いたします。

結び

本ツールは、ゲームの会話ログの記録という、これまで手間のかかっていた作業を大幅に効率化します。これにより、プレイヤーの皆様はゲームのストーリーやキャラクターのセリフをより深く分析し、考察するための時間を確保できるようになるでしょう。

ぜひ本ツールをご活用いただき、皆様のゲーム体験の質向上にお役立てください。