️말하기
AI 대화를 거치지 않고 아바타가 직접 텍스트를 말하도록 하는 TTS(Text-to-Speech) 기능입니다.
빠른 시작
기본 사용법
import { KleverOneClient } from "@klever-one/web-sdk/core";
const client = new KleverOneClient({
apiKey: "your-api-key",
container: document.getElementById("streaming-container")!,
});
await client.connect();
// 단일 텍스트 발화
client.speak("안녕하세요! 저는 디지털 휴먼입니다.");
// 여러 문장 순차 발화
client.speak([
"첫 번째 문장입니다.",
"두 번째 문장입니다.",
"마지막 문장입니다.",
]);
메서드
speak(input)
TTS를 통해 아바타가 텍스트를 말하게 합니다. 단일 텍스트와 텍스트 배열을 모두 지원합니다.
public speak(input: string): void;
public speak(input: string[]): void;
매개변수
input(string | string[]): 아바타가 말할 텍스트 (단일 문자열 또는 배열)
다양한 사용 예제
단일 텍스트 발화
// 환영 인사
client.speak("안녕하세요! 무엇을 도와드릴까요?");
// 상태 안내
client.speak("처리 중입니다. 잠시만 기다려 주세요.");
// 확인 메시지
client.speak("작업이 완료되었습니다.");
배열을 이용한 연속 발화
const introduction = [
"안녕하세요!",
"저는 고객 서비스 도우미입니다.",
"궁금한 것이 있으면 언제든 말씀해 주세요.",
];
client.speak(introduction);
조건부 발화
function announceStatus(isSuccess, message) {
if (isSuccess) {
client.speak(`성공적으로 처리되었습니다: ${message}`);
} else {
client.speak(`오류가 발생했습니다: ${message}`);
}
}
announceStatus(true, "데이터가 저장되었습니다");
단계별 가이드
function provideStepByStepGuide() {
const steps = [
"첫 번째 단계: 화면의 시작 버튼을 클릭해 주세요.",
"두 번째 단계: 필요한 정보를 입력해 주세요.",
"세 번째 단계: 확인 버튼을 눌러 완료해 주세요.",
];
client.speak(steps);
}
provideStepByStepGuide();
발화 시작 이벤트
아바타가 말을 시작할 때 onLipMotionStart 이벤트를 통해 현재 발화 중인 문장 정보를 받을 수 있습니다.
기본 사용법
const client = new KleverOneClient({
apiKey: "your-api-key",
container: document.getElementById("streaming-container"),
callbacks: {
onLipMotionStart: (data) => {
console.log(`문장 ${data.index + 1}/${data.totalCount}: ${data.text}`);
// 예: "문장 1/3: 안녕하세요!"
},
},
});
client.speak(["안녕하세요!", "반갑습니다.", "도움이 필요하신가요?"]);
// → 각 문장마다 onLipMotionStart 이벤트 발생
이벤트 데이터
| 필드 | 타입 | 설명 |
|---|---|---|
text | string | 현재 발화 중인 문장 텍스트 |
index | number | 현재 문장의 인덱스 (0부터 시작) |
totalCount | number | 전체 문장 개수 |
React에서 사용
import { useKleverOneClient } from "@klever-one/web-sdk/react";
import { type LipMotionData } from "@klever-one/web-sdk/core";
const callbacks = useMemo(
() => ({
onLipMotionStart: (data: LipMotionData) => {
console.log(`발화 진행: ${data.index + 1}/${data.totalCount}`);
console.log(`현재 문장: ${data.text}`);
},
}),
[],
);
const client = useKleverOneClient({
apiKey: "your-api-key",
container: containerRef.current || tempContainer,
callbacks,
});
발화 완료 이벤트
모든 발화가 끝났을 때 onConversationEnd 이벤트를 통해 알림을 받을 수 있습니다.
기본 사용법
const client = new KleverOneClient({
apiKey: "your-api-key",
container: document.getElementById("streaming-container"),
callbacks: {
onConversationEnd: () => {
console.log("모든 발화가 끝났습니다!");
// 다음 작업 수행 (예: UI 업데이트, 다음 메시지 전송 등)
},
},
});
client.speak(["첫 번째 문장", "두 번째 문장", "마지막 문장"]);
// → 모든 문장 발화 완료 후 onConversationEnd 이벤트 발생
React에서 사용
import { useKleverOneClient } from "@klever-one/web-sdk/react";
const callbacks = useMemo(
() => ({
onConversationEnd: () => {
console.log("모든 발화 완료!");
// 상태 업데이트, 다음 동작 트리거 등
},
}),
[],
);
const client = useKleverOneClient({
apiKey: "your-api-key",
container: containerRef.current || tempContainer,
callbacks,
});
실용적인 활용 예시
순차적 메시지 전송
const client = new KleverOneClient({
apiKey: "your-api-key",
container: document.getElementById("streaming-container"),
callbacks: {
onConversationEnd: () => {
// 첫 번째 메시지 완료 후 다음 메시지 전송
setTimeout(() => {
client.speak("추가 안내 사항입니다.");
}, 1000);
},
},
});
client.speak("안내를 시작하겠습니다.");
UI 상태 관리
let isSpeaking = false;
const client = new KleverOneClient({
apiKey: "your-api-key",
container: document.getElementById("streaming-container"),
callbacks: {
onLipMotionStart: () => {
isSpeaking = true;
document.getElementById("status").textContent = "말하는 중...";
},
onConversationEnd: () => {
isSpeaking = false;
document.getElementById("status").textContent = "대기 중";
},
},
});
React Hook 사용법
기본 React Hook 예제
"use client";
import { useState, useRef, useMemo } from "react";
import { useKleverOneClient } from "@klever-one/web-sdk/react";
import { type LipMotionData } from "@klever-one/web-sdk/core";
function SpeechControl() {
const [inputText, setInputText] = useState("");
const containerRef = useRef(null);
const tempContainer = useMemo(() => {
if (typeof document !== "undefined") {
return document.createElement("div");
}
return {} as HTMLDivElement;
}, []);
const callbacks = useMemo(
() => ({
onLipMotionStart: (data: LipMotionData) =>
console.log(
`아바타 발화 시작! [${data.index + 1}/${data.totalCount}]: ${data.text}`,
),
}),
[],
);
const client = useKleverOneClient({
apiKey: "your-api-key",
container: containerRef.current || tempContainer,
callbacks,
});
const handleSpeak = () => {
if (inputText.trim()) {
client.speak(inputText);
setInputText("");
}
};
return (
<div>
<div
ref={containerRef}
className="h-[400px] w-[800px] bg-black"
/>
<input
type="text"
value={inputText}
onChange={(e) => setInputText(e.target.value)}
placeholder="말할 내용을 입력하세요..."
/>
<button onClick={handleSpeak}>️말하기</button>
</div>
);
}
관련 문서
- API 참조 - 대화 텍스트 전송 - AI와 자연스러운 대화
- API 참조 - 연결 - 서버 연결 방법
- React Hook 사용법 - React에서 SDK 사용하기
- TypeScript 사용법 - 타입 안전한 개발