(null);
const [loading, setLoading] = useState(false);
const handleSpeak = async () => {
setLoading(true);
try {
const response = await fetch('/api/tts/edge', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text }),
});
const blob = await response.blob();
const url = URL.createObjectURL(blob);
setAudioUrl(url);
} finally {
setLoading(false);
}
};
const { ref, isLoading, ...audio } = useAudioPlayer(audioUrl || '');
return (
);
}
```
---
## React Hooks
### useEdgeSpeech
```tsx
import { useEdgeSpeech } from '@lobehub/tts/react';
function EdgeSpeechComponent() {
const { speak, stop, isLoading, error } = useEdgeSpeech({
locale: 'en-US',
voice: 'en-US-AriaNeural',
});
const handleSpeak = () => {
speak('Hello from Edge Speech!');
};
return (
{error &&
Error: {error.message}
}
);
}
```
### useOpenAITTS
```tsx
import { useOpenAITTS } from '@lobehub/tts/react';
function OpenAITTSComponent() {
const { speak, stop, isLoading, audioUrl } = useOpenAITTS({
apiKey: process.env.NEXT_PUBLIC_OPENAI_API_KEY,
voice: 'nova',
model: 'tts-1-hd',
});
return (
{audioUrl &&
}
);
}
```
### useOpenAISTT (Speech-to-Text)
```tsx
import { useOpenAISTT } from '@lobehub/tts/react';
function SpeechToTextComponent() {
const {
startRecording,
stopRecording,
isRecording,
transcript,
error
} = useOpenAISTT({
apiKey: process.env.NEXT_PUBLIC_OPENAI_API_KEY,
});
return (
{transcript &&
Transcript: {transcript}
}
{error &&
Error: {error.message}
}
);
}
```
### useAudioRecorder
```tsx
import { useAudioRecorder } from '@lobehub/tts/react';
function AudioRecorderComponent() {
const {
startRecording,
stopRecording,
isRecording,
audioBlob,
audioUrl,
duration,
} = useAudioRecorder();
const handleSave = () => {
if (audioBlob) {
const a = document.createElement('a');
a.href = audioUrl!;
a.download = 'recording.webm';
a.click();
}
};
return (
{audioUrl && (
<>
>
)}
);
}
```
### useSpeechRecognition (Browser Native)
```tsx
import { useSpeechRecognition } from '@lobehub/tts/react';
function BrowserSTTComponent() {
const {
startListening,
stopListening,
isListening,
transcript,
isSupported,
} = useSpeechRecognition({
language: 'en-US',
continuous: true,
});
if (!isSupported) {
return Speech recognition not supported in this browser.
;
}
return (
Transcript: {transcript}
);
}
```
---
## Voice Options
### Edge Speech Voices (Free)
```typescript
// Popular English voices
const englishVoices = [
'en-US-GuyNeural', // Male, casual
'en-US-AriaNeural', // Female, friendly
'en-US-JennyNeural', // Female, assistant
'en-US-DavisNeural', // Male, deep
'en-GB-SoniaNeural', // Female, British
'en-GB-RyanNeural', // Male, British
'en-AU-NatashaNeural', // Female, Australian
];
// Other languages
const multilingualVoices = [
'zh-CN-XiaoxiaoNeural', // Chinese, Female
'ja-JP-NanamiNeural', // Japanese, Female
'de-DE-KatjaNeural', // German, Female
'fr-FR-DeniseNeural', // French, Female
'es-ES-ElviraNeural', // Spanish, Female
'ko-KR-SunHiNeural', // Korean, Female
];
```
### OpenAI Voices
```typescript
const openaiVoices = [
'alloy', // Neutral, versatile
'echo', // Warm, conversational
'fable', // Expressive, storytelling
'onyx', // Deep, authoritative
'nova', // Friendly, energetic
'shimmer', // Clear, professional
];
```
---
## Configuration Options
### EdgeSpeechTTS Options
```typescript
interface EdgeSpeechTTSOptions {
locale: string; // Language/region code
pitch?: string; // Pitch adjustment (-50% to +50%)
rate?: string; // Speed adjustment (0.5 to 2.0)
volume?: string; // Volume adjustment (0 to 100)
}
const tts = new EdgeSpeechTTS({
locale: 'en-US',
});
const payload = {
input: 'Text to speak',
options: {
voice: 'en-US-AriaNeural',
pitch: '+5%',
rate: '1.2',
volume: '80',
},
};
```
### MicrosoftTTS Options
```typescript
interface MicrosoftSpeechTTSOptions {
locale: string;
subscriptionKey: string;
region: string;
}
interface MicrosoftSpeakOptions {
voice: string;
style?: string; // cheerful, sad, angry, etc.
styleDegree?: number; // 0.01 to 2
role?: string; // Girl, Boy, etc.
rate?: string;
pitch?: string;
}
```
### OpenAI TTS Options
```typescript
interface OpenAITTSOptions {
apiKey: string;
baseUrl?: string; // Custom API endpoint
}
interface OpenAISpeakOptions {
model: 'tts-1' | 'tts-1-hd';
voice: 'alloy' | 'echo' | 'fable' | 'onyx' | 'nova' | 'shimmer';
speed?: number; // 0.25 to 4.0
response_format?: 'mp3' | 'opus' | 'aac' | 'flac';
}
```
---
## Streaming Support
### Stream TTS Response
```typescript
import { EdgeSpeechTTS } from '@lobehub/tts';
const tts = new EdgeSpeechTTS({ locale: 'en-US' });
// Get stream instead of buffer
const response = await tts.createStream({
input: 'Long text to stream...',
options: { voice: 'en-US-GuyNeural' },
});
// Process stream
const reader = response.body?.getReader();
if (reader) {
while (true) {
const { done, value } = await reader.read();
if (done) break;
// Process chunk
console.log('Received chunk:', value.length, 'bytes');
}
}
```
---
## Error Handling
```typescript
import { EdgeSpeechTTS } from '@lobehub/tts';
async function generateSpeech(text: string) {
try {
const tts = new EdgeSpeechTTS({ locale: 'en-US' });
const response = await tts.create({
input: text,
options: { voice: 'en-US-GuyNeural' },
});
return Buffer.from(await response.arrayBuffer());
} catch (error) {
if (error instanceof Error) {
if (error.message.includes('WebSocket')) {
console.error('WebSocket connection failed. Check network.');
} else if (error.message.includes('voice')) {
console.error('Invalid voice selection.');
} else {
console.error('TTS Error:', error.message);
}
}
throw error;
}
}
```
---
## Integration Examples
### With LobeChat
```typescript
// LobeTTS is used internally by LobeChat for voice features
import { EdgeSpeechTTS } from '@lobehub/tts';
// LobeChat voice assistant pattern
async function speakAssistantResponse(message: string) {
const tts = new EdgeSpeechTTS({ locale: 'en-US' });
const audio = await tts.create({
input: message,
options: { voice: 'en-US-AriaNeural' },
});
return audio;
}
```
### With AI Chatbot
```typescript
// Complete voice-enabled chatbot
import { useOpenAITTS, useOpenAISTT } from '@lobehub/tts/react';
function VoiceChatbot() {
const { speak, isLoading: isSpeaking } = useOpenAITTS({
apiKey: process.env.NEXT_PUBLIC_OPENAI_API_KEY!,
voice: 'nova',
});
const {
startRecording,
stopRecording,
isRecording,
transcript,
} = useOpenAISTT({
apiKey: process.env.NEXT_PUBLIC_OPENAI_API_KEY!,
});
const handleChat = async () => {
stopRecording();
// Send transcript to AI
const response = await fetch('/api/chat', {
method: 'POST',
body: JSON.stringify({ message: transcript }),
});
const { reply } = await response.json();
// Speak AI response
speak(reply);
};
return (
{transcript &&
You said: {transcript}
}
);
}
```
---
## Best Practices
### Performance
1. **Reuse TTS instances**: Create once, use multiple times
2. **Stream for long text**: Use streaming for text >500 characters
3. **Cache audio**: Store generated audio to avoid regeneration
4. **Preload voices**: Initialize TTS early in app lifecycle
### Quality
1. **Choose appropriate voice**: Match voice to content tone
2. **Use HD models**: OpenAI tts-1-hd for critical content
3. **Add SSML**: For precise pronunciation control
4. **Test across browsers**: Verify audio playback compatibility
### Cost Optimization
1. **Use Edge TTS**: Free and high quality for most use cases
2. **Batch requests**: Combine short texts when possible
3. **Implement caching**: Hash text → cached audio
4. **Rate limit**: Prevent abuse in production
---
## Troubleshooting
### "WebSocket is not defined"
```typescript
// Add to Node.js entry point
import WebSocket from 'ws';
global.WebSocket = WebSocket;
```
### "Module not found: @lobehub/tts"
```javascript
// next.config.js
module.exports = {
transpilePackages: ['@lobehub/tts'],
};
```
### Audio not playing in browser
```typescript
// Ensure user interaction before playing
document.addEventListener('click', () => {
audio.play();
}, { once: true });
```
### CORS errors with API routes
```typescript
// Add CORS headers
return new NextResponse(audioBuffer, {
headers: {
'Content-Type': 'audio/mpeg',
'Access-Control-Allow-Origin': '*',
},
});
```
---
## Resources
### Official Links
- **GitHub**: https://github.com/lobehub/lobe-tts
- **npm**: https://www.npmjs.com/package/@lobehub/tts
- **License**: MIT
### Related LobeHub Projects
- **LobeChat**: Extensible chatbot framework
- **LobeUI**: Component library for AI apps
- **LobeIcons**: AI/LLM brand logos
- **Lobei18n**: Internationalization tool
### Voice Resources
- [Microsoft Edge TTS Voices](https://docs.microsoft.com/azure/cognitive-services/speech-service/language-support)
- [OpenAI TTS Documentation](https://platform.openai.com/docs/guides/text-to-speech)
---
## Version History
- **Current**: 100+ releases on npm
- **Tech Stack**: TypeScript, React, ESM
- **License**: MIT © 2023 LobeHub
---
**Last Updated**: 2026-01-13
**Skill Version**: 1.0.0
**Source**: https://github.com/lobehub/lobe-tts