Skip to content本文へ移動

@celesta/voicevox

音声合成に使った AudioQuery から、モーラの時刻と口パクを作る。

@celesta/voicevox は、VOICEVOX の音声合成に使った AudioQuery から、各モーラ・音素・間が WAV のどこにあるかを求め、その時刻から LipSyncTrack を作ります。会話のコンポーネント、WAV から作る口パク、LipSyncTrack は @celesta/character にあります。変換機能は独立したパッケージから読み込んでください。@celesta/character からは再エクスポートされません。

デスクトップアプリと CLI に同梱されています。ランタイムのビルド時にこのパッケージもビルドされ、File Set Up TypeScript で型定義と読み込み設定が追加されます。非公開パッケージのため npm では配布していません。ブラウザのプレイグラウンドには対応していません。

音声合成の情報に合わせて口を動かす

WAV の生成に使った AudioQuery を、速度や間の設定も含めてそのまま使ってください。トラックは Dialogue や CharacterView の lipSync に渡すか、useLipSync() で読み取れます。このパッケージ自体は音声を合成せず、VOICEVOX サーバへの通信も行いません。 AudioQuery を voicevox.tsx と同じフォルダに voicevox-query.json として保存し、以下の例の音声と口の画像は手元の素材に置き換えてください。

import * as React from 'react';
import { Assets, Composition, Rect } from '@celesta/react';
import { Character, CharacterView, Dialogue } from '@celesta/character';
import type { AssetReference } from '@celesta/react';
import type { CharacterViewReference } from '@celesta/character';

import { lipSyncFromVoicevox } from '@celesta/voicevox';
import query from './voicevox-query.json';

const track = lipSyncFromVoicevox(query);
const mira = React.createRef<AssetReference>();
const miraView = React.createRef<CharacterViewReference>();

export default function Root() {
  return (
    <Composition width={1920} height={1080} fps={30} durationInFrames={Math.ceil(track.durationInSeconds * 30)}>
      <Rect width={1920} height={1080} fill="#20243a" />
      <Assets>
        <Character
          ref={mira}
          name="Mira"
          portrait={{
            defaultExpression: 'calm',
            expressions: {
              calm: './mira/calm.png',
              smile: './mira/smile.png',
            },
            lipSync: {
              a: './mira/mouth-a.png', i: './mira/mouth-i.png',
              u: './mira/mouth-u.png', e: './mira/mouth-e.png',
              o: './mira/mouth-o.png', closed: './mira/mouth-closed.png',
            },
          }}
          subtitle={{
            x: 960, y: 940, anchorX: 0.5, anchorY: 0.5, maxWidth: 1600,
            style: {
              fontSize: 56,
              fill: { type: 'solid', color: '#ffffff' },
              stroke: { paint: { type: 'solid', color: '#3a2d52' }, width: 6 },
              align: 'center',
            },
          }}
        />
      </Assets>

      <CharacterView ref={miraView} character={mira} x={1400} y={200} />

      <Dialogue character={miraView} audio="./voices/hello.wav" lipSync={track}>
        こんにちは、ずんだもんなのだ。
      </Dialogue>
    </Composition>
  );
}

@celesta/voicevox

API 用途
lipSyncFromVoicevox(query, options?) AudioQuery を LipSyncTrack に変換します。先頭の無音も含め、WAV の開始時点が 0 秒です。
lipSyncFromVoicevox(timing) 計算済みの時刻から同じトラックを作ります。口と時刻が食い違いません。オプションは timingFromVoicevox に渡してください。
timingFromVoicevox(query, options?) すべてのモーラ・音素・間・アクセント句について、WAV の開始からの秒数を返します。形はクエリと同じで、accentPhrases[i].moras[j] が accent_phrases[i].moras[j] に対応します。声に合わせてモーラを点灯させたり、間で表情を変えたりするのに使います。
voicevoxVowelShape(vowel) 音素を a/i/u/e/o/closed に対応付けます。大文字の無声化した母音も同じ形になり、N、cl、pau、sil、未知の値は closed になります。

タイミングの設定

API 用途
frameRate 既定は VOICEVOX の音素の時間刻みである 93.75 Hz です。丸めない場合は null、別のエンジンではその時間刻みを指定します。動画の fps とは別の設定です。
interrogativeUpspeak 既定は true です。疑問文の語尾上げを無効にして音声を合成した場合は false を指定してください。

VoicevoxAudioQuery、VoicevoxAccentPhrase、VoicevoxMora、VoicevoxTiming、VoicevoxTimedAccentPhrase、VoicevoxTimedMora、VoicevoxTimedPause、VoicevoxTimedPhoneme、VoicevoxSpan、VoicevoxTimingOptions、VoicevoxLipSyncOptions もエクスポートされます。LipSyncTrack は @celesta/character から読み込みます。

インストールせずに、試してみよう。

ブラウザで Celesta を動かせます。書き出しもできます。

プレイグラウンドを開く