wasmdashai commited on
Commit
4c2bc7a
·
verified ·
1 Parent(s): f01d749

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +104 -98
index.html CHANGED
@@ -94,11 +94,9 @@
94
  <div class="p-6 border-b border-gray-100">
95
  <h2 class="text-xl font-semibold text-gray-800 mb-4">Text Input</h2>
96
  <div class="relative">
97
- <textarea
98
- id="textInput"
99
- class="w-full h-48 px-4 py-3 border border-gray-200 rounded-lg textarea-shadow focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition duration-200 resize-none"
100
- placeholder="Enter the text you want to convert to speech..."
101
- ></textarea>
102
  <div class="absolute bottom-3 right-3 flex items-center space-x-2">
103
  <span id="charCount" class="text-xs text-gray-500">0 characters</span>
104
  <button id="clearBtn" class="text-gray-400 hover:text-gray-600 transition">
@@ -106,16 +104,18 @@
106
  </button>
107
  </div>
108
  </div>
109
-
110
  <div class="mt-6 flex flex-col sm:flex-row justify-between items-center space-y-4 sm:space-y-0">
111
  <div class="flex items-center space-x-4">
112
  <div class="flex items-center">
113
  <label for="voiceSelect" class="mr-2 text-sm font-medium text-gray-700">Voice:</label>
114
  <select id="voiceSelect" class="border border-gray-200 rounded-md px-3 py-1 text-sm focus:ring-indigo-500 focus:border-indigo-500 outline-none">
 
 
115
  <option value="us">American English</option>
116
- <option value="uk">British English</option>
117
- <option value="au">Australian English</option>
118
- <option value="in">Indian English</option>
119
  </select>
120
  </div>
121
  <div class="flex items-center">
@@ -127,18 +127,18 @@
127
  </select>
128
  </div>
129
  </div>
130
-
131
  <button id="generateBtn" class="gradient-bg hover:opacity-90 text-white font-medium py-2 px-6 rounded-lg shadow-md transition duration-200 flex items-center">
132
  <i class="fas fa-play-circle mr-2"></i>
133
  Generate Voice
134
  </button>
135
  </div>
136
  </div>
137
-
138
  <!-- Output Section -->
139
  <div class="p-6">
140
  <h2 class="text-xl font-semibold text-gray-800 mb-4">Generated Audio</h2>
141
-
142
  <!-- Loading State -->
143
  <div id="loadingState" class="hidden">
144
  <div class="flex flex-col items-center justify-center py-8">
@@ -147,7 +147,7 @@
147
  <p class="text-sm text-gray-500 mt-1">This may take a few moments</p>
148
  </div>
149
  </div>
150
-
151
  <!-- Audio Player -->
152
  <div id="audioPlayerContainer" class="hidden">
153
  <div class="audio-player bg-gradient-to-r from-indigo-50 to-purple-50 rounded-xl p-4 border border-gray-200">
@@ -166,7 +166,7 @@
166
  <audio id="audioPlayer" controls class="w-full"></audio>
167
  </div>
168
  </div>
169
-
170
  <!-- Empty State -->
171
  <div id="emptyState" class="flex flex-col items-center justify-center py-12 text-center">
172
  <i class="fas fa-comment-dots text-4xl text-gray-300 mb-4"></i>
@@ -175,7 +175,7 @@
175
  </div>
176
  </div>
177
  </div>
178
-
179
  <!-- Features Section -->
180
  <div class="mt-12 grid grid-cols-1 md:grid-cols-3 gap-6">
181
  <div class="bg-white p-6 rounded-xl shadow-sm border border-gray-100">
@@ -218,9 +218,14 @@
218
  </div>
219
  </footer>
220
  </div>
 
 
 
 
 
 
 
221
 
222
- <script>
223
- document.addEventListener('DOMContentLoaded', function() {
224
  // DOM Elements
225
  const textInput = document.getElementById('textInput');
226
  const charCount = document.getElementById('charCount');
@@ -234,104 +239,105 @@
234
  const audioPlayer = document.getElementById('audioPlayer');
235
  const downloadBtn = document.getElementById('downloadBtn');
236
  const audioInfo = document.getElementById('audioInfo');
 
 
 
 
 
 
237
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  // Update character count
239
- textInput.addEventListener('input', function() {
240
  const count = textInput.value.length;
241
- charCount.textContent = `${count} characters`;
242
-
243
- if (count > 0) {
244
- clearBtn.classList.remove('invisible');
245
- } else {
246
- clearBtn.classList.add('invisible');
247
- }
248
  });
249
-
250
  // Clear text input
251
- clearBtn.addEventListener('click', function() {
252
  textInput.value = '';
253
- charCount.textContent = '0 characters';
254
- clearBtn.classList.add('invisible');
255
  });
256
-
257
  // Generate voice
258
- generateBtn.addEventListener('click', function() {
259
  const text = textInput.value.trim();
260
- if (!text) {
261
- alert('Please enter some text to convert to speech.');
262
- return;
263
  }
264
-
265
- const voice = voiceSelect.value;
266
- const speed = speedSelect.value;
267
-
268
- // Show loading state
269
- loadingState.classList.remove('hidden');
270
- audioPlayerContainer.classList.add('hidden');
271
- emptyState.classList.add('hidden');
272
-
273
- // Simulate API call (in a real app, this would be a fetch or axios call)
274
- simulateAPICall(text, voice, speed);
275
- });
 
 
 
 
 
 
 
276
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
  // Download audio
278
- downloadBtn.addEventListener('click', function() {
279
  if (audioPlayer.src) {
280
  const a = document.createElement('a');
281
- a.href = audioPlayer.src;
282
- a.download = `lahja-ai-voice-${new Date().getTime()}.mp3`;
283
- document.body.appendChild(a);
284
- a.click();
285
- document.body.removeChild(a);
286
  }
287
  });
288
-
289
- // Simulate API call (replace with actual API call in production)
290
- function simulateAPICall(text, voice, speed) {
291
- console.log(`Making API call with text: "${text}", voice: ${voice}, speed: ${speed}`);
292
-
293
- // Simulate network delay
294
- setTimeout(() => {
295
- // This is a simulation - in a real app, you would:
296
- // 1. Make a POST request to your API endpoint
297
- // 2. Handle the response with the audio URL
298
- // 3. Set the audio player source
299
-
300
- // For demo purposes, we'll use a placeholder audio
301
- const voiceLabels = {
302
- 'us': 'American English',
303
- 'uk': 'wasmdashai/vits-ar-sa-huba-v1',
304
- 'au': 'Australian English',
305
- 'in': 'Indian English'
306
- };
307
-
308
- const speedLabels = {
309
- '0.8': 'Slow',
310
- '1.0': 'Normal',
311
- '1.2': 'Fast'
312
- };
313
-
314
- // Update audio info
315
- audioInfo.textContent = `${voiceLabels[voice]} • ${speedLabels[speed]} speed`;
316
-
317
- // Set audio source (in a real app, this would come from the API response)
318
- audioPlayer.src = 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3';
319
-
320
- // Hide loading, show audio player
321
- loadingState.classList.add('hidden');
322
- audioPlayerContainer.classList.remove('hidden');
323
-
324
- // Play audio automatically
325
- setTimeout(() => {
326
- audioPlayer.play().catch(e => console.log('Autoplay prevented:', e));
327
- }, 300);
328
-
329
- }, 2000);
330
- }
331
-
332
- // Initialize
333
  textInput.dispatchEvent(new Event('input'));
334
  });
335
  </script>
336
- <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=wasmdashai/mywap" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
 
 
337
  </html>
 
94
  <div class="p-6 border-b border-gray-100">
95
  <h2 class="text-xl font-semibold text-gray-800 mb-4">Text Input</h2>
96
  <div class="relative">
97
+ <textarea id="textInput"
98
+ class="w-full h-48 px-4 py-3 border border-gray-200 rounded-lg textarea-shadow focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition duration-200 resize-none"
99
+ placeholder="Enter the text you want to convert to speech...">السلام عليكم كيف الحال اخبارك علومك وش مسوي بالله وش الجديد </textarea>
 
 
100
  <div class="absolute bottom-3 right-3 flex items-center space-x-2">
101
  <span id="charCount" class="text-xs text-gray-500">0 characters</span>
102
  <button id="clearBtn" class="text-gray-400 hover:text-gray-600 transition">
 
104
  </button>
105
  </div>
106
  </div>
107
+
108
  <div class="mt-6 flex flex-col sm:flex-row justify-between items-center space-y-4 sm:space-y-0">
109
  <div class="flex items-center space-x-4">
110
  <div class="flex items-center">
111
  <label for="voiceSelect" class="mr-2 text-sm font-medium text-gray-700">Voice:</label>
112
  <select id="voiceSelect" class="border border-gray-200 rounded-md px-3 py-1 text-sm focus:ring-indigo-500 focus:border-indigo-500 outline-none">
113
+ <option value="SA2">Najdi Arabic Haba v2</option>
114
+
115
  <option value="us">American English</option>
116
+ <option value="SA1">Najdi Arabic Haba v1</option>
117
+
118
+ <option value="SA3">Najdi Arabic AHmmed v1</option>
119
  </select>
120
  </div>
121
  <div class="flex items-center">
 
127
  </select>
128
  </div>
129
  </div>
130
+
131
  <button id="generateBtn" class="gradient-bg hover:opacity-90 text-white font-medium py-2 px-6 rounded-lg shadow-md transition duration-200 flex items-center">
132
  <i class="fas fa-play-circle mr-2"></i>
133
  Generate Voice
134
  </button>
135
  </div>
136
  </div>
137
+
138
  <!-- Output Section -->
139
  <div class="p-6">
140
  <h2 class="text-xl font-semibold text-gray-800 mb-4">Generated Audio</h2>
141
+
142
  <!-- Loading State -->
143
  <div id="loadingState" class="hidden">
144
  <div class="flex flex-col items-center justify-center py-8">
 
147
  <p class="text-sm text-gray-500 mt-1">This may take a few moments</p>
148
  </div>
149
  </div>
150
+
151
  <!-- Audio Player -->
152
  <div id="audioPlayerContainer" class="hidden">
153
  <div class="audio-player bg-gradient-to-r from-indigo-50 to-purple-50 rounded-xl p-4 border border-gray-200">
 
166
  <audio id="audioPlayer" controls class="w-full"></audio>
167
  </div>
168
  </div>
169
+
170
  <!-- Empty State -->
171
  <div id="emptyState" class="flex flex-col items-center justify-center py-12 text-center">
172
  <i class="fas fa-comment-dots text-4xl text-gray-300 mb-4"></i>
 
175
  </div>
176
  </div>
177
  </div>
178
+
179
  <!-- Features Section -->
180
  <div class="mt-12 grid grid-cols-1 md:grid-cols-3 gap-6">
181
  <div class="bg-white p-6 rounded-xl shadow-sm border border-gray-100">
 
218
  </div>
219
  </footer>
220
  </div>
221
+
222
+ <script type="module">
223
+ import {Client} from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
224
+
225
+ document.addEventListener('DOMContentLoaded', async function () {
226
+ // Connect to Gradio client (must be inside async function)
227
+ const client = await Client.connect("wasmdashai/RunTasking");
228
 
 
 
229
  // DOM Elements
230
  const textInput = document.getElementById('textInput');
231
  const charCount = document.getElementById('charCount');
 
239
  const audioPlayer = document.getElementById('audioPlayer');
240
  const downloadBtn = document.getElementById('downloadBtn');
241
  const audioInfo = document.getElementById('audioInfo');
242
+
243
+ const voiceLabels = {
244
+ 'us': 'American English',
245
+ 'SA1': 'Najdi Arabic Haba v1',
246
+ 'SA2': 'Najdi Arabic Haba v2',
247
+ 'SA3': 'Najdi Arabic AHmmed v1',
248
 
249
+ };
250
+
251
+ const voiceModels = {
252
+ 'us': 'wasmdashai/vits-en-v1',
253
+ 'SA1': 'wasmdashai/vits-ar-sa-huba-v1',
254
+ 'SA2': 'wasmdashai/vits-ar-sa-huba-v2',
255
+ 'SA3': 'wasmdashai/vits-ar-sa-A',
256
+
257
+
258
+ };
259
+
260
+ const speedLabels = {
261
+ '0.3': 'Slow',
262
+ '1.0': 'Normal',
263
+ '1.2': 'Fast'
264
+ };
265
+
266
  // Update character count
267
+ textInput.addEventListener('input', function () {
268
  const count = textInput.value.length;
269
+ charCount.textContent = `${count} characters`;
270
+ clearBtn.classList.toggle('invisible', count === 0);
 
 
 
 
 
271
  });
272
+
273
  // Clear text input
274
+ clearBtn.addEventListener('click', function () {
275
  textInput.value = '';
276
+ charCount.textContent = '0 characters';
277
+ clearBtn.classList.add('invisible');
278
  });
279
+
280
  // Generate voice
281
+ generateBtn.addEventListener('click', async function () {
282
  const text = textInput.value.trim();
283
+ if (!text) {
284
+ alert('Please enter some text to convert to speech.');
285
+ return;
286
  }
287
+
288
+ const voice = voiceSelect.value;
289
+ const speed = parseFloat(speedSelect.value);
290
+
291
+ loadingState.classList.remove('hidden');
292
+ audioPlayerContainer.classList.add('hidden');
293
+ emptyState.classList.add('hidden');
294
+ console.log("start result:", voice);
295
+
296
+ try {
297
+ const result = await client.predict("/predict", {
298
+ text: text,
299
+ name_model: voiceModels[voice],
300
+ speaking_rate: 0.9
301
+ });
302
+ console.log("Prediction result:", result);
303
+
304
+ const audioUrl = result.data?.[0]?.url;
305
+ if (!audioUrl) throw new Error("No audio URL received");
306
 
307
+ audioPlayer.src = audioUrl;
308
+ audioInfo.textContent = `${voiceLabels[voice]} • ${speedLabels[speed.toFixed(1)]} speed`;
309
+
310
+ loadingState.classList.add('hidden');
311
+ audioPlayerContainer.classList.remove('hidden');
312
+
313
+ // Auto play
314
+ setTimeout(() => {
315
+ audioPlayer.play().catch(e => console.warn('Autoplay failed:', e));
316
+ }, 300);
317
+ } catch (err) {
318
+ console.error("Error during prediction:", err);
319
+ loadingState.classList.add('hidden');
320
+ emptyState.classList.remove('hidden');
321
+ }
322
+ });
323
+
324
  // Download audio
325
+ downloadBtn.addEventListener('click', function () {
326
  if (audioPlayer.src) {
327
  const a = document.createElement('a');
328
+ a.href = audioPlayer.src;
329
+ a.download = `lahja-ai-voice-${Date.now()}.mp3`;
330
+ document.body.appendChild(a);
331
+ a.click();
332
+ document.body.removeChild(a);
333
  }
334
  });
335
+
336
+ // Initialize char count
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
337
  textInput.dispatchEvent(new Event('input'));
338
  });
339
  </script>
340
+
341
+ <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=wasmdashai/mywap" style="color: #fff;text-decoration: underline;" target="_blank">Remix</a></p>
342
+ </body>
343
  </html>