AIでミュージックビデオを作った話
ラッパーの楽曲のミュージックビデオを作るにあたり、嬉しいことにAI作画を担当させてもらいました。中身は基本的に僕が前から推しているStable Diffusion Videos (nateraw/stable-diffusion-videos, SDV)で実装しています。
Moisture - NNC a.k.a. DJ KYOHEI
空に唄えば - NNC a.k.a. DJ KYOHEI
中身のこと
この背景で流れている映像を担当しました。ひとつめのMoistureでは、アーバンな曲調に合わせて煌びやかな街並みが流れ移りゆくようなものをイメージしていて、ミュージックビデオとはいっても今回は厳密にはリリックビデオ、あるいは最近でいうところのVisualizerなので、細かいところはあまり気にしていません。なのでよくよくみると細部(たとえば顔とかそれこそ手とか)はかなり描画が雑になっています。
SDVは基本的には作成した2枚のイラストを使って、1枚目から2枚目への遷移を段階的に作成するライブラリ。つまり、ある(非常に短時間の)ワンシーンにおける映像の始まりと終わりの画像をプロンプトで指定することで2枚の画像が生成され、あとはその中間がザクザク作られていくイメージ。
つまり具体的な生成プロセスにおいては1回の映像出力に対して2つのプロンプトを突っ込まなければいけないんだけど、これが結構難しい。そもそもその2枚を思い通りに出力させるのが難しい上に、その遷移の最中に意外と全然違う方向にビジュアルが吹っ飛んだりもする。そこで(これはある種のテクニックとして)、今回の画像生成では一回の出力で使うプロンプトには2つとも同じものを指定して、シード値だけを変える形で作成した。
たとえば以下の2つは"many black shadows walking in the bright night city"的なプロンプト(厳密な表現は忘れた)を指定したもの。
これら2枚に対してimage-to-imageで中間層18枚(つまり始まりから終わりまで全部で20フレーム)込みで動画にしていく形で各シーンを作っていった。
SDVはColab上でGUI的な感じで走らせることができるけど、そんなことやってたら量を生成することは無理なので、内部のpipeline.walkのコードをひっぱってきてこちらでgenerate_videos的な感じで関数化していて、
def generate_videos(text, seed=10, fps=30, iter=20):
h = 512; w = 768
video_path = pipeline.walk(
[text]*2,
[seed, seed+1],
fps=fps, # use 5 for testing, 25 or 30 for better quality
num_interpolation_steps=iter, # use 3-5 for testing, 30 or more for better results
height = h, # use multiples of 64 if > 512. Multiples of 8 if < 512.
width = w, # use multiples of 64 if > 512. Multiples of 8 if < 512.
output_dir=outdir
)
print(video_path)
visualize_video_colab(video_path)
ここではそもそも指定できるプロンプトは1つ、シードも一つ指定したら終わりはその1つ次の値になるようにしていて、あとはこれをループさせて
texts = [
"many black shadows walking in the bright night city",
"blah blah",
]
for t in texts:
for s in range(10):
generate_videos(text=t,seed=100+s, fps=30, iter=20)
みたいな感じで各プロンプトに対してとにかく大量に素材を作って、どれを使うかは後で考えるぐらいがちょうどいい。
ちなみにこのコードだと各プロンプトに対してseed100→101, 101→102, ..., っていうふうに動画が作られていくわけだけど、前の動画とプロンプト、シードを全く同じにしておくというのがポイントになっていて、そうしておけば前の動画からちょうど繋がる。つまり多少長めのシーケンスを作成できる。
大量のプロンプトとランダムシードで素材を作りまくって(たぶん3000件ぐらいは作ったんじゃないかな)、実際の映像編集は(めんどくさいから)Premiere Proでやりました。でも、振り返るとPythonでやった方が楽だったかもしれない。
まあこんな感じでまだ何件か依頼が来ているのでこなしていく。