BlenderでVOICEVOXの音声をPythonで追加


概要

CSVで用意したテキストをVOICEVOXで音声ファイルを作り、Blenderで取り込みます。
これをPythonで行う方法を紹介します。

準備(VOICEVOXのインストールと実行)

VOICEVOXは、無料で使える中品質なテキスト読み上げソフトウェアです。
使用においては、VOICEVOXの利用規約をご確認ください。

下記のサイトから、インストーラーをダウンロードしてインストールしてください。

インストールしたら、起動してください。
起動したら、GUIでも使えますが、Webサーバーとしても起動します。
Blenderからはcurlを使ってWebサーバーの方にアクセスします。
もし、curlが入ってなければ、インストールしておいてください。

手順

Blenderを起動し、下図のように2つのテキストエディターとビデオシーケンサーを開いてください。

CSV

「時刻(秒)、キャラクター番号、テキスト」を書いたCSVファイルを用意してください。下記はサンプルです。

voice.csv
0,2,3DCGなら
1.6,12,ブレンダー!

1つ目のテキストエディターでCSVを開いてください。
ファイル選択画面で、デフォルトでCSVは見えませんが、右上のフィルターをオフにすると見えるようになります。

Pythonコード

2つ目のテキストエディターの新規を押し、下記をコピペしてください。

import bpy
import csv
import time
from pathlib import Path
from subprocess import run

csvfile = [text.filepath for text in bpy.data.texts
           if text.filepath.endswith(".csv")][0]

se = bpy.context.scene.sequence_editor
header = "Content-Type: application/json"
fps = bpy.context.scene.render.fps

tmp = Path("/tmp")
pth = tmp /" wav"
pth.mkdir(exist_ok=True)

# delete all sequence
for s in se.sequences_all:
     se.sequences.remove(s)

with open(csvfile) as fp:
    for i, ss in enumerate(csv.reader(fp), 1):
        try:
            sec, *mnt = map(float, reversed(("0:" + ss[0]).split(":")))
            speaker = int(ss[1])
            text = ss[2]
        except (IndexError, ValueError):
            print(f"Error at line {i}: {ss}")
            break
        frame_start = int((mnt[0] * 60 + sec) * fps)
        url = f"localhost:50021/{{}}?speaker={speaker}"
        namt = str(tmp / "text.txt")
        with open(namt, "w") as fp:
            fp.write(text)
        cmd = f'curl -s -X POST {url.format("audio_query")} --get --data-urlencode text@{namt}'
        res = run(cmd.split(), capture_output=True)
        namq = str(tmp / "query.json")
        with open(namq, "w") as fp:
            fp.write(res.stdout.decode())
        cmd = f'curl -s -H {header} -X POST -d @{namq} {url.format("synthesis")}'
        res = run(cmd.split(), capture_output=True)
        nama = f"audio{i:03}.wav"
        with open(pth / nama, "wb") as fp:
            fp.write(res.stdout)
        ss = se.sequences.new_sound(nama, str(pth / nama), i * 2, frame_start)
        ss = se.sequences.new_effect(f"txt{i:03}", "TEXT", i * 2 + 1, frame_start, frame_end=ss.frame_final_end)
        ss.text = text
        time.sleep(0.1)

上記のPythonコードを実行すると、CSVを読み込んで音声ファイルを作成して取り込みます。
スペースキーを押すと再生します。

また、下記の設定でアニメーションレンダリングすると、音声と字幕付きで作成できました。

  • ファイルフォーマット:FFmpeg動画
  • エンコーディング
    • コンテナ:MPEG-4
    • オーディオ
      • 音声コーデック:AAC

以上