Compare commits

...

10 Commits

Author SHA1 Message Date
raojianb
654787b17b fix: incorrect home page url in header banner 2024-11-19 10:23:33 -08:00
Joby
6fca8b4d42 feat: upgrade the sdk to v2.0.8 (#39) 2024-11-17 22:38:11 -08:00
Joby
431281d47c feat: task mode (#30) 2024-10-22 16:58:38 -07:00
Joby
274a307e83 chore: update sdk version (#26) 2024-09-30 18:24:59 -07:00
Joby
03ef24b031 chore: update sdk version (#24) 2024-09-27 15:39:13 -07:00
Joby
21f6c6d468 feat: support knwoledge base (#23)
* feat: support knwoledge base

* feat: support knwoledge base
2024-09-25 19:53:26 -07:00
Joby
d7a7e3174c feat: update dependencies (#20) 2024-09-23 16:14:07 -07:00
Joby
e653fa74c4 feat: add language and voice rate (#19) 2024-09-23 15:55:33 -07:00
Joby
5dd784d63e feat: add task type (#18) 2024-09-23 13:38:15 -07:00
Joby
efb98f612b feat: simplify api (#14) 2024-09-22 01:54:14 -07:00
4 changed files with 70 additions and 22 deletions

View File

@@ -20,3 +20,34 @@ export const AVATARS = [
name: "Joshua Heygen CEO", name: "Joshua Heygen CEO",
}, },
]; ];
export const STT_LANGUAGE_LIST = [
{ label: 'Bulgarian', value: 'bg', key: 'bg' },
{ label: 'Chinese', value: 'zh', key: 'zh' },
{ label: 'Czech', value: 'cs', key: 'cs' },
{ label: 'Danish', value: 'da', key: 'da' },
{ label: 'Dutch', value: 'nl', key: 'nl' },
{ label: 'English', value: 'en', key: 'en' },
{ label: 'Finnish', value: 'fi', key: 'fi' },
{ label: 'French', value: 'fr', key: 'fr' },
{ label: 'German', value: 'de', key: 'de' },
{ label: 'Greek', value: 'el', key: 'el' },
{ label: 'Hindi', value: 'hi', key: 'hi' },
{ label: 'Hungarian', value: 'hu', key: 'hu' },
{ label: 'Indonesian', value: 'id', key: 'id' },
{ label: 'Italian', value: 'it', key: 'it' },
{ label: 'Japanese', value: 'ja', key: 'ja' },
{ label: 'Korean', value: 'ko', key: 'ko' },
{ label: 'Malay', value: 'ms', key: 'ms' },
{ label: 'Norwegian', value: 'no', key: 'no' },
{ label: 'Polish', value: 'pl', key: 'pl' },
{ label: 'Portuguese', value: 'pt', key: 'pt' },
{ label: 'Romanian', value: 'ro', key: 'ro' },
{ label: 'Russian', value: 'ru', key: 'ru' },
{ label: 'Slovak', value: 'sk', key: 'sk' },
{ label: 'Spanish', value: 'es', key: 'es' },
{ label: 'Swedish', value: 'sv', key: 'sv' },
{ label: 'Turkish', value: 'tr', key: 'tr' },
{ label: 'Ukrainian', value: 'uk', key: 'uk' },
{ label: 'Vietnamese', value: 'vi', key: 'vi' },
];

View File

@@ -2,7 +2,7 @@ import type { StartAvatarResponse } from "@heygen/streaming-avatar";
import StreamingAvatar, { import StreamingAvatar, {
AvatarQuality, AvatarQuality,
StreamingEvents, StreamingEvents, TaskMode, TaskType, VoiceEmotion,
} from "@heygen/streaming-avatar"; } from "@heygen/streaming-avatar";
import { import {
Button, Button,
@@ -23,7 +23,7 @@ import { useMemoizedFn, usePrevious } from "ahooks";
import InteractiveAvatarTextInput from "./InteractiveAvatarTextInput"; import InteractiveAvatarTextInput from "./InteractiveAvatarTextInput";
import { AVATARS } from "@/app/lib/constants"; import {AVATARS, STT_LANGUAGE_LIST} from "@/app/lib/constants";
export default function InteractiveAvatar() { export default function InteractiveAvatar() {
const [isLoadingSession, setIsLoadingSession] = useState(false); const [isLoadingSession, setIsLoadingSession] = useState(false);
@@ -32,6 +32,8 @@ export default function InteractiveAvatar() {
const [debug, setDebug] = useState<string>(); const [debug, setDebug] = useState<string>();
const [knowledgeId, setKnowledgeId] = useState<string>(""); const [knowledgeId, setKnowledgeId] = useState<string>("");
const [avatarId, setAvatarId] = useState<string>(""); const [avatarId, setAvatarId] = useState<string>("");
const [language, setLanguage] = useState<string>('en');
const [data, setData] = useState<StartAvatarResponse>(); const [data, setData] = useState<StartAvatarResponse>();
const [text, setText] = useState<string>(""); const [text, setText] = useState<string>("");
const mediaStream = useRef<HTMLVideoElement>(null); const mediaStream = useRef<HTMLVideoElement>(null);
@@ -89,12 +91,20 @@ export default function InteractiveAvatar() {
const res = await avatar.current.createStartAvatar({ const res = await avatar.current.createStartAvatar({
quality: AvatarQuality.Low, quality: AvatarQuality.Low,
avatarName: avatarId, avatarName: avatarId,
knowledgeId: knowledgeId, knowledgeId: knowledgeId, // Or use a custom `knowledgeBase`.
voice: {
rate: 1.5, // 0.5 ~ 1.5
emotion: VoiceEmotion.EXCITED,
},
language: language,
disableIdleTimeout: true,
}); });
setData(res); setData(res);
// default to voice mode // default to voice mode
await avatar.current?.startVoiceChat(); await avatar.current?.startVoiceChat({
useSilencePrompt: false
});
setChatMode("voice_mode"); setChatMode("voice_mode");
} catch (error) { } catch (error) {
console.error("Error starting avatar session:", error); console.error("Error starting avatar session:", error);
@@ -109,9 +119,8 @@ export default function InteractiveAvatar() {
return; return;
} }
await avatar.current // speak({ text: text, task_type: TaskType.REPEAT })
.speak({ text: text, sessionId: data?.session_id! }) await avatar.current.speak({ text: text, taskType: TaskType.REPEAT, taskMode: TaskMode.SYNC }).catch((e) => {
.catch((e) => {
setDebug(e.message); setDebug(e.message);
}); });
setIsLoadingRepeat(false); setIsLoadingRepeat(false);
@@ -123,20 +132,13 @@ export default function InteractiveAvatar() {
return; return;
} }
await avatar.current await avatar.current
.interrupt({ sessionId: data?.session_id! }) .interrupt()
.catch((e) => { .catch((e) => {
setDebug(e.message); setDebug(e.message);
}); });
} }
async function endSession() { async function endSession() {
if (!avatar.current) { await avatar.current?.stopAvatar();
setDebug("Avatar API not initialized");
return;
}
await avatar.current.stopAvatar({
sessionId: data?.session_id!,
});
setStream(undefined); setStream(undefined);
} }
@@ -155,9 +157,9 @@ export default function InteractiveAvatar() {
const previousText = usePrevious(text); const previousText = usePrevious(text);
useEffect(() => { useEffect(() => {
if (!previousText && text) { if (!previousText && text) {
avatar.current?.startListening({ sessionId: data?.session_id! }); avatar.current?.startListening();
} else if (previousText && !text) { } else if (previousText && !text) {
avatar?.current?.stopListening({ sessionId: data?.session_id! }); avatar?.current?.stopListening();
} }
}, [text, previousText]); }, [text, previousText]);
@@ -249,6 +251,21 @@ export default function InteractiveAvatar() {
</SelectItem> </SelectItem>
))} ))}
</Select> </Select>
<Select
label="Select language"
placeholder="Select language"
className="max-w-xs"
selectedKeys={[language]}
onChange={(e) => {
setLanguage(e.target.value);
}}
>
{STT_LANGUAGE_LIST.map((lang) => (
<SelectItem key={lang.key}>
{lang.label}
</SelectItem>
))}
</Select>
</div> </div>
<Button <Button
className="bg-gradient-to-tr from-indigo-500 to-indigo-300 w-full text-white" className="bg-gradient-to-tr from-indigo-500 to-indigo-300 w-full text-white"

View File

@@ -28,7 +28,7 @@ export default function NavBar() {
<Link <Link
isExternal isExternal
color="foreground" color="foreground"
href="https://app.heygen.com/interactive-avatar" href="https://labs.heygen.com/interactive-avatar"
> >
Avatars Avatars
</Link> </Link>

View File

@@ -10,7 +10,7 @@
}, },
"dependencies": { "dependencies": {
"@ai-sdk/openai": "^0.0.34", "@ai-sdk/openai": "^0.0.34",
"@heygen/streaming-avatar": "^2.0.0-beta.1", "@heygen/streaming-avatar": "^2.0.8",
"@nextui-org/button": "2.0.34", "@nextui-org/button": "2.0.34",
"@nextui-org/chip": "^2.0.32", "@nextui-org/chip": "^2.0.32",
"@nextui-org/code": "2.0.29", "@nextui-org/code": "2.0.29",