Skip to content

Commit

Permalink
[TTV] improvements (#86)
Browse files Browse the repository at this point in the history
* [TTV] retry character creation once

* [TTV] increase polling time of character

* [TTV] update share text

* feat: add vercel speed insights

---------

Co-authored-by: louisjoecodes <[email protected]>
  • Loading branch information
jonatanvm and louisjoecodes authored Oct 31, 2024
1 parent ef573d6 commit a04d736
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 70 deletions.
35 changes: 24 additions & 11 deletions examples/text-to-voice/x-to-voice/app/(default)/actions/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ const synthesizeRetrieveHumanSchema = z.object({
});

const uploadAudio = async (buffer: Buffer) => {
const fileBlob = new Blob([buffer], { type: 'audio/mpeg' });
const fileBlob = new Blob([buffer], { type: "audio/mpeg" });
const formData = new FormData();
formData.append('file', fileBlob, 'audio.mp3');
formData.append("file", fileBlob, "audio.mp3");
const audioResponse = await fetch(
"https://mercury.dev.dream-ai.com/api/v1/audio",
{
Expand All @@ -41,10 +41,9 @@ const uploadAudio = async (buffer: Buffer) => {

const uploadImage = async (imageUrl: string) => {
const imageResponse = await fetch(imageUrl);
console.log();
const imageBlob = await imageResponse.blob();
const formData = new FormData();
formData.append('file', imageBlob, 'image.jpg');
formData.append("file", imageBlob, "image.jpg");
const audioResponse = await fetch(
"https://mercury.dev.dream-ai.com/api/v1/portrait",
{
Expand Down Expand Up @@ -89,16 +88,19 @@ export async function getJobStatus(jobId: string) {
return status;
}

const createCharacter = async ({ voiceBuffer, profilePicture }: { voiceBuffer: Buffer, profilePicture: string }) => {
const createCharacter = async ({ voiceBuffer, profilePicture }: {
voiceBuffer: Buffer,
profilePicture: string
}): Promise<string | undefined> => {
const [audioData, imageData] = await Promise.all([
await uploadAudio(voiceBuffer),
await uploadImage(profilePicture)
await uploadImage(profilePicture),
]);
const voiceUrl = audioData["url"];
const avatarImage = imageData["url"];
const requestBody = { "audioSource": "audio", voiceUrl, avatarImage, };
const requestBody = { "audioSource": "audio", voiceUrl, avatarImage };
const statusData = await createVideo(requestBody);
return statusData['jobId'];
return statusData["jobId"];
};

async function getAnalysis(user: XProfile) {
Expand Down Expand Up @@ -273,10 +275,21 @@ export const synthesizeHumanAction = actionClient
),
]);

const jobId = await createCharacter({
let jobId = await createCharacter({
voiceBuffer: audioBuffer1,
profilePicture: user.profilePicture
})
profilePicture: user.profilePicture,
});

if (!jobId) {
jobId = await createCharacter({
voiceBuffer: audioBuffer1,
profilePicture: user.profilePicture,
});
}

if (!jobId) {
throw Error("Couldn't create character.")
}

const humanSpecimen = humanSpecimenSchema.parse({
user,
Expand Down
97 changes: 55 additions & 42 deletions examples/text-to-voice/x-to-voice/app/(default)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Analytics } from "@vercel/analytics/react";
import { BackgroundWave } from "@/components/background-wave";
import Link from "next/link";
import { Button } from "@/components/ui/button";
import { SpeedInsights } from "@vercel/speed-insights/next";

export const maxDuration = 60; // Applies to the actions

Expand All @@ -23,54 +24,66 @@ const geistMono = localFont({

export const metadata: Metadata = {
title: "X to Voice | ElevenLabs",
description: "Analyze your X profile to generate a unique voice using ElevenLabs' new Voice Design feature",
description:
"Analyze your X profile to generate a unique voice using ElevenLabs' new Voice Design feature",
};

export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
export default function RootLayout({
children,
}: Readonly<{ children: React.ReactNode }>) {
return (
<html lang="en" className={"h-full w-full"}>
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased w-full h-full flex flex-col sm:pt-20`}
>
<nav className={"sm:fixed w-full top-0 left-0 flex items-center justify-between py-4 px-8"}>
<div className={"flex"}>
<Link href={"/"} prefetch={true}><ElevenLabsLogo
className={"h-[15px] w-auto hover:text-gray-500"} /></Link>
</div>
<div className={"flex gap-4"}>
<Link
href="https://elevenlabs.io/app/sign-in"
target="_blank"
aria-label="View source on GitHub"
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased w-full h-full flex flex-col sm:pt-20`}
>
<nav
className={
"sm:fixed w-full top-0 left-0 flex items-center justify-between py-4 px-8"
}
>
<Button
variant={"secondary"}
size={"xs"}
className="rounded-full z-50 text-sm text-gray-800"
>
Sign up
</Button>
</Link>
<Link
href="https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/text-to-voice/x-to-voice"
target="_blank"
rel="noopener noreferrer"
className={"py-0.5"}
aria-label="View source on GitHub"
>
<GithubLogo className={"w-5 h-5 hover:text-gray-500 text-[#24292f]"}></GithubLogo>
</Link>
</div>
</nav>

<div className="flex flex-col flex-grow w-full items-center justify-center sm:px-4">
{children}
<BackgroundWave />
</div>
<Toaster />
<Analytics />
</body>
<div className={"flex"}>
<Link href={"/"} prefetch={true}>
<ElevenLabsLogo
className={"h-[15px] w-auto hover:text-gray-500"}
/>
</Link>
</div>
<div className={"flex gap-4"}>
<Link
href="https://elevenlabs.io/app/sign-in"
target="_blank"
aria-label="View source on GitHub"
>
<Button
variant={"secondary"}
size={"xs"}
className="rounded-full z-50 text-sm text-gray-800"
>
Sign up
</Button>
</Link>
<Link
href="https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/text-to-voice/x-to-voice"
target="_blank"
rel="noopener noreferrer"
className={"py-0.5"}
aria-label="View source on GitHub"
>
<GithubLogo
className={"w-5 h-5 hover:text-gray-500 text-[#24292f]"}
/>
</Link>
</div>
</nav>

<div className="flex flex-col flex-grow w-full items-center justify-center sm:px-4">
{children}
<BackgroundWave />
</div>
<Toaster />
<Analytics />
<SpeedInsights />
</body>
</html>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export function AvatarPlayer({ jobId }: {
setVideoUrl(data.videoUrl);
setIsLoading(false);
} catch {
intervalId = window.setTimeout(fetchCharacter, 2000);
intervalId = window.setTimeout(fetchCharacter, 4000);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ function XIcon({ className }: { className: string }) {
);
}

export function ShareOnXButton({ shareText }: { shareText: string }) {
export function ShareOnXButton() {
const shareText = "This is what I would sound like based on my X posts using the @elevenlabsio Voice Designer\n\nTry it yourself on xtovoice.com\n\n#xtovoice\n\n"
function share() {
const url = window.location.href;
window.open(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,7 @@ export async function SpecimenCard({ humanSpecimen }: { humanSpecimen: HumanSpec
</Link>
</h1>
<div className="flex gap-2 items-center justify-center">
<ShareOnXButton
shareText={`This is what I would sound like based on my X posts using the @elevenlabsio Voice Designer #xtovoice`}
/>
<ShareOnXButton />
<CopyShareLink />
</div>
</div>
Expand All @@ -79,9 +77,7 @@ export async function SpecimenCard({ humanSpecimen }: { humanSpecimen: HumanSpec
</div>
</div>
<div className="flex gap-2 items-center justify-center sm:hidden">
<ShareOnXButton
shareText={`This is what I would sound like based on my X posts using the @elevenlabsio Voice Designer`}
/>
<ShareOnXButton />
<CopyShareLink />
</div>
<Separator className="my-6" />
Expand Down
1 change: 1 addition & 0 deletions examples/text-to-voice/x-to-voice/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@upstash/redis": "^1.34.3",
"@vercel/analytics": "^1.3.1",
"@vercel/blob": "^0.25.1",
"@vercel/speed-insights": "^1.0.14",
"apify-client": "^2.9.7",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
Expand Down
49 changes: 40 additions & 9 deletions examples/text-to-voice/x-to-voice/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit a04d736

Please sign in to comment.