Ccmmutty logo
Commutty IT
4 min read

【Blender】音声ファイルから3Dモデルの口パク動画を生成する

https://cdn.magicode.io/media/notebox/3a1a24d8-58e4-47dd-8e31-7ec3159f79b9.jpeg
3Dモデルの口パク動画を作りたいと思ったのですが毎回GUIで作るのも手間なので、スクリプトで生成できないか試してみたものになります。
メモ程度なので雑なところはありますが、自身のユースケースに合わせて改良してみてください

使い方

Blenderを開き、事前にカメラの位置とポーズを調整しておく

テキストエディタを開く

テキストエディタに以下の内容をコピペ

import bpy
import wave

"""
変数の定義
"""
# 口パクの元となる音声ファイルのパスを指定
sound_file_path = "input/input.wav"
# 出力する動画のファイルフォーマットを指定
output_file_format = "AVI_JPEG"
# 出力する動画のパスを指定
output_video_path = "output/video"
# シェイプキーを持つオブジェクト名を指定
object_name = "Face.001"
# シェイプキー名を指定
shape_key_name = "Fcl_MTH_A"
# 作成するアニメーションの名前を指定
action_name = "Face.action.001"

"""
メイン処理
"""
# 音声の長さを取得
with wave.open(sound_file_path, 'rb') as wf:
    frames = wf.getnframes()
    rate = wf.getframerate()
    duration = frames / float(rate)

# レンダリング時のフレームレートを取得
scene = bpy.context.scene
fps = scene.render.fps

# 音声の長さとフレームレートから最終フレーム位置を計算
last_frame = int(duration * fps)

# シェイプキーオブジェクトの取得
obj = bpy.data.objects.get(object_name)
shape_key = obj.data.shape_keys.key_blocks.get(shape_key_name)
shape_key_name = shape_key.name

# オブジェクトに対してアニメーションデータを作成
if obj.animation_data is None:
    obj.animation_data_create()

# アニメーションのアクションを作成
action = obj.animation_data.action
if action is None:
    action = bpy.data.actions.new(name=action_name)
    obj.animation_data.action = action

# 既存のチャンネル削除 (既存のアニメーションが消えるので、確認した上でコメントアウトを外してください)
bpy.context.area.type = 'GRAPH_EDITOR'
# bpy.ops.anim.channels_delete()

# レンダリングの開始と終了位置を指定
frame_start = 0
frame_end = last_frame

# タイムラインを設定
bpy.context.scene.frame_set(frame_start)
bpy.context.scene.frame_end = frame_end

# シェイプキーの値に対してキーフレームを追加
shape_key.keyframe_insert(data_path="value", frame=frame_start)
shape_key.keyframe_insert(data_path="value", frame=frame_end)

# オブジェクトをアクティブに設定
bpy.context.view_layer.objects.active = obj

# Fカーブにベイク
bpy.ops.graph.sound_bake(filepath=sound_file_path)

# アニメーションを再生
bpy.ops.screen.animation_play()

# レンダリング設定
bpy.context.scene.render.image_settings.file_format = output_file_format
bpy.context.scene.render.filepath = output_video_path

# ビューで動画をレンダリング
bpy.ops.render.render(animation=True)

スクリプト内の変数を埋める

  • sound_file_path
  • output_file_format
  • output_video_path
  • object_name
  • shape_key_name
  • action_name

実行する

スクリプトを実行する

完成品

音声は無しです。
ビデオシーケンサーに音声データを追加する処理をスクリプトに追加することで音声を入れることもできます。

Discussion

コメントにはログインが必要です。