diff --git a/voicevox-remotion-template/src/data/pizza-kiln/script.ts b/voicevox-remotion-template/src/data/pizza-kiln/script.ts index 5670dc7..caf2aa4 100644 --- a/voicevox-remotion-template/src/data/pizza-kiln/script.ts +++ b/voicevox-remotion-template/src/data/pizza-kiln/script.ts @@ -1,4 +1,4 @@ -import type {SpeakingAvatarAnimationType} from "../../avatar-animations"; +import {getStandeeSet, type AvatarDefinition} from "../../standee-sets"; export type VoicevoxVoice = Readonly<{ speakerName: string; @@ -8,13 +8,7 @@ export type CharacterDefinition = Readonly<{ displayName: string; voicevox: VoicevoxVoice; - avatar: Readonly<{ - kind: "sayo"; - accentColor: string; - imagePath: string; - mouthImageDir?: string; - speakingAnimationType?: SpeakingAvatarAnimationType; - }>; + avatar: AvatarDefinition; }>; export const characters = { @@ -25,9 +19,8 @@ styleName: "ノーマル", }, avatar: { - kind: "sayo", + ...getStandeeSet("sayo_ohnegus_ai"), accentColor: "#6b5f83", - imagePath: "image/sayo-standee-base.png", speakingAnimationType: "rhubarbLipSync", }, }, diff --git a/voicevox-remotion-template/src/data/script.ts b/voicevox-remotion-template/src/data/script.ts index a745d5f..041438b 100644 --- a/voicevox-remotion-template/src/data/script.ts +++ b/voicevox-remotion-template/src/data/script.ts @@ -1,29 +1,10 @@ -import type { - IdleAvatarAnimationType, - SpeakingAvatarAnimationType, -} from "../avatar-animations"; +import {getStandeeSet, type AvatarDefinition} from "../standee-sets"; export type VoicevoxVoice = Readonly<{ speakerName: string; styleName: string; }>; -export type AvatarDefinition = Readonly<{ - kind: "zundamon" | "sayo"; - accentColor: string; - imagePath?: string; - mouthImageDir?: string; - imageLayout?: Readonly<{ - width?: number; - maxHeight?: number; - translateY?: number; - flipX?: boolean; - }>; - nameplatePosition?: "top" | "bottom" | "none"; - idleAnimationType?: IdleAvatarAnimationType; - speakingAnimationType?: SpeakingAvatarAnimationType; -}>; - export type CharacterDefinition = Readonly<{ displayName: string; voicevox: VoicevoxVoice; @@ -38,15 +19,8 @@ styleName: "ノーマル", }, avatar: { - kind: "zundamon", + ...getStandeeSet("zundamon_ohnegus_ai"), accentColor: "#79d36f", - imagePath: "image/zundamon-standee-base.png", - imageLayout: { - width: 560, - maxHeight: 760, - translateY: -87, - flipX: true, - }, nameplatePosition: "none", idleAnimationType: "none", speakingAnimationType: "rhubarbLipSync", @@ -59,14 +33,8 @@ styleName: "ノーマル", }, avatar: { - kind: "sayo", + ...getStandeeSet("sayo_ohnegus_ai"), accentColor: "#6b5f83", - imagePath: "image/sayo-standee-base.png", - imageLayout: { - width: 560, - maxHeight: 760, - translateY: -60, - }, nameplatePosition: "none", idleAnimationType: "none", speakingAnimationType: "rhubarbLipSync", diff --git a/voicevox-remotion-template/src/pizza-kiln-composition.tsx b/voicevox-remotion-template/src/pizza-kiln-composition.tsx index 21ce731..4389e1c 100644 --- a/voicevox-remotion-template/src/pizza-kiln-composition.tsx +++ b/voicevox-remotion-template/src/pizza-kiln-composition.tsx @@ -31,6 +31,10 @@ } from "./lipsync/LipSyncedStandeeImage"; const BACKGROUND_VIDEO_PATH = "video/pizza-kiln-background.mp4"; +const STAGE_STANDEE_WIDTH = 610; +const STAGE_STANDEE_HEIGHT = 760; +const STAGE_STANDEE_RIGHT = 315; +const STAGE_STANDEE_BOTTOM = -118; const CORNER_STANDEE_WIDTH = 420; const CORNER_STANDEE_HEIGHT = 360; const CORNER_IMAGE_WIDTH = 470; @@ -130,15 +134,15 @@ ? getMouthForSpeechFrame(speechId, localFrame, fps) : "rest"; const isCorner = mode === "corner"; - const frameWidth = isCorner ? CORNER_STANDEE_WIDTH : 560; - const frameHeight = isCorner ? CORNER_STANDEE_HEIGHT : 700; + const frameWidth = isCorner ? CORNER_STANDEE_WIDTH : STAGE_STANDEE_WIDTH; + const frameHeight = isCorner ? CORNER_STANDEE_HEIGHT : STAGE_STANDEE_HEIGHT; return (
; + +export type StandeeSet = Readonly<{ + kind: AvatarKind; + imagePath: string; + mouthImageDir: string; + imageLayout: StandeeImageLayout; +}>; + +export type AvatarDefinition = Readonly< + StandeeSet & { + accentColor: string; + nameplatePosition?: "top" | "bottom" | "none"; + idleAnimationType?: IdleAvatarAnimationType; + speakingAnimationType?: SpeakingAvatarAnimationType; + } +>; + +export const standeeSets = { + "zundamon_default": { + kind: "zundamon", + imagePath: "image/zundamon-standee-base.png", + mouthImageDir: "image/zundamon-rhubarb-mouths", + imageLayout: { + width: 560, + maxHeight: 760, + translateY: -87, + flipX: true, + }, + }, + "sayo_default": { + kind: "sayo", + imagePath: "image/sayo-standee-base.png", + mouthImageDir: "image/sayo-rhubarb-mouths", + imageLayout: { + width: 560, + maxHeight: 760, + translateY: -60, + }, + }, + "zundamon_ohnegus_ai": { + kind: "zundamon", + imagePath: "image/zundamon_ohnegus_ai_base.png", + mouthImageDir: "image/zundamon-ohnegus-ai-rhubarb-mouths", + imageLayout: { + width: 540, + maxHeight: 730, + translateY: 0, + flipX: true, + }, + }, + "sayo_ohnegus_ai": { + kind: "sayo", + imagePath: "image/sayo_ohnegus_ai_base.png", + mouthImageDir: "image/sayo-ohnegus-ai-rhubarb-mouths", + imageLayout: { + width: 520, + maxHeight: 720, + translateY: 0, + }, + }, +} as const satisfies Record; + +export type StandeeSetId = keyof typeof standeeSets; + +export const getStandeeSet = (id: StandeeSetId): StandeeSet => standeeSets[id]; diff --git a/voicevox-remotion-template/src/yukkuri-composition.tsx b/voicevox-remotion-template/src/yukkuri-composition.tsx index 8a1b467..a2cf21e 100644 --- a/voicevox-remotion-template/src/yukkuri-composition.tsx +++ b/voicevox-remotion-template/src/yukkuri-composition.tsx @@ -13,10 +13,10 @@ characters, initialVisibleCharacters, timeline, - type AvatarDefinition, type CharacterId, type TimelineEvent, } from "./data/script"; +import type {AvatarDefinition} from "./standee-sets"; import { idleAvatarAnimations, speakingAvatarAnimations, @@ -424,7 +424,7 @@ }) => { const character = characters[characterId]; const {avatar}: {avatar: AvatarDefinition} = character; - const scale = hasMultipleCharacters ? 0.88 : focused ? 1.05 : 1; + const scale = hasMultipleCharacters ? 0.82 : focused ? 0.94 : 0.9; const opacity = focused || !hasMultipleCharacters ? 1 : 0.72; const idleAnimationType = avatar.idleAnimationType ?? "gentleBob"; const speakingAnimationType = avatar.speakingAnimationType ?? "gentleBob"; @@ -544,7 +544,7 @@ justifyContent: "center", gap: hasMultipleCharacters ? 130 : 0, width: "100%", - paddingBottom: 40, + paddingBottom: 0, }} > {visibleCharacters.map((characterId) => (