C#分享辅助类:朗读文本或生成语音(VoiceHandler)

30 篇文章 1 订阅

名称

方法

朗读声音,播放声音

PlaySound

播放音频文件

PlayWav

保存声音文件

SaveSound

释放资源

Dispose

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Runtime.InteropServices;
using System.Threading;

namespace Wsfly
{
    public class VoiceHandler
    {
        const int SpFlags = 1;                          //SpeechVoiceSpeakFlags.SVSFlagsAsyn

        static object _spVoiceCls = null;               //保存朗读用的 SAPI.SpVoice 
        static object _oISpeechObjectTokens = null;     //保存 SAPI.ISpeechObjectTokens 就是系统有的语音引擎集合
        static int _tokensCount = 0;                    //语音引擎集合数
        public static DictionaryEntry[] _deTokens = null;   //语音模块
        static string _currentTokenName = null;             //当前语音模块名称

        /// <summary>
        /// 当前语音模块
        /// </summary>
        public static object CurrentToken
        {
            get
            {
                //未设置播放语音模块 使用默认
                if (string.IsNullOrWhiteSpace(_currentTokenName)) return _deTokens[0];

                //循环得到名称
                foreach (DictionaryEntry entry in _deTokens)
                {
                    if (entry.Key.ToString() == _currentTokenName)
                    {
                        return entry;
                    }
                }

                //返回默认
                return _deTokens[0];
            }
            set
            {
                //当前语音模块
                _currentTokenName = value.ToString();
            }
        }

        //是否初始化
        static bool isInit = false;

        /// <summary>
        /// 初始化
        /// </summary>
        private VoiceHandler()
        {
            InitSAPI();
            isInit = true;
        }
        /// <summary>
        /// 初始化 API
        /// </summary>
        public static void InitSAPI()
        {
            //如果已经初始化 则退出
            if (isInit) return;

            //创建语音对象朗读用
            _spVoiceCls = ComHandler.CreateComObject("SAPI.SpVoice");

            if (_spVoiceCls == null)
            {
                throw new Exception("您还未安装微软语音插件!");
            }
            else
            {
                //取得所有的 识别对象模块集合
                //取得SAPI.ISpeechObjectTokens
                _oISpeechObjectTokens = ComHandler.CallComMethod("GetVoices", _spVoiceCls);

                //识别对象集合 Count;
                object r = ComHandler.GetComPropery("Count", _oISpeechObjectTokens);
                if (r is int)
                {
                    //语言数量
                    _tokensCount = (int)r;

                    //有语言模块
                    if (_tokensCount > 0)
                    {
                        //取得全部语音识别对象模块,及名称,以被以后使用
                        _deTokens = new DictionaryEntry[_tokensCount];
                        for (int i = 0; i < _tokensCount; i++)
                        {
                            //从集合中取出单个 识别对象模块
                            object oSpObjectToken = ComHandler.CallComMethod("Item", _oISpeechObjectTokens, i); //返回 SAPI.SpObjectToken
                            //取名称
                            string name = ComHandler.CallComMethod("GetDescription", oSpObjectToken) as string;
                            //放到 DictionaryEntry 对象中,key 是 名称, value 是 识别对象模块
                            _deTokens[i] = new DictionaryEntry(name, oSpObjectToken);

                        }
                    }
                }
            }
        }
        /// <summary>
        /// 朗读声音,播放声音
        /// </summary>
        /// <param name="msg"></param>
        public static void PlaySound(string msg, int rate = 0, int volume = 100)
        {
            ///初始化
            if (!isInit) { new VoiceHandler(); }

            try
            {
                if (_spVoiceCls != null)
                {
                    //设置语言引擎
                    ComHandler.SetComProperty("Voice", _spVoiceCls, ((DictionaryEntry)CurrentToken).Value);
                    ComHandler.SetComProperty("Rate", _spVoiceCls, rate);
                    ComHandler.SetComProperty("Volume", _spVoiceCls, volume);
                    //调用Speak 函数,msg 是要播放的文本,1 是异步播放,因为是异步的 com 对象不立刻释放
                    ComHandler.CallComMethod("Speak", _spVoiceCls, msg, SpFlags);
                }
            }
            catch (Exception ex)
            {

            }
        }
        /// <summary>
        /// 播放音频文件
        /// </summary>
        /// <param name="stream"></param>
        public static void PlayWav(System.IO.Stream stream)
        {
            System.Media.SoundPlayer player = new System.Media.SoundPlayer(stream);
            player.Play();
        }
        /// <summary>
        /// 保存声音文件
        /// </summary>
        /// <param name="msg">播放的语音</param>
        /// <param name="fileName">保存路径</param>
        /// <param name="rate">语速</param>
        /// <param name="volume">音量</param>
        public static void SaveSound(string msg, string fileName, int rate = 0, int volume = 100)
        {
            int SpFileMode = 3;
            object oSpFileStream = ComHandler.CreateComObject("SAPI.SpFileStream"); //创建 SAPI.SpFileStream
            object oSpVoice = ComHandler.CreateComObject("SAPI.SpVoice"); //创建 SAPI.SpVoice

            try
            {
                ComHandler.CallComMethod("Open", oSpFileStream, fileName, SpFileMode, false); //打开流
                ComHandler.SetComProperty("Voice", oSpVoice, ((DictionaryEntry)CurrentToken).Value); //设置 Voice 属性,让谁朗读
                ComHandler.SetComProperty("Rate", oSpVoice, rate);
                ComHandler.SetComProperty("Volume", oSpVoice, volume);
                ComHandler.SetComProperty("AudioOutputStream", oSpVoice, oSpFileStream); //设置流

                ComHandler.CallComMethod("Speak", oSpVoice, msg, SpFlags); //调用 Speak

                ComHandler.CallComMethod("WaitUntilDone", oSpVoice, Timeout.Infinite); //等
                ComHandler.CallComMethod("Close", oSpFileStream); //关闭流
            }
            finally
            {
                Marshal.ReleaseComObject(oSpVoice);
                Marshal.ReleaseComObject(oSpFileStream);
            }
        }
        /// <summary>
        /// 释放资源
        /// </summary>
        public static void Dispose()
        {
            //释放com对象
            Marshal.ReleaseComObject(_spVoiceCls);
            //标记未初始化
            isInit = false;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MOZ-Soft

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值