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