You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C#中如何捕获Microsoft.CognitiveServices.Speech.SpeechSynthesizer发音完成时机

实现SpeechSynthesizer的状态监听与合成完成事件处理

一、注册SynthesisCompleted事件

SpeechSynthesizer.SynthesisCompleted事件会在语音合成任务完成(无论成功或失败)时触发,只需在初始化合成器后绑定事件处理方法即可:

  1. 初始化SpeechSynthesizer实例后,通过+=关联事件处理逻辑;
  2. 在事件处理方法中编写合成完成后的操作,比如更新状态、触发后续任务。

二、跟踪发音状态

SpeechSynthesizer没有直接提供IsSpeaking属性,你可以通过自定义字段结合事件和异步任务状态来维护:

  • 启动合成前将自定义状态字段设为true;
  • 在SynthesisCompleted事件或异步任务完成后将字段设为false;
  • 后台线程定期检查该字段值即可获取当前是否正在发音。

完整示例代码

using Microsoft.CognitiveServices.Speech;
using System;
using System.Threading;
using System.Threading.Tasks;

class SpeechSynthesisDemo
{
    // 自定义状态字段:标记是否正在发音
    private static bool _isSpeaking;
    private static SpeechSynthesizer _synthesizer;

    static async Task Main(string[] args)
    {
        // 替换为你的Azure语音服务订阅密钥和区域
        var speechConfig = SpeechConfig.FromSubscription("YOUR_SUBSCRIPTION_KEY", "YOUR_REGION");
        _synthesizer = new SpeechSynthesizer(speechConfig);

        // 注册合成完成事件
        _synthesizer.SynthesisCompleted += OnSynthesisCompleted;

        // 启动后台线程,定期检查发音状态
        var statusMonitorThread = new Thread(MonitorSpeakingStatus) { IsBackground = true };
        statusMonitorThread.Start();

        // 执行文本转语音异步任务
        string textToSpeak = "这是一段用于测试的文本转语音内容。";
        _isSpeaking = true;
        var synthesisResult = await _synthesizer.SpeakTextAsync(textToSpeak);

        // 也可以通过Task结果直接判断合成状态
        if (synthesisResult.Reason == ResultReason.SynthesizingAudioCompleted)
        {
            Console.WriteLine("合成任务完成(通过Task结果检测)");
        }
        else if (synthesisResult.Reason == ResultReason.Canceled)
        {
            var cancellationDetails = SpeechSynthesisCancellationDetails.FromResult(synthesisResult);
            Console.WriteLine($"合成被取消:{cancellationDetails.Reason}");
            if (cancellationDetails.Reason == CancellationReason.Error)
            {
                Console.WriteLine($"错误信息:{cancellationDetails.ErrorDetails}");
            }
            _isSpeaking = false;
        }

        Console.ReadLine();
        _synthesizer.Dispose();
    }

    // 合成完成事件处理方法
    private static void OnSynthesisCompleted(object sender, SynthesisEventArgs e)
    {
        _isSpeaking = false;
        Console.WriteLine("合成任务完成(通过SynthesisCompleted事件触发)");
        // 这里可以添加自定义逻辑,比如通知其他模块、记录日志等
    }

    // 后台线程状态监控逻辑
    private static void MonitorSpeakingStatus()
    {
        while (true)
        {
            Thread.Sleep(1000);
            Console.WriteLine($"当前发音状态:{(_isSpeaking ? "正在发音" : "未发音")}");
        }
    }
}

关键说明

  • 事件注册时机:必须在调用SpeakTextAsync之前完成事件绑定,否则可能无法捕获合成完成事件;
  • UI线程注意:如果是WPF/WinForms等UI应用,在事件处理方法中更新UI时需要切换到UI线程(比如WPF用Dispatcher.Invoke,WinForms用Control.Invoke);
  • 资源释放:使用完SpeechSynthesizer后务必调用Dispose()释放资源,避免内存泄漏。

内容的提问来源于stack exchange,提问作者CodeMilian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 21:35:27