Newer
Older
remotion_docker_devcontainer / voicevox-remotion-template / src / data / zundamon-jiron / script.ts
import {
  audio,
  wait,
  defineVQTimeline,
  say,
  still,
  standeeFacingDirection,
  standeeShake,
  standeeVerticalOffset,
  type VQCustomTimelineEvent,
  type VQStandeeFacingDirectionEvent,
  type VQStandeeShakeEvent,
  type VQStandeeVerticalOffsetEvent,
  type VQSpeechEvent,
  type VQTimelineEvent,
  type VQTimelineInputEvent,
} from "../../lib/VQRemotionLib/timeline";
import type {CharacterId, VoicevoxVoice} from "./characters";

export {characters, initialVisibleCharacters} from "./characters";
export type {CharacterDefinition, CharacterId, VoicevoxVoice} from "./characters";

export const compositionTitle = "ずんだもんの持論";

export type ShowOptions = Readonly<{
  caption?: string;
  durationSeconds?: number;
}>;

export type SpeechEvent = VQSpeechEvent<CharacterId, VoicevoxVoice>;

export type ShowEvent = VQCustomTimelineEvent<
  "show",
  {
    character: CharacterId;
    caption?: string;
    durationSeconds?: number;
  }
>;

export type HideTitleEvent = VQCustomTimelineEvent<
  "hideTitle",
  {
    id: string;
  }
>;

export type TimelineEvent = VQTimelineEvent<
  CharacterId,
  VoicevoxVoice,
  | ShowEvent
  | HideTitleEvent
  | VQStandeeFacingDirectionEvent<CharacterId>
  | VQStandeeShakeEvent<CharacterId>
  | VQStandeeVerticalOffsetEvent<CharacterId>
>;
export type TimelineInputEvent = VQTimelineInputEvent<
  CharacterId,
  VoicevoxVoice,
  | ShowEvent
  | HideTitleEvent
  | VQStandeeFacingDirectionEvent<CharacterId>
  | VQStandeeShakeEvent<CharacterId>
  | VQStandeeVerticalOffsetEvent<CharacterId>
>;

// 用途: キャラクターを画面に登場させ、任意の説明字幕を表示する。
// 使用方法: timeline 内で show("sayo", {caption: "小夜が登場!"}) のように呼び出す。
// オプションや引数詳細: durationSeconds を省略すると timing.ts の既定秒数で表示する。
export const show = (
  character: CharacterId,
  options: ShowOptions = {}
): ShowEvent => ({
  type: "show",
  character,
  ...options,
});

export const hideTitle = (id: string): HideTitleEvent => ({
  type: "hideTitle",
  id,
});

export const timeline = defineVQTimeline([
  still("zundamon-jiron-background-001", "image/still/nc238325_living_day.jpg", {
    fit: "cover",
  }),
  audio("zundamon-jiron-bgm-001", "audio/common_bgm/saturn-3-music-rockabye-baby-music-box-lullaby-loopable-527146.mp3", {
    playback: "loop",
    volume: 0.2,
  }),
  say("zundamon-jiron-zunda-001", "zundamon", "ふー、着替えて落ち着いたのだ。"),
  say("zundamon-jiron-zunda-002", "zundamon", "やっぱり寮ではこのスタイルが一番なのだ。"),
  hideTitle("zundamon-jiron-hide-title-001"),
  standeeVerticalOffset("zundamon-jiron-zunda-y-001", "zundamon", -20),
  audio("zundamon-jiron-sound-effect-002", "audio/common_soundeffect/Door 6_5 Open.wav",
    {
      playback: "once",
      durationSeconds: 1.5,
    }
  ),
  show("sayo", { }),
  say("zundamon-jiron-sayo-001", "sayo", "あ、ずんだもんだ。"),
  standeeFacingDirection("zundamon-jiron-zunda-facing-001", "zundamon", "right"),
  say("zundamon-jiron-sayo-002", "sayo", "あったかくなってきたにしても、おむつ一枚はちょっとラフな格好すぎない?"),
  say("zundamon-jiron-zunda-003", "zundamon", "そんなことないのだ!これが夏のベストスタイルなのだ!"),
  say("zundamon-jiron-zunda-004", "zundamon", "小夜もこのスタイルにしてみればいいのだ。たぶん似合うし、快適なのだ!"),
  say("zundamon-jiron-sayo-003", "sayo", "えー、私はいいや。なんか清潔じゃない感じがするし…。"),
  say("zundamon-jiron-zunda-005", "zundamon", "それは偏見なのだ!"),
  say("zundamon-jiron-zunda-006", "zundamon", "考えてみるのだ。紙おむつは常に新品をあてることになるから、むしろ清潔なのだ!"),
  say("zundamon-jiron-zunda-007", "zundamon", "毎日おろしたての下着を身につけるようなものなのだ。洗濯して使い続ける下着よりも清潔なのは明らかなのだ。"),
  say("zundamon-jiron-sayo-004", "sayo", "うーん、そう言われると確かにそうかも…。"),
  say("zundamon-jiron-zunda-008", "zundamon", "なのだ?だからみんなもこのスタイルを試してみるといいのだ!"),
  say("zundamon-jiron-sayo-005", "sayo", "確かに言ってることはまちがってないんだけど、\n清潔なのは「穿いた直後」の話だよね?"),
  say("zundamon-jiron-zunda-009", "zundamon", "うっ…!"),
  audio("zundamon-jiron-sound-effect-001", "audio/common_soundeffect/nc174220_osikko7.mp3",
    {
      playback: "once",
      durationSeconds: 10.0,
    }
  ),
  standeeShake("zundamon-jiron-zunda-shake-001", "zundamon", {
    durationSeconds: 2.0,
    amplitudeX: 9,
    amplitudeY: 6,
    frequencyHz: 16,
  }),
  wait(2.0),
  say("zundamon-jiron-zunda-010", "zundamon", "……丁度いま、清潔じゃなくなったのだ。"),
  say("zundamon-jiron-sayo-006", "sayo", "そうだね…。"),
  say("zundamon-jiron-sayo-007", "sayo", "(……でも、漏らさないで使う限りはずんだもんが言うとおりなのかな?)"),
  say("zundamon-jiron-zunda-011", "zundamon", "こまめに替えれば大丈夫なのだ!\nなので、小夜もおむつスタイルを試してみるといいのだ!"),
  say("zundamon-jiron-sayo-008", "sayo", "考えておくね。\nずんだもんは早くおむつ替えてね。"),
  say("zundamon-jiron-zunda-012", "zundamon", "そうするのだ!"),
  wait(4.0),
] satisfies readonly TimelineInputEvent[]);