はじめに
初めて書いた記事なので、わかりにくいかもしれませんがご容赦ください。
また、最新版を確認したい場合や、ZIPファイルでインストールしたい場合はこちら
以下のソースコードはすべてGNU General Public License v3.0の元公開されています。
こんにちは、あかずと申します。
突然ですが、皆さんはゆっくり実況を作成したことはありますか?
もし作成したことがある方は、セリフの入力が面倒だと感じたことが一度はあると思います。
というわけで、生声実況の動画をゆっくり実況に変換することで、
できる限りセリフ入力の作業を楽にしていきます。
環境
もの | バージョン |
---|---|
Python | 3.10.9 |
YMM4 | 最新版 |
インストール
$ pip install openai-whisper pykakasi
PyTorchのインストール
公式サイトからご自身の環境に合ったものをインストールしてください。
ffmpegのインストール
ffmpegのインストール方法を検索し、ご自身でインストールをお願いします。
準備
プロジェクトファイルの雛形を作成する
プロジェクトファイル(.ymmp)の雛形を作成し、その雛形に合わせてセリフを自動的に追加します。
以下の通りに進めてみてください。
- YMM4を起動します。
- 使用する予定のキャラクターの立ち絵を適当に全て配置します。
(読み込むため) - プロジェクト直下にdefaultフォルダを作成します。
- defaultの中にproject.jsonとして保存します。
セリフの雛形を作成する
少し面倒ですが、以下の通りに進めてみてください。
- YMM4を起動します。
- お好きなキャラクターで一言だけ喋らせます。
- defaultフォルダにitems.jsonとして保存します。
- items.jsonを開きます。
- TimelineのItemsのみを残し、それ以外を削除します。
- VoiceCacheの中を空の文字列にします。
以下の様になっていたら成功です!
{
"$type": "YukkuriMovieMaker.Project.Items.VoiceItem, YukkuriMovieMaker",
"IsWaveformEnabled": false,
"CharacterName": "ゆっくり魔理沙",
"Serif": "こんばんは",
"Decorations": [],
"Hatsuon": "こんばんわ",
...
実装
以下のコードをプロジェクト直下にgenerate.pyとして保存してください!
import whisper
import time
from pykakasi import kakasi
import json
import re
import sys
# 読み込み
def read(path):
with open(path, "r", encoding="utf-8-sig") as file:
return json.load(file)
# 書き込み
def save(path, data):
with open(path, "w", encoding="utf-8") as file:
json.dump(data, file, indent=4, ensure_ascii=False)
# 数字変換
def convert_numbers(word):
pattern = r"\d+"
matches = re.findall(pattern, word)
for match in matches:
word = word.replace(match, f"<NUMK VAL={match}>")
return word
# ひらがなに変換
def convert_hiragana(word):
kks = kakasi()
converted = kks.convert(word)
result = ""
for converted_word in converted:
result += f"{converted_word['hira']}"
return convert_numbers(result)
# 入力
args = sys.argv
# 初期化
model = whisper.load_model(args[2])
default_items = read("./default/items.json")
default_project = read("./default/project.json") # .copy()
# 処理
print("---変換開始---")
start = time.time()
result = model.transcribe(
args[1], # ファイルパス
verbose=True,
language="ja",
)
end = time.time()
print(f"---変換終了---\n変換時間{end-start}秒です。")
# 書き出し
items = []
for i, j in enumerate(result["segments"]):
items.append(default_items.copy())
items[i]["Serif"] = j["text"].replace("!", "")
items[i]["Hatsuon"] = convert_hiragana(j["text"])
items[i]["VoiceLength"] = "00:00:" + str(j["end"] - j["start"])
items[i]["Length"] = int(j["end"] - j["start"]) * 60
items[i]["Frame"] = int(j["start"] * 60)
items[i]["CharacterName"] = str(sys.argv[3])
default_project["Timeline"]["Items"] = items
file_path = input("---書き出し完了---\nファイル名: ")
save(f"./export/{file_path}.ymmp", default_project)
実行
実行の前にexportフォルダを作成したら完成です
whisperモデル一覧
$ python generate.py 音声/動画のファイルパス whisperのモデル キャラ名
最後まで読んでいただき、ありがとうございます。
お疲れ様でした!