xd / templates /index.html
jnjj's picture
Upload 80 files
0711651 verified
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Personalized Avatar Video</title>
</head>
<body>
<h2>Personalized Avatar Video</h2>
<div>
<label>Upload or record audio: <input type="file" id="audioInput" accept="audio/*"></label>
<button id="btnTranscribe">Transcribe</button><br>
<label>Or enter text: <input type="text" id="textInput"></label>
<button id="btnUseText">Use Text</button><br>
<label>Transcription / Edited Text:</label><br>
<textarea id="transcribed" rows="2" cols="50"></textarea><br>
<label>Assistant Response:</label><br>
<textarea id="assistant" rows="2" cols="50"></textarea><br>
<button id="btnChat">Get Response</button>
</div>
<hr>
<div>
<label>Select Avatar:</label>
<select id="avatarSelect">
{% for name in avatars %}
<option value="{{ name }}">{{ name }}</option>
{% endfor %}
</select>
<img id="avatarImg" src="" width="150" height="150">
</div>
<hr>
<div>
<button id="btnTTS">Synthesize Speech</button><br>
<audio id="audioOut" controls autoplay></audio><br>
<button id="btnSync">Generate Lip-Synced Video</button><br>
<video id="videoOut" width="400" controls autoplay muted></video>
</div>
<script>
async function requestMic() {
try {
await navigator.mediaDevices.getUserMedia({ audio: true });
} catch(e) {
console.warn('Microphone access denied');
}
}
window.addEventListener('load', requestMic);
document.getElementById('avatarSelect').addEventListener('change',function(){
var n=this.value;
document.getElementById('avatarImg').src='/thumbnails/'+n+'.png';
});
document.getElementById('btnTranscribe').onclick = async function(){
var inp = document.getElementById('audioInput');
if(!inp.files.length) return;
var fd = new FormData();
fd.append('audio', inp.files[0]);
var res = await fetch('/transcribe',{method:'POST',body:fd});
var j = await res.json();
document.getElementById('transcribed').value = j.text;
};
document.getElementById('btnUseText').onclick = function(){
document.getElementById('transcribed').value = document.getElementById('textInput').value;
};
document.getElementById('btnChat').onclick = async function(){
var text = document.getElementById('transcribed').value;
var res = await fetch('/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({text})});
var j = await res.json();
document.getElementById('assistant').value = j.response;
};
document.getElementById('btnTTS').onclick = async function(){
var text = document.getElementById('assistant').value;
var res = await fetch('/tts',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({text})});
var j = await res.json();
if(j.audio_url) {
var a = document.getElementById('audioOut');
a.src = j.audio_url;
await a.play();
}
};
document.getElementById('btnSync').onclick = async function(){
var avatar = document.getElementById('avatarSelect').value;
var audio_url = document.getElementById('audioOut').src;
var res = await fetch('/sync',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({avatar,audio_url})});
var j = await res.json();
if(j.video_url) {
var v = document.getElementById('videoOut');
v.src = j.video_url;
v.muted = false;
await v.play();
}
};
</script>
</body>
</html>