1
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

YMM4のセリフ入力自動化してみた

Last updated at Posted at 2023-10-21

はじめに

初めて書いた記事なので、わかりにくいかもしれませんがご容赦ください。

また、最新版を確認したい場合や、ZIPファイルでインストールしたい場合はこちら

以下のソースコードはすべてGNU General Public License v3.0の元公開されています。

こんにちは、あかずと申します。
突然ですが、皆さんはゆっくり実況を作成したことはありますか?
もし作成したことがある方は、セリフの入力が面倒だと感じたことが一度はあると思います。
というわけで、生声実況の動画をゆっくり実況に変換することで、
できる限りセリフ入力の作業を楽にしていきます。

環境

もの バージョン
Python 3.10.9
YMM4 最新版

インストール

$ pip install openai-whisper pykakasi

PyTorchのインストール

公式サイトからご自身の環境に合ったものをインストールしてください。

ffmpegのインストール

ffmpegのインストール方法を検索し、ご自身でインストールをお願いします。

準備

プロジェクトファイルの雛形を作成する

プロジェクトファイル(.ymmp)の雛形を作成し、その雛形に合わせてセリフを自動的に追加します。
以下の通りに進めてみてください。

  1. YMM4を起動します。
  2. 使用する予定のキャラクターの立ち絵を適当に全て配置します。
    (読み込むため)
  3. プロジェクト直下にdefaultフォルダを作成します。
  4. defaultの中にproject.jsonとして保存します。

セリフの雛形を作成する

少し面倒ですが、以下の通りに進めてみてください。

  1. YMM4を起動します。
  2. お好きなキャラクターで一言だけ喋らせます。
  3. defaultフォルダにitems.jsonとして保存します。
  4. items.jsonを開きます。
  5. TimelineのItemsのみを残し、それ以外を削除します。
  6. VoiceCacheの中を空の文字列にします。
    以下の様になっていたら成功です!
items.json
{
  "$type": "YukkuriMovieMaker.Project.Items.VoiceItem, YukkuriMovieMaker",
  "IsWaveformEnabled": false,
  "CharacterName": "ゆっくり魔理沙",
  "Serif": "こんばんは",
  "Decorations": [],
  "Hatsuon": "こんばんわ",
...

実装

以下のコードをプロジェクト直下にgenerate.pyとして保存してください!

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フォルダを作成したら完成です:tada:
whisperモデル一覧

$ python generate.py 音声/動画のファイルパス whisperのモデル キャラ名

最後まで読んでいただき、ありがとうございます。
お疲れ様でした!

1
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?