名称: sapi-tts
描述: 基于 Windows SAPI5 的文本转语音,支持神经语音。轻量级替代高 GPU 占用的 TTS 方案——零 GPU 占用,即时生成。自动检测系统上可用的最佳语音。支持 Windows 10/11。
使用 Windows 内置 SAPI5 的轻量级文本转语音工具。零 GPU 占用,即时生成。
将以下脚本保存为 tts.ps1,并放入你的技能文件夹中:
<#
.SYNOPSIS
Windows SAPI5 TTS - 轻量级文本转语音
.DESCRIPTION
使用 Windows 内置语音合成引擎 (SAPI5)。
支持神经语音 (Windows 11) 或传统语音 (Windows 10)。
零 GPU 占用,即时生成。
#>
param(
[Parameter(Mandatory=$false, Position=0)]
[string]$Text = "",
[Parameter(Mandatory=$false)]
[Alias("Voice", "v")]
[string]$VoiceName = "",
[Parameter(Mandatory=$false)]
[Alias("Lang", "l")]
[string]$Language = "fr",
[Parameter(Mandatory=$false)]
[Alias("o")]
[string]$Output = "",
[Parameter(Mandatory=$false)]
[Alias("r")]
[int]$Rate = 0,
[Parameter(Mandatory=$false)]
[Alias("p")]
[switch]$Play,
[Parameter(Mandatory=$false)]
[switch]$ListVoices
)
Add-Type -AssemblyName System.Speech
$synth = New-Object System.Speech.Synthesis.SpeechSynthesizer
$installedVoices = $synth.GetInstalledVoices() | Where-Object { $_.Enabled } | ForEach-Object { $_.VoiceInfo }
if ($ListVoices) {
Write-Host "`n已安装的 SAPI5 语音列表:`n" -ForegroundColor Cyan
foreach ($v in $installedVoices) {
$type = if ($v.Name -match "Online|Neural") { "[神经]" } else { "[传统]" }
Write-Host " $($v.Name)" -ForegroundColor White -NoNewline
Write-Host " $type" -ForegroundColor DarkGray -NoNewline
Write-Host " - $($v.Culture) $($v.Gender)" -ForegroundColor Gray
}
Write-Host ""
$synth.Dispose()
exit 0
}
if (-not $Text) {
Write-Error "需要提供文本。用法:.\tts.ps1 '你的文本'"
Write-Host "使用 -ListVoices 查看可用语音"
$synth.Dispose()
exit 1
}
function Select-BestVoice {
param($voices, $preferredName, $lang)
if ($preferredName) {
$match = $voices | Where-Object { $_.Name -like "*$preferredName*" } | Select-Object -First 1
if ($match) { return $match }
Write-Warning "未找到语音 '$preferredName',正在自动选择..."
}
$cultureMap = @{
"fr" = "fr-FR"; "french" = "fr-FR"
"en" = "en-US"; "english" = "en-US"
"de" = "de-DE"; "german" = "de-DE"
"es" = "es-ES"; "spanish" = "es-ES"
"it" = "it-IT"; "italian" = "it-IT"
}
$targetCulture = $cultureMap[$lang.ToLower()]
if (-not $targetCulture) { $targetCulture = $lang }
$neuralMatch = $voices | Where-Object {
$_.Name -match "Online|Neural" -and $_.Culture.Name -eq $targetCulture
} | Select-Object -First 1
if ($neuralMatch) { return $neuralMatch }
$langMatch = $voices | Where-Object { $_.Culture.Name -eq $targetCulture } | Select-Object -First 1
if ($langMatch) { return $langMatch }
$anyNeural = $voices | Where-Object { $_.Name -match "Online|Neural" } | Select-Object -First 1
if ($anyNeural) { return $anyNeural }
return $voices | Select-Object -First 1
}
$selectedVoice = Select-BestVoice -voices $installedVoices -preferredName $VoiceName -lang $Language
if (-not $selectedVoice) {
Write-Error "未找到 SAPI5 语音!请在 Windows 设置 > 时间和语言 > 语音 中安装语音包"
$synth.Dispose()
exit 1
}
if (-not $Output) {
$ttsDir = "$env:USERPROFILE\.openclaw\workspace\tts"
if (-not (Test-Path $ttsDir)) { New-Item -ItemType Directory -Path $ttsDir -Force | Out-Null }
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$Output = "$ttsDir\sapi_$timestamp.wav"
}
try {
$synth.SelectVoice($selectedVoice.Name)
$synth.Rate = $Rate
$synth.SetOutputToWaveFile($Output)
$synth.Speak($Text)
$synth.SetOutputToNull()
Write-Host "语音:$($selectedVoice.Name) [$($selectedVoice.Culture)]" -ForegroundColor Cyan
Write-Host "MEDIA:$Output"
# 如果请求,自动播放(使用 .NET MediaPlayer,无需外部播放器)
if ($Play) {
Add-Type -AssemblyName PresentationCore
$player = New-Object System.Windows.Media.MediaPlayer
$player.Open([Uri]$Output)
$player.Play()
Start-Sleep -Milliseconds 500
while ($player.Position -lt $player.NaturalDuration.TimeSpan) {
Start-Sleep -Milliseconds 100
}
$player.Close()
}
} catch {
Write-Error "TTS 生成失败:$($_.Exception.Message)"
exit 1
} finally {
$synth.Dispose()
}
# 生成音频文件
.\tts.ps1 "Bonjour, comment vas-tu ?"
# 生成并立即播放
.\tts.ps1 "Bonjour !" -Play
| 参数 | 别名 | 默认值 | 描述 |
|---|---|---|---|
-Text |
(位置参数) | 必需 | 要朗读的文本 |
-VoiceName |
-Voice, -v |
自动选择 | 语音名称(支持部分匹配) |
-Language |
-Lang, -l |
fr | 语言:fr, en, de, es, it... |
-Output |
-o |
自动生成 | 输出 WAV 文件路径 |
-Rate |
-r |
0 | 语速:-10 (慢) 到 +10 (快) |
-Play |
-p |
false | 生成后立即播放音频 |
-ListVoices |
显示已安装的语音列表 |
# 法语,生成后自动播放
.\tts.ps1 "Bonjour !" -Lang fr -Play
# 英语,语速稍快
.\tts.ps1 "Hello there!" -Lang en -Rate 2 -Play
# 指定语音
.\tts.ps1 "Salut !" -Voice "Denise" -Play
# 列出可用语音
.\tts.ps1 -ListVoices
神经语音比传统桌面语音听起来自然得多。
神经语音已内置。前往:
设置 → 时间和语言 → 语音 → 管理语音
如需安装更多神经语音(例如法语 Denise):
-ListVoices 命令验证由 Pocus 🎩 — AI 助手,与 Olive (@Korddie) 共同制作。