GPT-4Vを使ってゲーム実況させる

# はじめに

GPT-4Vを使ってゲーム実況をさせてみます。
この記事はLLM Advent Calendar 2023の12月14日のアドベントカレンダー記事となります。

# 解説

以下のようなゲーム実況スクリプトを自動で作成できる状態が、この記事のゴールです。

<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">「お気に入りのゲーム実況をする、超興奮した日本人人気VTuberのスタイルで、短いナレーションスクリプトを作成してください」でゲームプレイ動画をGPT-4Vに入れてみました。GPT-4Vやっぱり性能いいなぁ (TTSはvoicevox使用) <a href="https://t.co/GR1kcMYENN">pic.twitter.com/GR1kcMYENN</a></p>&mdash; inada (@dev_inada) <a href="https://twitter.com/dev_inada/status/1721927636748738830?ref_src=twsrc%5Etfw">November 7, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## コード

と言っても、コード自体は数10行で、以下の通り簡単に実装できます。

```
from IPython.display import display, Image
import base64
import cv2
import openai
import requests
import tempfile
import time

with tempfile.NamedTemporaryFile(suffix=".mp4") as f:
    with open(f.name, "wb") as f2:
        f2.write(requests.get("https://raw.githubusercontent.com/takaaki-inada/rinna-4b-multimodal-hello-aituber/main/mock_sample.mp4").content)

    video = cv2.VideoCapture(f2.name)
    base64Frames = []
    while video.isOpened():
        success, frame = video.read()
        if not success:
            break
        _, buffer = cv2.imencode(".jpg", frame)
        base64Frames.append(base64.b64encode(buffer).decode("utf-8"))

    video.release()
    print(len(base64Frames), "frames read.")

display_handle = display(None, display_id=True)
for img in base64Frames:
    display_handle.update(Image(data=base64.b64decode(img.encode("utf-8"))))
    time.sleep(0.025)

PROMPT_CONTENT = """
これはゼルダの伝説のゲームプレイ動画です。
お気に入りのゲーム実況をする、超興奮した日本人人気VTuberのスタイルで、ゲームの次の展開を予想しながら短いナレーションスクリプトを作成してください。
ゼルダの伝説の大ファンで、興奮を伝えるために、必要に応じて大文字や感嘆符を使ってください。
"""

PROMPT_MESSAGES = [
    {
        "role": "user",
        "content": [
            PROMPT_CONTENT,
            *map(lambda x: {"image": x}, base64Frames[0::60]),
        ],
    },
]
params = {
    "model": "gpt-4-vision-preview",
    "messages": PROMPT_MESSAGES,
    "api_key": "ここに OpenAI の APIKey をセット",
    "headers": {"Openai-Version": "2020-11-07"},
    "max_tokens": 256,
}

result = openai.ChatCompletion.create(**params)
print(result.choices[0].message.content)

```

実行にはOpenAIのAPIKeyの発行が必要です。
APIKeyを発行して上記コードにセットして実行すると、こんな感じの実況スクリプトを作成してくれます。

> エヴェリボディー、こんにちはー！今日は「ゼルダの伝説 ブレス オブ ザ ワイルド」の冒険を進めていくよー！今、僕たちはなんとか難関を乗り越えて、高い高い山に登ってきたぞ！見てくれ、この絶景！ハイラルの大地がこんなにも広大で美しいなんて、もう感動しちゃうよね！
> さてさて、この先にはどんな秘密があるのかな？ここは分かれ道だ！左に行くべきか、右に行くべきか…うーん、迷っちゃうなあ。でもね、この看板を信じてみよう！そうだ、風の向くまま、心のままに行くんだ！

## リアルタイムプレイへの適用

ゼルダのプレイ画面で、リアルタイムに過去15秒分のフレームで実況させるとこんな感じになります。

<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">ゼルダ実況ずんだもんv0.21(GPT-4V / youri7b 併用版) 今年もそろそろ年末なので現状を一旦、自分のmemoかねて。過去15秒15フレームを使って実況。GPT-4V使うとさすがに状況認識能力があがって、前回１割ぐらいの打率(状況認識能力)が５割ぐらいまであがった感じ。 <a href="https://t.co/WPbixDURVo">pic.twitter.com/WPbixDURVo</a></p>&mdash; inada (@dev_inada) <a href="https://twitter.com/dev_inada/status/1734945923804057612?ref_src=twsrc%5Etfw">December 13, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">ゼルダ実況ずんだもんAI v0.21(GPT-4V / youri7b 併用版) memoその2。GPT-4Vの状況認識能力の追加確認用かな。GPT-4Vさまさまなので何も自分は大したことしてないです。仕組み気になる人は以前のrinna4b版のqiitaまとめ記事あるので見てねー <a href="https://t.co/U14JHUjxpq">pic.twitter.com/U14JHUjxpq</a></p>&mdash; inada (@dev_inada) <a href="https://twitter.com/dev_inada/status/1734961633875902810?ref_src=twsrc%5Etfw">December 13, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

さすがGPT-4Vだけあって、なかなかの状況認識能力を感じさせます。

リアルタイム版の仕組みの記事はこちらです。

https://qiita.com/takaaki_inada/items/62e6f21cb2dbdae43ed4

# おわりに

コードを貼りつけただけの簡単な記事ですみません。どたなかのお役に立てれば幸いです。