geadmin commited on
Commit
344df93
·
verified ·
1 Parent(s): 9b652e9

Add 1 files

Browse files
Files changed (1) hide show
  1. index.html +278 -13
index.html CHANGED
@@ -51,6 +51,39 @@
51
  .play-btn:hover {
52
  transform: scale(1.1);
53
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  </style>
55
  </head>
56
  <body>
@@ -89,7 +122,7 @@
89
 
90
  <div class="space-y-4">
91
  <!-- Voice Cards -->
92
- <div class="voice-card bg-gray-50 rounded-lg p-4 border border-gray-200 transition duration-300 cursor-pointer">
93
  <div class="flex items-center space-x-3">
94
  <div class="w-12 h-12 rounded-full bg-indigo-100 flex items-center justify-center">
95
  <i class="fas fa-user text-indigo-600"></i>
@@ -102,7 +135,7 @@
102
  <div class="mt-3 flex justify-between items-center">
103
  <span class="text-xs px-2 py-1 bg-green-100 text-green-800 rounded">Active</span>
104
  <div class="flex space-x-2">
105
- <button class="text-gray-500 hover:text-indigo-600">
106
  <i class="fas fa-play play-btn"></i>
107
  </button>
108
  <button class="text-gray-500 hover:text-indigo-600">
@@ -112,7 +145,7 @@
112
  </div>
113
  </div>
114
 
115
- <div class="voice-card bg-gray-50 rounded-lg p-4 border border-gray-200 transition duration-300 cursor-pointer">
116
  <div class="flex items-center space-x-3">
117
  <div class="w-12 h-12 rounded-full bg-pink-100 flex items-center justify-center">
118
  <i class="fas fa-user text-pink-600"></i>
@@ -125,7 +158,7 @@
125
  <div class="mt-3 flex justify-between items-center">
126
  <span class="text-xs px-2 py-1 bg-gray-100 text-gray-800 rounded">Inactive</span>
127
  <div class="flex space-x-2">
128
- <button class="text-gray-500 hover:text-indigo-600">
129
  <i class="fas fa-play play-btn"></i>
130
  </button>
131
  <button class="text-gray-500 hover:text-indigo-600">
@@ -135,7 +168,7 @@
135
  </div>
136
  </div>
137
 
138
- <div class="voice-card bg-gray-50 rounded-lg p-4 border border-gray-200 transition duration-300 cursor-pointer">
139
  <div class="flex items-center space-x-3">
140
  <div class="w-12 h-12 rounded-full bg-purple-100 flex items-center justify-center">
141
  <i class="fas fa-user text-purple-600"></i>
@@ -148,7 +181,7 @@
148
  <div class="mt-3 flex justify-between items-center">
149
  <span class="text-xs px-2 py-1 bg-gray-100 text-gray-800 rounded">Inactive</span>
150
  <div class="flex space-x-2">
151
- <button class="text-gray-500 hover:text-indigo-600">
152
  <i class="fas fa-play play-btn"></i>
153
  </button>
154
  <button class="text-gray-500 hover:text-indigo-600">
@@ -211,10 +244,10 @@
211
  <div class="mb-4">
212
  <label class="block text-sm font-medium text-gray-700 mb-1">Select Voice</label>
213
  <div class="flex items-center space-x-3">
214
- <select class="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:ring-indigo-500 focus:border-indigo-500">
215
- <option>Professional Male</option>
216
- <option>Friendly Female</option>
217
- <option>British Narrator</option>
218
  </select>
219
  <button class="px-3 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200">
220
  <i class="fas fa-random"></i>
@@ -224,7 +257,7 @@
224
 
225
  <div class="mb-4">
226
  <label class="block text-sm font-medium text-gray-700 mb-1">Enter Text</label>
227
- <textarea rows="5" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-indigo-500 focus:border-indigo-500" placeholder="Type or paste your text here...">Hello, this is a demonstration of the ElevenLabs AI voice cloning technology. The voice you're hearing has been generated by artificial intelligence.</textarea>
228
  </div>
229
 
230
  <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
@@ -246,14 +279,246 @@
246
  </div>
247
  </div>
248
 
 
 
 
 
 
 
 
 
 
 
249
  <div class="flex flex-wrap gap-3">
250
- <button class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 flex items-center">
251
  <i class="fas fa-play mr-2"></i> Generate
252
  </button>
253
- <button class="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 flex items-center">
254
  <i class="fas fa-download mr-2"></i> Download
255
  </button>
256
  <button class="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 flex items-center">
257
  <i class="fas fa-share-alt mr-2"></i> Share
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
  </html>
 
51
  .play-btn:hover {
52
  transform: scale(1.1);
53
  }
54
+
55
+ /* Audio visualization */
56
+ .audio-visualizer {
57
+ display: flex;
58
+ align-items: flex-end;
59
+ height: 60px;
60
+ gap: 2px;
61
+ margin-top: 10px;
62
+ }
63
+
64
+ .audio-bar {
65
+ background-color: #6366f1;
66
+ width: 4px;
67
+ border-radius: 2px;
68
+ transition: height 0.1s ease;
69
+ }
70
+
71
+ /* Progress bar */
72
+ .progress-container {
73
+ width: 100%;
74
+ height: 4px;
75
+ background-color: #e2e8f0;
76
+ border-radius: 2px;
77
+ margin-top: 10px;
78
+ }
79
+
80
+ .progress-bar {
81
+ height: 100%;
82
+ background-color: #6366f1;
83
+ border-radius: 2px;
84
+ width: 0%;
85
+ transition: width 0.1s linear;
86
+ }
87
  </style>
88
  </head>
89
  <body>
 
122
 
123
  <div class="space-y-4">
124
  <!-- Voice Cards -->
125
+ <div class="voice-card bg-gray-50 rounded-lg p-4 border border-gray-200 transition duration-300 cursor-pointer" data-voice="Professional Male">
126
  <div class="flex items-center space-x-3">
127
  <div class="w-12 h-12 rounded-full bg-indigo-100 flex items-center justify-center">
128
  <i class="fas fa-user text-indigo-600"></i>
 
135
  <div class="mt-3 flex justify-between items-center">
136
  <span class="text-xs px-2 py-1 bg-green-100 text-green-800 rounded">Active</span>
137
  <div class="flex space-x-2">
138
+ <button class="text-gray-500 hover:text-indigo-600 play-voice-btn">
139
  <i class="fas fa-play play-btn"></i>
140
  </button>
141
  <button class="text-gray-500 hover:text-indigo-600">
 
145
  </div>
146
  </div>
147
 
148
+ <div class="voice-card bg-gray-50 rounded-lg p-4 border border-gray-200 transition duration-300 cursor-pointer" data-voice="Friendly Female">
149
  <div class="flex items-center space-x-3">
150
  <div class="w-12 h-12 rounded-full bg-pink-100 flex items-center justify-center">
151
  <i class="fas fa-user text-pink-600"></i>
 
158
  <div class="mt-3 flex justify-between items-center">
159
  <span class="text-xs px-2 py-1 bg-gray-100 text-gray-800 rounded">Inactive</span>
160
  <div class="flex space-x-2">
161
+ <button class="text-gray-500 hover:text-indigo-600 play-voice-btn">
162
  <i class="fas fa-play play-btn"></i>
163
  </button>
164
  <button class="text-gray-500 hover:text-indigo-600">
 
168
  </div>
169
  </div>
170
 
171
+ <div class="voice-card bg-gray-50 rounded-lg p-4 border border-gray-200 transition duration-300 cursor-pointer" data-voice="British Narrator">
172
  <div class="flex items-center space-x-3">
173
  <div class="w-12 h-12 rounded-full bg-purple-100 flex items-center justify-center">
174
  <i class="fas fa-user text-purple-600"></i>
 
181
  <div class="mt-3 flex justify-between items-center">
182
  <span class="text-xs px-2 py-1 bg-gray-100 text-gray-800 rounded">Inactive</span>
183
  <div class="flex space-x-2">
184
+ <button class="text-gray-500 hover:text-indigo-600 play-voice-btn">
185
  <i class="fas fa-play play-btn"></i>
186
  </button>
187
  <button class="text-gray-500 hover:text-indigo-600">
 
244
  <div class="mb-4">
245
  <label class="block text-sm font-medium text-gray-700 mb-1">Select Voice</label>
246
  <div class="flex items-center space-x-3">
247
+ <select id="voiceSelect" class="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:ring-indigo-500 focus:border-indigo-500">
248
+ <option value="Professional Male">Professional Male</option>
249
+ <option value="Friendly Female">Friendly Female</option>
250
+ <option value="British Narrator">British Narrator</option>
251
  </select>
252
  <button class="px-3 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200">
253
  <i class="fas fa-random"></i>
 
257
 
258
  <div class="mb-4">
259
  <label class="block text-sm font-medium text-gray-700 mb-1">Enter Text</label>
260
+ <textarea id="textInput" rows="5" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-indigo-500 focus:border-indigo-500" placeholder="Type or paste your text here...">Hello, this is a demonstration of the ElevenLabs AI voice cloning technology. The voice you're hearing has been generated by artificial intelligence.</textarea>
261
  </div>
262
 
263
  <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
 
279
  </div>
280
  </div>
281
 
282
+ <!-- Audio Visualization -->
283
+ <div id="audioVisualization" class="hidden">
284
+ <div class="audio-visualizer" id="visualizer">
285
+ <!-- Bars will be added dynamically -->
286
+ </div>
287
+ <div class="progress-container">
288
+ <div class="progress-bar" id="progressBar"></div>
289
+ </div>
290
+ </div>
291
+
292
  <div class="flex flex-wrap gap-3">
293
+ <button id="generateBtn" class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 flex items-center">
294
  <i class="fas fa-play mr-2"></i> Generate
295
  </button>
296
+ <button id="downloadBtn" class="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 flex items-center">
297
  <i class="fas fa-download mr-2"></i> Download
298
  </button>
299
  <button class="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 flex items-center">
300
  <i class="fas fa-share-alt mr-2"></i> Share
301
+ </button>
302
+ <button id="stopBtn" class="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 flex items-center hidden">
303
+ <i class="fas fa-stop mr-2"></i> Stop
304
+ </button>
305
+ </div>
306
+ </div>
307
+
308
+ <!-- Output Section -->
309
+ <div class="bg-white rounded-xl shadow-md p-6">
310
+ <h2 class="text-xl font-semibold text-gray-800 mb-4">Generated Output</h2>
311
+ <div id="outputContainer" class="bg-gray-50 rounded-lg p-4 min-h-32">
312
+ <p class="text-gray-500 italic" id="outputPlaceholder">Your generated voice will appear here...</p>
313
+ <audio id="audioPlayer" controls class="w-full mt-4 hidden"></audio>
314
+ </div>
315
+ </div>
316
+ </div>
317
+ </div>
318
+ </main>
319
+ </div>
320
 
321
+ <script>
322
+ document.addEventListener('DOMContentLoaded', function() {
323
+ // Modal functionality
324
+ const newVoiceBtn = document.getElementById('newVoiceBtn');
325
+ const closeModalBtn = document.getElementById('closeModalBtn');
326
+ const addVoiceModal = document.getElementById('addVoiceModal');
327
+
328
+ newVoiceBtn.addEventListener('click', () => {
329
+ addVoiceModal.classList.remove('hidden');
330
+ });
331
+
332
+ closeModalBtn.addEventListener('click', () => {
333
+ addVoiceModal.classList.add('hidden');
334
+ });
335
+
336
+ // Voice synthesis functionality
337
+ const generateBtn = document.getElementById('generateBtn');
338
+ const stopBtn = document.getElementById('stopBtn');
339
+ const downloadBtn = document.getElementById('downloadBtn');
340
+ const textInput = document.getElementById('textInput');
341
+ const voiceSelect = document.getElementById('voiceSelect');
342
+ const outputPlaceholder = document.getElementById('outputPlaceholder');
343
+ const audioPlayer = document.getElementById('audioPlayer');
344
+ const audioVisualization = document.getElementById('audioVisualization');
345
+ const visualizer = document.getElementById('visualizer');
346
+ const progressBar = document.getElementById('progressBar');
347
+
348
+ let speechSynthesis = window.speechSynthesis;
349
+ let utterance = null;
350
+ let isPlaying = false;
351
+
352
+ // Create audio visualization bars
353
+ for (let i = 0; i < 50; i++) {
354
+ const bar = document.createElement('div');
355
+ bar.className = 'audio-bar';
356
+ bar.style.height = `${Math.random() * 30 + 10}px`;
357
+ visualizer.appendChild(bar);
358
+ }
359
+
360
+ // Animate visualization bars
361
+ function animateBars() {
362
+ const bars = visualizer.querySelectorAll('.audio-bar');
363
+ bars.forEach(bar => {
364
+ const newHeight = Math.random() * 30 + 10;
365
+ bar.style.height = `${newHeight}px`;
366
+ });
367
+
368
+ if (isPlaying) {
369
+ requestAnimationFrame(animateBars);
370
+ }
371
+ }
372
+
373
+ // Generate voice
374
+ generateBtn.addEventListener('click', () => {
375
+ const text = textInput.value.trim();
376
+ if (!text) return;
377
+
378
+ const selectedVoice = voiceSelect.value;
379
+
380
+ // Update UI
381
+ outputPlaceholder.textContent = `Generating "${selectedVoice}" voice...`;
382
+ audioVisualization.classList.remove('hidden');
383
+ generateBtn.classList.add('hidden');
384
+ stopBtn.classList.remove('hidden');
385
+ isPlaying = true;
386
+
387
+ // Create speech synthesis utterance
388
+ utterance = new SpeechSynthesisUtterance(text);
389
+
390
+ // Set voice properties based on selection
391
+ switch(selectedVoice) {
392
+ case 'Professional Male':
393
+ utterance.rate = 1.0;
394
+ utterance.pitch = 0.9;
395
+ break;
396
+ case 'Friendly Female':
397
+ utterance.rate = 1.1;
398
+ utterance.pitch = 1.2;
399
+ break;
400
+ case 'British Narrator':
401
+ utterance.rate = 0.95;
402
+ utterance.pitch = 0.85;
403
+ break;
404
+ }
405
+
406
+ // Start animation
407
+ animateBars();
408
+
409
+ // Update progress bar
410
+ let startTime = Date.now();
411
+ let estimatedDuration = text.length * 50; // Rough estimate (ms)
412
+
413
+ const progressInterval = setInterval(() => {
414
+ const elapsed = Date.now() - startTime;
415
+ const progress = Math.min(elapsed / estimatedDuration * 100, 100);
416
+ progressBar.style.width = `${progress}%`;
417
+
418
+ if (progress >= 100) {
419
+ clearInterval(progressInterval);
420
+ }
421
+ }, 100);
422
+
423
+ // On speech end
424
+ utterance.onend = () => {
425
+ isPlaying = false;
426
+ generateBtn.classList.remove('hidden');
427
+ stopBtn.classList.add('hidden');
428
+ outputPlaceholder.textContent = `Voice generation complete for "${selectedVoice}"`;
429
+ clearInterval(progressInterval);
430
+ };
431
+
432
+ // On speech error
433
+ utterance.onerror = (event) => {
434
+ console.error('Speech synthesis error:', event);
435
+ isPlaying = false;
436
+ generateBtn.classList.remove('hidden');
437
+ stopBtn.classList.add('hidden');
438
+ outputPlaceholder.textContent = 'Error generating voice. Please try again.';
439
+ clearInterval(progressInterval);
440
+ };
441
+
442
+ // Speak the text
443
+ speechSynthesis.speak(utterance);
444
+ });
445
+
446
+ // Stop generation
447
+ stopBtn.addEventListener('click', () => {
448
+ if (speechSynthesis.speaking) {
449
+ speechSynthesis.cancel();
450
+ isPlaying = false;
451
+ generateBtn.classList.remove('hidden');
452
+ stopBtn.classList.add('hidden');
453
+ outputPlaceholder.textContent = 'Voice generation stopped';
454
+ }
455
+ });
456
+
457
+ // Play voice samples from cards
458
+ const playButtons = document.querySelectorAll('.play-voice-btn');
459
+ playButtons.forEach(button => {
460
+ button.addEventListener('click', (e) => {
461
+ e.stopPropagation();
462
+ const card = button.closest('.voice-card');
463
+ const voiceName = card.dataset.voice;
464
+ const sampleText = `This is a sample of the ${voiceName} voice from ElevenLabs.`;
465
+
466
+ const utterance = new SpeechSynthesisUtterance(sampleText);
467
+
468
+ // Set voice properties based on selection
469
+ switch(voiceName) {
470
+ case 'Professional Male':
471
+ utterance.rate = 1.0;
472
+ utterance.pitch = 0.9;
473
+ break;
474
+ case 'Friendly Female':
475
+ utterance.rate = 1.1;
476
+ utterance.pitch = 1.2;
477
+ break;
478
+ case 'British Narrator':
479
+ utterance.rate = 0.95;
480
+ utterance.pitch = 0.85;
481
+ break;
482
+ }
483
+
484
+ speechSynthesis.speak(utterance);
485
+ });
486
+ });
487
+
488
+ // Download functionality (simulated)
489
+ downloadBtn.addEventListener('click', () => {
490
+ const text = textInput.value.trim();
491
+ if (!text) return;
492
+
493
+ const selectedVoice = voiceSelect.value;
494
+ outputPlaceholder.textContent = `Preparing download for "${selectedVoice}" voice...`;
495
+
496
+ // Simulate download preparation
497
+ setTimeout(() => {
498
+ outputPlaceholder.textContent = `Download ready for "${selectedVoice}" (simulated)`;
499
+
500
+ // In a real implementation, this would download the audio file
501
+ // For now, we'll just show a message
502
+ alert('In a real implementation, this would download the generated voice as an MP3 file.');
503
+ }, 1500);
504
+ });
505
+
506
+ // Voice card selection
507
+ const voiceCards = document.querySelectorAll('.voice-card');
508
+ voiceCards.forEach(card => {
509
+ card.addEventListener('click', () => {
510
+ const voiceName = card.dataset.voice;
511
+ voiceSelect.value = voiceName;
512
+
513
+ // Update active state
514
+ voiceCards.forEach(c => {
515
+ c.querySelector('span').className = 'text-xs px-2 py-1 bg-gray-100 text-gray-800 rounded';
516
+ });
517
+
518
+ card.querySelector('span').className = 'text-xs px-2 py-1 bg-green-100 text-green-800 rounded';
519
+ });
520
+ });
521
+ });
522
+ </script>
523
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - <a href="https://enzostvs-deepsite.hf.space?remix=geadmin/ideas" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p></body>
524
  </html>