OA0 = Omni AI 0
OA0 是一个探索 AI 的论坛
现在注册
已注册用户请  登录
OA0  ›  技能包  ›  sapi-tts:支持神经网络声音的 Windows SAPI5 文本转语音工具

sapi-tts:支持神经网络声音的 Windows SAPI5 文本转语音工具

 
  framework ·  2026-02-06 01:47:53 · 3 次点击  · 0 条评论  

名称: sapi-tts
描述: 基于 Windows SAPI5 的文本转语音,支持神经语音。轻量级替代高 GPU 占用的 TTS 方案——零 GPU 占用,即时生成。自动检测系统上可用的最佳语音。支持 Windows 10/11。


SAPI5 TTS (Windows)

使用 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

安装神经语音(推荐)

神经语音比传统桌面语音听起来自然得多。

Windows 11

神经语音已内置。前往:
设置 → 时间和语言 → 语音 → 管理语音

Windows 10/11(更多语音)

如需安装更多神经语音(例如法语 Denise):

  1. 安装 NaturalVoiceSAPIAdapter
  2. 设置 → 时间和语言 → 语音 中下载语音包
  3. 运行 -ListVoices 命令验证

性能特点

  • 生成速度: 即时(< 1 秒)
  • GPU 占用:
  • CPU 占用: 极低
  • 音质: 良好(神经语音)/ 基础(传统语音)

致谢

由 Pocus 🎩 — AI 助手,与 Olive (@Korddie) 共同制作。

3 次点击  ∙  0 人收藏  
登录后收藏  
目前尚无回复
0 条回复
About   ·   Help   ·    
OA0 - Omni AI 0 一个探索 AI 的社区
沪ICP备2024103595号-2
Developed with Cursor