A high-quality Dart implementation of Microsoft Edge Text-to-Speech (TTS) API, providing seamless text-to-speech conversion with support for 500+ voices across 40+ languages.
- � 500+ Voices: Access to Microsoft Edge's complete voice library
- 🌍 Multi-language: Support for 40+ languages and locales
- 🔄 Streaming: Real-time audio streaming with metadata synchronization
- 📝 Subtitles: Generate SRT and WebVTT subtitle files
- 🛠️ CLI Tools: Command-line interface for easy integration
- 🔐 Enterprise Ready: Robust DRM authentication and error handling
- 🎯 Type Safe: Full Dart type safety with comprehensive error handling
Add to your pubspec.yaml:
dependencies:
edge_dart: ^1.0.0import 'package:edge_dart/edge_dart.dart';
Future<void> main() async {
// Simple text-to-speech
final tts = Communicate(
'Hello, world! This is Edge TTS.',
'en-US-EmmaMultilingualNeural',
);
await tts.save('hello.mp3');
print('Audio saved successfully!');
}import 'package:edge_dart/edge_dart.dart';
Future<void> main() async {
final tts = Communicate(
'This is a streaming example.',
'en-US-EmmaMultilingualNeural',
boundary: BoundaryType.wordBoundary,
);
await for (final chunk in tts.stream()) {
if (chunk is AudioChunk) {
print('Audio chunk: ${chunk.data.length} bytes');
} else if (chunk is MetadataChunk) {
print('Word: "${chunk.text}" at ${chunk.offset}ms');
}
}
}# Basic synthesis
dart run bin/edge_dart.dart -t "Hello World" -o output.mp3
# List available voices
dart run bin/edge_dart.dart --list-voices
# Advanced options
dart run bin/edge_dart.dart -t "Hello" -v en-US-JennyNeural --rate +50% --volume +20%
# Generate subtitles
dart run bin/edge_dart.dart -t "Hello World" -s subtitles.srtimport 'package:edge_dart/edge_dart.dart';
Future<void> main() async {
// List all voices
final voices = await listVoices();
print('Found ${voices.length} voices');
// Find specific voices
final voicesManager = await VoicesManager.create();
final englishVoices = voicesManager.find(
language: 'en',
gender: 'Female',
);
for (final voice in englishVoices.take(5)) {
print('${voice.shortName} (${voice.locale})');
}
}MIT License - see LICENSE file for details.
- Inspired by edge-tts Python library
- Microsoft Edge TTS service
Microsoft Edge 文本转语音 (TTS) API 的高质量 Dart 实现,支持 500+ 种语音和 40+ 种语言的无缝文本转语音转换。
- 🎤 500+ 语音: 访问 Microsoft Edge 完整的语音库
- 🌍 多语言: 支持 40+ 种语言和地区
- 🔄 流式传输: 实时音频流传输和元数据同步
- 📝 字幕生成: 生成 SRT 和 WebVTT 字幕文件
- 🛠️ 命令行工具: 便于集成的命令行接口
- 🔐 企业级: 健壮的 DRM 认证和错误处理
- 🎯 类型安全: 完整的 Dart 类型安全和错误处理
在 pubspec.yaml 中添加:
dependencies:
edge_dart: ^1.0.0import 'package:edge_dart/edge_dart.dart';
Future<void> main() async {
// 简单的文本转语音
final tts = Communicate(
'你好,世界!这是 Edge TTS。',
'zh-CN-XiaoyiNeural',
);
await tts.save('hello.mp3');
print('音频保存成功!');
}import 'package:edge_dart/edge_dart.dart';
Future<void> main() async {
final tts = Communicate(
'这是一个流式传输示例。',
'zh-CN-XiaoyiNeural',
boundary: BoundaryType.wordBoundary,
);
await for (final chunk in tts.stream()) {
if (chunk is AudioChunk) {
print('音频块: ${chunk.data.length} 字节');
} else if (chunk is MetadataChunk) {
print('词语: "${chunk.text}" 在 ${chunk.offset}ms');
}
}
}# 基本合成
dart run bin/edge_dart.dart -t "你好世界" -o output.mp3
# 列出可用语音
dart run bin/edge_dart.dart --list-voices
# 高级选项
dart run bin/edge_dart.dart -t "你好" -v zh-CN-XiaoyiNeural --rate +50% --volume +20%
# 生成字幕
dart run bin/edge_dart.dart -t "你好世界" -s subtitles.srtimport 'package:edge_dart/edge_dart.dart';
Future<void> main() async {
// 列出所有语音
final voices = await listVoices();
print('找到 ${voices.length} 个语音');
// 查找特定语音
final voicesManager = await VoicesManager.create();
final chineseVoices = voicesManager.find(
language: 'zh',
gender: 'Female',
);
for (final voice in chineseVoices.take(5)) {
print('${voice.shortName} (${voice.locale})');
}
}- 中文: 简体中文、繁体中文(大陆、台湾、香港)
- 英语: 美国、英国、澳大利亚、印度等
- 日语: 标准日语和地区变体
- 韩语: 韩国标准语
- 西班牙语: 西班牙、墨西哥、阿根廷等
- 法语: 法国、加拿大、比利时、瑞士
- 德语: 德国、奥地利、瑞士
- 以及 35+ 种其他语言
MIT 许可证 - 详见 LICENSE 文件。
- 受 edge-tts Python 库启发
- Microsoft Edge TTS 服务
Communicate(
String text, // Text to synthesize
String voice, // Voice name (e.g., 'en-US-EmmaMultilingualNeural')
{
String rate = '+0%', // Speech rate: '+50%', '-20%', etc.
String volume = '+0%', // Volume: '+20%', '-10%', etc.
String pitch = '+0Hz', // Pitch: '+100Hz', '-50Hz', etc.
BoundaryType boundary = BoundaryType.sentenceBoundary,
}
)Methods:
Stream<TtsChunk> stream()- Stream audio and metadata chunksFuture<void> save(String audioPath, {String? metadataPath})- Save to files
// List all available voices
final voices = await listVoices();
// Advanced voice search
final manager = await VoicesManager.create();
final results = manager.find(
language: 'en', // Language code
gender: 'Female', // 'Male' or 'Female'
locale: 'en-US', // Specific locale
);final subMaker = SubMaker();
// or
final advancedSubMaker = AdvancedSubMaker();
// Feed metadata chunks
subMaker.feed(metadataChunk);
// Generate subtitles
final srtContent = subMaker.getSrt();
final vttContent = subMaker.getVtt();final tts = Communicate(
'This is a test with custom parameters.',
'en-US-JennyNeural',
rate: '+50%', // 50% faster
volume: '+20%', // 20% louder
pitch: '+100Hz', // Higher pitch
);
await tts.save('custom_voice.mp3');final tts = Communicate(
'First sentence. Second sentence. Third sentence.',
'en-US-EmmaMultilingualNeural',
boundary: BoundaryType.sentenceBoundary,
);
final subMaker = AdvancedSubMaker();
final audioData = <int>[];
await for (final chunk in tts.stream()) {
if (chunk is AudioChunk) {
audioData.addAll(chunk.data);
} else if (chunk is MetadataChunk) {
subMaker.feed(chunk);
}
}
// Save audio
await File('output.mp3').writeAsBytes(audioData);
// Save subtitles
await File('output.srt').writeAsString(subMaker.getSrt());- ✅ Windows: Full support
- ✅ macOS: Full support
- ✅ Linux: Full support
- ✅ Web: WebSocket streaming supported
- ✅ Mobile: Android and iOS compatible
No audio generated
- Verify voice name spelling
- Check internet connectivity
- Ensure text is not empty
WebSocket connection errors
- Check firewall settings
- Verify network connectivity
- Try different voice/text combination
403 Forbidden errors
- Automatic retry mechanism handles this
- DRM authentication resolves most cases
- Reuse
VoicesManagerinstances for better performance - Use streaming for large texts
- Close WebSocket connections properly
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create your feature branch
- Add tests for new features
- Ensure all tests pass
- Submit a pull request
- Batch Processing: Multiple text synthesis in parallel
- Voice Cloning: Custom voice training support
- SSML Support: Advanced SSML markup
- Caching: Voice and authentication caching
- Plugins: Extension system for custom processors
If you find this project useful, please consider giving it a star on GitHub!
- 📧 Issues: GitHub Issues
- � Discussions: GitHub Discussions
- 📖 Documentation: Wiki