Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>ASR & TTS Tool</title> | |
| <style> | |
| body { | |
| font-family: Arial, sans-serif; | |
| max-width: 1100px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| line-height: 1.6; | |
| background: linear-gradient(180deg, #eef4ff 0%, #f7f7fb 55%, #ffffff 100%); | |
| } | |
| .section { | |
| margin-bottom: 30px; | |
| padding: 20px; | |
| border: 1px solid rgba(30, 41, 59, 0.12); | |
| border-radius: 16px; | |
| background: rgba(255, 255, 255, 0.82); | |
| box-shadow: 0 18px 50px rgba(15, 23, 42, 0.08); | |
| } | |
| .controls { | |
| display: flex; | |
| gap: 20px; | |
| margin-bottom: 15px; | |
| } | |
| .record-controls, | |
| .upload-controls { | |
| display: flex; | |
| gap: 10px; | |
| align-items: center; | |
| } | |
| .file-input { | |
| max-width: 200px; | |
| } | |
| .button { | |
| padding: 10px 20px; | |
| margin: 5px; | |
| border: none; | |
| border-radius: 5px; | |
| background-color: #007bff; | |
| color: white; | |
| cursor: pointer; | |
| transition: background-color 0.3s; | |
| } | |
| .button:hover { | |
| background-color: #0056b3; | |
| } | |
| .button:disabled { | |
| background-color: #cccccc; | |
| cursor: not-allowed; | |
| } | |
| textarea { | |
| width: 100%; | |
| height: 100px; | |
| margin: 10px 0; | |
| padding: 10px; | |
| border: 1px solid #ddd; | |
| border-radius: 4px; | |
| resize: vertical; | |
| } | |
| .status { | |
| margin: 10px 0; | |
| padding: 10px; | |
| border-radius: 5px; | |
| font-size: 14px; | |
| } | |
| .error { | |
| background-color: #ffe6e6; | |
| border: 1px solid #ffcccc; | |
| color: #cc0000; | |
| } | |
| .success { | |
| background-color: #e6ffe6; | |
| border: 1px solid #ccffcc; | |
| color: #006600; | |
| } | |
| #audioPlayer { | |
| width: 100%; | |
| margin: 10px 0; | |
| } | |
| #avatarCanvas { | |
| width: 100%; | |
| height: 520px; | |
| border-radius: 16px; | |
| background: radial-gradient(circle at top, #22335a 0%, #111827 60%, #050816 100%); | |
| overflow: hidden; | |
| } | |
| .avatar-grid { | |
| display: grid; | |
| grid-template-columns: minmax(0, 1.2fr) minmax(280px, 0.8fr); | |
| gap: 18px; | |
| align-items: start; | |
| } | |
| .avatar-note { | |
| color: #334155; | |
| font-size: 14px; | |
| margin-top: 8px; | |
| } | |
| h1, | |
| h2 { | |
| color: #333; | |
| } | |
| h1 { | |
| border-bottom: 2px solid #007bff; | |
| padding-bottom: 10px; | |
| margin-bottom: 30px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>ASR, TTS, and 3D Avatar Tool</h1> | |
| <div class="section"> | |
| <h2>Speech Recognition</h2> | |
| <div class="controls"> | |
| <div class="record-controls"> | |
| <button id="startRecording" class="button">Start Recording</button> | |
| <button id="stopRecording" class="button" disabled>Stop Recording</button> | |
| </div> | |
| <div class="upload-controls"> | |
| <input type="file" id="audioFileInput" accept="audio/*" | |
| title="Supported formats: WAV, MP3, M4A, OGG, etc. Files will be converted to 16kHz mono WAV." | |
| class="file-input" /> | |
| <button id="uploadAudio" class="button">Upload Audio</button> | |
| </div> | |
| </div> | |
| <div id="asrStatus" class="status"></div> | |
| <textarea id="transcription" placeholder="Transcription will appear here..." readonly></textarea> | |
| </div> | |
| <div class="section"> | |
| <h2>Text to Speech</h2> | |
| <textarea id="ttsInput" placeholder="Enter text for TTS..."></textarea> | |
| <button id="generateSpeech" class="button">Generate Speech</button> | |
| <div id="ttsStatus" class="status"></div> | |
| <audio id="audioPlayer" controls></audio> | |
| <button id="downloadAudio" class="button" disabled>Download Audio</button> | |
| </div> | |
| <div class="section"> | |
| <h2>3D Avatar</h2> | |
| <div class="avatar-grid"> | |
| <div id="avatarCanvas"></div> | |
| <div> | |
| <p><strong>Model:</strong> <span id="avatarModelName">Loading...</span></p> | |
| <p><strong>Lip sync:</strong> <span id="avatarLipSyncState">Idle</span></p> | |
| <p class="avatar-note">This viewer loads <code>live3d-model/andry_3d/avatar_animasi.glb</code> and drives the mouth blendshapes from the TTS audio playback.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <script type="importmap"> | |
| { | |
| "imports": { | |
| "three": "./libs/build/three.module.js" | |
| } | |
| } | |
| </script> | |
| <script src="recorder.js"></script> | |
| <script type="module" src="avatar3d.js"></script> | |
| <script src="main.js"></script> | |
| </body> | |
| </html> |