00Boobs00 commited on
Commit
7308563
·
verified ·
1 Parent(s): 4dab19a

Upload components/PocketTTS.js with huggingface_hub

Browse files
Files changed (1) hide show
  1. components/PocketTTS.js +90 -0
components/PocketTTS.js ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState, useRef } from 'react';
2
+ import { Volume2, Play } from 'lucide-react';
3
+
4
+ export default function PocketTTS() {
5
+ const [text, setText] = useState('Hello, this is a test of PocketTTS integration.');
6
+ const [audioUrl, setAudioUrl] = useState('');
7
+ const [loading, setLoading] = useState(false);
8
+ const audioRef = useRef(null);
9
+
10
+ const handleSynthesize = async () => {
11
+ if (!text.trim()) return;
12
+ setLoading(true);
13
+ setAudioUrl('');
14
+
15
+ try {
16
+ const response = await fetch('/api/tts', {
17
+ method: 'POST',
18
+ headers: { 'Content-Type': 'application/json' },
19
+ body: JSON.stringify({ text }),
20
+ });
21
+
22
+ if (!response.ok) throw new Error('TTS Generation failed');
23
+
24
+ const blob = await response.blob();
25
+ const url = URL.createObjectURL(blob);
26
+ setAudioUrl(url);
27
+ } catch (err) {
28
+ console.error(err);
29
+ } finally {
30
+ setLoading(false);
31
+ }
32
+ };
33
+
34
+ const playAudio = () => {
35
+ if (audioRef.current) {
36
+ audioRef.current.play();
37
+ }
38
+ };
39
+
40
+ return (
41
+ <div className="bg-slate-800 rounded-xl p-6 shadow-xl border border-slate-700">
42
+ <div className="flex items-center gap-2 mb-4">
43
+ <Volume2 className="w-5 h-5 text-blue-500" />
44
+ <h2 className="text-lg font-semibold text-white">Pocket TTS</h2>
45
+ </div>
46
+
47
+ <div className="space-y-4">
48
+ <div>
49
+ <label className="block text-sm font-medium text-slate-400 mb-1">
50
+ Text to Speech
51
+ </label>
52
+ <textarea
53
+ value={text}
54
+ onChange={(e) => setText(e.target.value)}
55
+ className="w-full bg-slate-900 border border-slate-600 rounded-lg p-3 text-white placeholder-slate-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all resize-none h-24"
56
+ />
57
+ </div>
58
+
59
+ <div className="flex gap-2">
60
+ <button
61
+ onClick={handleSynthesize}
62
+ disabled={loading}
63
+ className="flex-1 bg-blue-600 hover:bg-blue-500 text-white font-medium py-2 rounded-lg transition-colors disabled:opacity-50"
64
+ >
65
+ {loading ? 'Synthesizing...' : 'Generate Audio'}
66
+ </button>
67
+
68
+ {audioUrl && (
69
+ <button
70
+ onClick={playAudio}
71
+ className="bg-slate-700 hover:bg-slate-600 text-white p-2 rounded-lg transition-colors"
72
+ title="Play Audio"
73
+ >
74
+ <Play className="w-5 h-5 fill-current" />
75
+ </button>
76
+ )}
77
+ </div>
78
+
79
+ {audioUrl && (
80
+ <audio
81
+ ref={audioRef}
82
+ src={audioUrl}
83
+ controls
84
+ className="w-full mt-2 h-8"
85
+ />
86
+ )}
87
+ </div>
88
+ </div>
89
+ );
90
+ }