セリフと効果音をプロンプトの決まった位置に置く:Wan 2.5 用の小さなプロンプト組み立て関数
Wan 2.5 は、ページの説明によると、動画と同時に人の声を生成できる初めての Wan モデルです。セリフを書けば口の動き、表情、身ぶりに合わせて声が入り、環境音や効果音、BGM も同じプロンプトから生成されます。便利な反面、映像の指示と音の指示が1つの文章に混ざるので、手で書いていると順番がばらばらになりがちです。この記事では、ショットの情報を辞書で持ち、決まった順番でプロンプトに組み立てる小さな関数を作ります。
ページに書かれているコツ
音について、ページには次のような説明があります。「プロンプトの最後に欲しい音を並べておけば、シーン全体に音が付きます。きまた、カメラの動きはふだんの言葉で書くだけで十分で、複数の出来事が順番どおりに起こるとも書かれています。テキストから動画では 16:9、9:16、1:1 を選べ、解像度は 720p または 1080p です。
この「音は最後」というルールをコードで固定してしまえば、誰が書いても同じ構造のプロンプトになります。
データの形
関数
def build_prompt(shot: dict) -> str:
parts = [
f"{shot['subject']}が{shot['action']}。",
f"カメラは{shot['camera']}。",
]
for speaker, line in shot.get("lines", []):
parts.append(f"{speaker}が「{line}」と言う。")
if shot.get("sounds"):
parts.append("音:" + "、".join(shot["sounds"]) + "。")
if shot.get("no_music"):
parts.append("BGMなし。")
return "".join(parts)
shot = {
"subject": "白いエプロンの店主",
"action": "カウンター越しにコーヒーを差し出す",
"camera": "ゆっくり寄る",
"lines": [("店主", "いらっしゃいませ、今日は雨ですね")],
"sounds": ["窓を打つ雨音", "カップをソーサーに置く音"],
"no_music": True,
}
print(build_prompt(shot))
出力は「白いエプロンの店主がカウンター越しにコーヒーを差し出す。カメラはゆっくり寄る。店主が「いらっしゃいませ、今日は雨ですね」と言う。音:窓を打つ雨音、カップをソーサーに置く音。BGMなし。」のようになります。映像、セリフ、音の順番が常に同じなので、複数のショットを並べて見比べるのも簡単です。
なぜセリフを独立させるのか
セリフは一番間違えたくない部分です。文章の途中に埋め込むと、言い回しを直したつもりで別の箇所まで変えてしまうことがあります。リストで持っておけば、セリフだけを差し替えて再生成できます。話者を必ず書くのも同じ理由で、複数人が登場するショットで誰が話すのかをはっきりさせます。
画像から動画にする場合
ページによると、1枚の画像を最初のフレームとしてアップロードすると、顔、衣装、商品、絵のタッチは元の画像に近いまま動き出します。この場合は subject に外見の説明を長く書く必要はなく、action と camera、それに音を中心に書けば十分です。関数はそのまま使えます。
複数ショットをまとめて扱う
ショットが増えてきたら、辞書のリストを JSON ファイルにして、ループで全部のプロンプトを出力すると便利です。ファイル名にショット番号を付けておけば、生成した動画と対応づけるのも簡単です。修正したときは JSON の該当キーだけを書き換え、Git などで差分を残しておくと、どの変更でどの結果になったのかをあとから追えます。
生成後の確認
確認は映像と音を分けて行うと効率的です。まず音を消して動きとカメラを見て、次に画面を見ずに音だけを聞きます。セリフの文言が指定どおりか、効果音のタイミングが不自然でないかは、音だけを聞いたほうが気づきやすくなります。
まとめ
プロンプトを「文章」ではなく「データ」として扱うと、修正の単位が小さくなります。セリフだけ、音だけ、カメラだけを変えて再生成できるので、どの変更が結果を良くしたのかが分かりやすくなります。ショットの辞書を JSON で保存しておけば、あとから同じ構成で別のシーンを作るときにもそのまま使えます。



