Spaces:
Running
Running
File size: 2,824 Bytes
7d41d24 557b9b9 36c293d 557b9b9 adef775 8a46dd4 36c293d 557b9b9 36c293d 8a46dd4 557b9b9 8a46dd4 557b9b9 8a46dd4 557b9b9 8a46dd4 557b9b9 8a46dd4 557b9b9 8a46dd4 557b9b9 8a46dd4 557b9b9 8a46dd4 557b9b9 8a46dd4 36c293d 557b9b9 8a46dd4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
const chat = document.getElementById("chat");
const bg = document.getElementById("bg");
const messages = [
{ name: "Suren", side: "left", avatar: "https://i.pravatar.cc/30?img=5", voice: "Rachel", text: "Are you ready to launch?" },
{ name: "Elon", side: "right", avatar: "https://i.pravatar.cc/30?img=9", voice: "Adam", text: "Always ready. 3...2...1..." },
{ name: "Suren", side: "left", avatar: "https://i.pravatar.cc/30?img=5", voice: "Rachel", text: "We’re live on TikTok now!" }
];
const voiceMap = {
Rachel: "21m00Tcm4TlvDq8ikWAM",
Adam: "pNInz6obpgDQGcFmaJgB",
Bella: "EXAVITQu4vr4xnSDxMaL"
};
const apiKey = "sk_4e67c39c0e9cbc87462cd2643e1f4d1d9959d7d81203adc2";
function loadBackground(e) {
const file = e.target.files[0];
const url = URL.createObjectURL(file);
bg.src = url;
bg.play();
}
async function getVoiceBlob(text, voice) {
const voiceId = voiceMap[voice] || voiceMap.Rachel;
const res = await fetch("https://api.elevenlabs.io/v1/text-to-speech/" + voiceId, {
method: "POST",
headers: {
"Content-Type": "application/json",
"xi-api-key": apiKey
},
body: JSON.stringify({ text, model_id: "eleven_monolingual_v1", voice_settings: { stability: 0.4, similarity_boost: 0.75 } })
});
return await res.blob();
}
async function start() {
chat.innerHTML = "";
bg.currentTime = 0;
const stream = document.querySelector(".phone-frame").captureStream(30);
const recorder = new MediaRecorder(stream);
const chunks = [];
recorder.ondataavailable = e => chunks.push(e.data);
recorder.onstop = () => {
const blob = new Blob(chunks, { type: "video/webm" });
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = "chat_tiktok_ready.mp4";
a.click();
};
recorder.start();
bg.play();
for (const msg of messages) {
const typing = document.createElement("div");
typing.className = "typing";
typing.innerHTML = "<span></span><span></span><span></span>";
chat.appendChild(typing);
chat.scrollTop = chat.scrollHeight;
await new Promise(r => setTimeout(r, 1200));
chat.removeChild(typing);
const wrap = document.createElement("div");
wrap.className = "message " + msg.side;
const avatar = document.createElement("img");
avatar.src = msg.avatar;
avatar.className = "avatar";
const bubble = document.createElement("div");
bubble.className = "bubble";
bubble.textContent = msg.text;
wrap.appendChild(avatar);
wrap.appendChild(bubble);
chat.appendChild(wrap);
chat.scrollTop = chat.scrollHeight;
const blob = await getVoiceBlob(msg.text, msg.voice);
const audio = new Audio(URL.createObjectURL(blob));
await new Promise(r => {
audio.onended = r;
audio.play();
});
}
recorder.stop();
}
|