-
Notifications
You must be signed in to change notification settings - Fork 94
/
minimal.html
93 lines (81 loc) · 3.34 KB
/
minimal.html
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
89
90
91
92
93
<!DOCTYPE html>
<html>
<head>
<title>Talking Head - minimal example</title>
<style>
body, html { width:100%; height:100%; max-width: 800px; margin: auto; position: relative; background-color: dimgray; color: white; }
#avatar { display: block; width:100%; height:100%; }
#controls { display: block; position: absolute; top: 10px; left: 10px; right: 10px; height: 50px; }
#text { position: absolute; width: Calc( 100% - 110px ); height: 100%; top: 0; left: 0; bottom: 0; right: 110px; font-family: Arial; font-size: 20px; }
#speak { block; position: absolute; top: 0; bottom: 0; right: 0; height: 100%; width: 100px; font-family: Arial; font-size: 20px; }
#loading { display: block; position: absolute; bottom: 10px; left: 10px; right: 10px; height: 50px; font-family: Arial; font-size: 20px; }
</style>
<script type="importmap">
{ "imports":
{
"three": "https://cdn.jsdelivr.net/npm/three@0.161.0/build/three.module.js/+esm",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.161.0/examples/jsm/",
"talkinghead": "https://cdn.jsdelivr.net/gh/met4citizen/TalkingHead@1.2/modules/talkinghead.mjs"
}
}
</script>
<script type="module">
import { TalkingHead } from "talkinghead";
let head;
document.addEventListener('DOMContentLoaded', async function(e) {
// Instantiate the class
// NOTE: Never put your API key in a client-side code unless you know
// that you are the only one to have access to that code!
const nodeAvatar = document.getElementById('avatar');
head = new TalkingHead( nodeAvatar, {
ttsEndpoint: "https://eu-texttospeech.googleapis.com/v1beta1/text:synthesize",
ttsApikey: "put-your-own-Google-TTS-API-key-here", // <- Change this
lipsyncModules: ["en", "fi"],
cameraView: "upper"
});
// Load and show the avatar
const nodeLoading = document.getElementById('loading');
try {
nodeLoading.textContent = "Loading...";
await head.showAvatar( {
url: 'https://models.readyplayer.me/64bfa15f0e72c63d7c3934a6.glb?morphTargets=ARKit,Oculus+Visemes,mouthOpen,mouthSmile,eyesClosed,eyesLookUp,eyesLookDown&textureSizeLimit=1024&textureFormat=png',
body: 'F',
avatarMood: 'neutral',
ttsLang: "en-GB",
ttsVoice: "en-GB-Standard-A",
lipsyncLang: 'en'
}, (ev) => {
if ( ev.lengthComputable ) {
let val = Math.min(100,Math.round(ev.loaded/ev.total * 100 ));
nodeLoading.textContent = "Loading " + val + "%";
}
});
nodeLoading.style.display = 'none';
} catch (error) {
console.log(error);
nodeLoading.textContent = error.toString();
}
// Speak when clicked
const nodeSpeak = document.getElementById('speak');
nodeSpeak.addEventListener('click', function () {
try {
const text = document.getElementById('text').value;
if ( text ) {
head.speakText( text );
}
} catch (error) {
console.log(error);
}
});
});
</script>
</head>
<body>
<div id="avatar"></div>
<div id="controls">
<input id="text" type="text" value="Hi there. How are you? I'm fine.">
<input id="speak" type="button" value="Speak">
</div>
<div id="loading"></div>
</body>
</html>