このチュートリアルは面白かったです。
Databricksで動かしました。翻訳したノートブックはこちらです。
%pip install opencv-python
%pip install -U openai
%restart_python
このノートブックは、ビデオを使用してGPTの視覚的な機能を示します。GPT-4oはビデオを直接入力として受け取りませんが、ビジョンと128Kコンテキストウィンドウを使用して、ビデオ全体の静止フレームを一度に説明することができます。2つの例を通して説明します:
- GPT-4oを使用してビデオの説明を取得する
- GPT-oとTTS APIを使用してビデオのナレーションを生成する
from IPython.display import display, Image, Audio
import cv2 # ビデオを読み取るためにOpenCVを使用しています。インストールするには !pip install opencv-python
import base64
import time
from openai import OpenAI
import os
import requests
client = OpenAI(api_key=dbutils.secrets.get("demo-token-takaaki.yayoi", "openai_api_key"))
os.environ['OPENAI_API_KEY'] = dbutils.secrets.get("demo-token-takaaki.yayoi", "openai_api_key")
1. GPTの視覚的な機能を使用してビデオの説明を取得する
まず、OpenCVを使用して鳥が写っている動画(うちのインコたちです)からフレームを抽出します:
video = cv2.VideoCapture("data/birds.MP4")
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.")
1350 frames read.
フレームが正しく読み込まれたことを確認するために表示します:
Databricksノートブックでは以下のコードブロックは動きませんでした。
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)
ビデオフレームを取得したら、プロンプトを作成してGPTにリクエストを送信します(GPTが状況を理解するためにすべてのフレームを送信する必要はありません):
PROMPT_MESSAGES = [
{
"role": "user",
"content": [
"これはアップロードしたいビデオのフレームです。ビデオと一緒にアップロードできる魅力的な説明を生成してください。",
*map(lambda x: {"image": x, "resize": 768}, base64Frames[0::50]),
],
},
]
params = {
"model": "gpt-4o",
"messages": PROMPT_MESSAGES,
"max_tokens": 200,
}
result = client.chat.completions.create(**params)
print(result.choices[0].message.content)
愛らしいインコたちが冒険中!彼らの色鮮やかな羽根が魅力的な動きを見せ、毎日がまるでカラフルな物語の一部みたい。このビデオで彼らの小さな世界をお楽しみください!🌈🐦
ここでもMLflow Tracingで動作を確認できます。
2. GPT-4とTTS(Text To Speech) APIを使用したビデオのナレーション生成
このビデオのナレーションをデイビッド・アッテンボロー風に作成しましょう。同じビデオフレームを使用して、GPTに短いスクリプトを作成させます:
PROMPT_MESSAGES = [
{
"role": "user",
"content": [
"これらはビデオのフレームです。デイビッド・アッテンボローのスタイルで短いナレーションスクリプトを作成してください。ナレーションのみを含めてください。",
*map(lambda x: {"image": x, "resize": 768}, base64Frames[0::60]),
],
},
]
params = {
"model": "gpt-4o",
"messages": PROMPT_MESSAGES,
"max_tokens": 500,
}
result = client.chat.completions.create(**params)
print(result.choices[0].message.content)
今、我々は小さな世界の一端を垣間見ることができます。この愛らしいインコたちは、興味津々に身の回りの世界を探検しています。彼らは何を見つけるのでしょうか?
そのカラフルな羽を輝かせながら、彼らは新しい発見を楽しんでいます。好奇心旺盛な彼らにとって、どんな小さな物も興味の対象です。テーブルの上に置かれたアイテムに向かい、細やかな視線を送るその姿には、身近な自然の神秘が詰まっています。
インコたちが日々新しい何かを見つけ出すその冒険心こそが、彼らを自然界の究極の探求者にしているのです。
次に、スクリプトをTTS APIに渡して、ナレーションのmp3を生成します:
response = requests.post(
"https://api.openai.com/v1/audio/speech",
headers={
"Authorization": f"Bearer {os.environ['OPENAI_API_KEY']}",
},
json={
"model": "tts-1-1106",
"input": result.choices[0].message.content,
"voice": "onyx",
},
)
audio = b""
for chunk in response.iter_content(chunk_size=1024 * 1024):
audio += chunk
Audio(audio)
以下のようにプレーヤーが表示されるので、音声を確認できます(以下は画像を貼り付けているだけなので再生できません)。保存した音声ファイルはこちらです。
音声ファイルを保存します。
with open('data/birds_narration.wav', 'wb') as f:
f.write(audio)
これで、元の動画と生成されたナレーションが揃ったので、iMovieなどでまとめます。結果がこちらです。
なにこれ楽しい。他の動画でも作ってみたくなりました。