[Unity安卓封装][C#版]Unity使用TextToSpeech

当你阅读到此篇文章想必对TTS有一定了解。如果不清楚可以查阅TTS文档。

TextToSpeech谷歌文档icon-default.png?t=M4ADhttps://developer.android.google.cn/reference/kotlin/android/speech/tts/TextToSpeech?hl=en

1.封装C#文件

using System;
using UnityEngine;

#if UNITY_ANDROID
/// <summary>
/// 基于AndroidTextToSpeech封装
/// https://developer.android.google.cn/reference/kotlin/android/speech/tts/TextToSpeech?hl=en
/// </summary>
public class AndroidTextToSpeech
{
    /// <summary>
    /// 发生错误
    /// </summary>
    public const int ERROR = -1;
    /// <summary>
    /// 表示由无效请求导致的故障。
    /// </summary>
    public const int ERROR_INVALID_REQUEST = -8;
    /// <summary>
    /// 表示由网络连接问题导致的故障。
    /// </summary>
    public const int ERROR_NETWORK = -6;
    /// <summary>
    /// 表示网络超时导致的故障。
    /// </summary>
    public const int ERROR_NETWORK_TIMEOUT = -7;
    /// <summary>
    /// 表示由于未完成语音数据下载而导致的故障。
    /// </summary>
    public const int ERROR_NOT_INSTALLED_YET = -9;
    /// <summary>
    /// 表示与输出(音频设备或文件)相关的故障。
    /// </summary>
    public const int ERROR_OUTPUT = -5;
    /// <summary>
    /// 表示TTS服务故障。
    /// </summary>
    public const int ERROR_SERVICE = -4;
    /// <summary>
    /// 表示TTS引擎无法合成给定输入。
    /// </summary>
    public const int ERROR_SYNTHESIS = -3;
    /// <summary>
    /// 表示语言可按语言环境使用,但不能按国家和变体使用。
    /// </summary>
    public const int LANG_AVAILABLE = 0;
    /// <summary>
    /// 表示语言适用于语言环境指定的语言和国家,但不适用于变体。
    /// </summary>
    public const int LANG_COUNTRY_AVAILABLE = 1;
    /// <summary>
    /// 表示语言完全按照区域设置的指定可用。
    /// </summary>
    public const int LANG_COUNTRY_VAR_AVAILABLE = 2;
    /// <summary>
    /// 语言数据丢失
    /// </summary>
    public const int LANG_MISSING_DATA = -1;
    /// <summary>
    /// 语言不支持
    /// </summary>
    public const int LANG_NOT_SUPPORTED = -2;
    /// <summary>
    /// 队列模式,其中新条目添加到播放队列的末尾。
    /// </summary>
    public const int QUEUE_ADD = 1;
    /// <summary>
    /// 队列模式,其中删除播放队列中的所有条目(要播放的媒体和要合成的文本),并用新条目替换。
    /// </summary>
    public const int QUEUE_FLUSH = 0;
    /// <summary>
    /// 客户端请求停止
    /// </summary>
    public const int STOPPED = -2;
    /// <summary>
    /// 成功
    /// </summary>
    public const int SUCCESS = 0;
    /// <summary>
    /// Init回调
    /// </summary>
    private Action<int> onInit;
    /// <summary>
    /// 
    /// </summary>
    /// <param name="activity">activity</param>
    /// <param name="engine">tts引擎</param>
    public AndroidTextToSpeech(AndroidJavaObject activity, string engine = null)
    {
        Init(activity, null, engine);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="activity">activity</param>
    /// <param name="initCall">初始化回调</param>
    /// <param name="engine">tts引擎</param>
    public AndroidTextToSpeech(AndroidJavaObject activity,Action<int> initCall = null, string engine = null)
    {
        Init(activity, initCall, engine);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="initCall">初始化回调</param>
    /// <param name="engine">tts引擎</param>
    public AndroidTextToSpeech(Action<int> initCall,string engine = null)
    {
        Init(null, initCall, engine);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="engine">tts引擎</param>
    public AndroidTextToSpeech(string engine=null)
    {
        Init(null, null, engine);
    }

    /// <summary>
    /// 设置音调
    /// </summary>
    /// <param name="pitch">设置音调,值越大声音越尖(女生),值越小则变成男声,1.0是常规</param>
    /// <returns>返回结果SUCCESS或者ERROR</returns>
    public int SetPitch(float pitch)
    {
        return textToSpeechObject.Call<int>("setPitch", pitch);
    }
    /// <summary>
    /// 设置语速
    /// </summary>
    /// <param name="pitch">语速</param>
    /// <returns>返回结果SUCCESS或者ERROR</returns>
    public int SetSpeechRate(float speechRate)
    {
        return textToSpeechObject.Call<int>("setSpeechRate", speechRate);
    }
    /// <summary>
    /// 正在讲话?
    /// </summary>
    /// <returns>True:正在讲话</returns>
    public bool IsSpeaking()
    {
        return textToSpeechObject.Call<bool>("isSpeaking");
    }
    /// <summary>
    /// 设置语言
    /// </summary>
    /// <param name="locale">java.util.Locale 对象</param>
    /// <returns>返回结果SUCCESS或者ERROR</returns>
    public int SetLanguage(AndroidJavaObject locale)
    {
        return textToSpeechObject.Call<int>("setLanguage", locale); 
    }
    /// <summary>
    /// 设置语言
    /// </summary>
    /// <param name="localeString">
    /// java.util.Locale 中应定义的常量名
    /// CHINA;US;等
    /// https://developer.android.google.cn/reference/kotlin/java/util/Locale.html?hl=en
    /// </param>
    /// <returns></returns>
    public int SetLanguage(string localeString)
    {
        return SetLanguage(localeClass.GetStatic<AndroidJavaObject>(localeString));
    }
    /// <summary>
    /// 返回一个语音实例,描述当前用于发送到TextToSpeech引擎的合成请求的语音。
    /// </summary>
    /// <returns></returns>
    public AndroidJavaObject GetVoice()
    {
        return localeClass.GetStatic<AndroidJavaObject>("getVoice");
    }
    /// <summary>
    /// 讲话
    /// </summary>
    /// <param name="text">文字</param>
    /// <param name="queueMode">模式</param>
    /// <param name="utteranceId">唯一标识</param>
    /// <returns>返回结果SUCCESS或者ERROR</returns>
    public int Speak(string text,int queueMode, string utteranceId=null)
    {
        return Speak(text, queueMode,null, utteranceId);
    }
    /// <summary>
    /// 讲话
    /// </summary>
    /// <param name="text">文字</param>
    /// <param name="queueMode">模式</param>
    /// <param name="param">参数,是android.os.Bundle对象</param>
    /// <param name="utteranceId">唯一标识</param>
    /// <returns></returns>
    public int Speak(string text, int queueMode, AndroidJavaObject param,string utteranceId)
    {
        return textToSpeechObject.Call<int>("speak", text, queueMode, param, utteranceId);
    }
    /// <summary>
    /// 停止
    /// </summary>
    /// <returns>返回结果SUCCESS或者ERROR</returns>
    public int Stop()
    {
        return textToSpeechObject.Call<int>("stop"); 
    }
    /// <summary>
    /// 终止
    /// </summary>
    public void Shutdown()
    {
        textToSpeechObject.Call<int>("shutdown"); 
    }

    /// <summary>
    /// 初始化
    /// </summary>
    /// <param name="activity"></param>
    /// <param name="initCall"></param>
    /// <param name="engine"></param>
    private void Init(AndroidJavaObject activity,Action<int> initCall,string engine)
    {
        onInit = initCall;
        if (activity == null)
        {
            activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
        }
        if (!string.IsNullOrEmpty(engine))
        {
            textToSpeechObject = new AndroidJavaObject("android.speech.tts.TextToSpeech", activity, new OnInitListener(this), engine);
        }
        else
        {
            textToSpeechObject = new AndroidJavaObject("android.speech.tts.TextToSpeech", activity, new OnInitListener(this));
        }
        localeClass = new AndroidJavaClass("java.util.Locale");
    }

    /// <summary>
    /// textToSpeech对象
    /// </summary>
    private AndroidJavaObject textToSpeechObject;
    /// <summary>
    /// locale类映射
    /// </summary>
    private AndroidJavaClass localeClass;

    /// <summary>
    /// 用于处理TextToSpeech中OnInitListener监听回调代理
    /// </summary>
    private class OnInitListener : AndroidJavaProxy
    {
        private AndroidTextToSpeech androidTextToSpeech;
        public OnInitListener(AndroidTextToSpeech androidTextToSpeech) : base("android.speech.tts.TextToSpeech$OnInitListener")
        {
            this.androidTextToSpeech = androidTextToSpeech;
        }

        /// <summary>
        /// 初始化结果处理
        /// </summary>
        /// <param name="state"></param>
        void onInit(int state)
        {
            androidTextToSpeech.OnInit(state);
        }
    }

    private void OnInit(int state)
    {
        onInit?.Invoke(state);
    }
}
#endif

2.使用

如果是Android 11+需要在AndroidManifest.xml中的manifest节点下填入queries信息如下(这里要与application节点同级):

	<queries>
		<intent>
			<action android:name="android.intent.action.TTS_SERVICE" />
		</intent>
	</queries>

测试

using UnityEngine;
using UnityEngine.UI;

public class TTSTest : MonoBehaviour
{
    public Text Tip;

    public InputField InputField;

    AndroidTextToSpeech AndroidTextToSpeech;
    void Start()
    {
        AndroidTextToSpeech = new AndroidTextToSpeech((state)=> {
            
            if (state == AndroidTextToSpeech.SUCCESS)
            {
                Tip.text += "启动成功\n";
                int res = AndroidTextToSpeech.SetLanguage("CHINA");
                if (res == AndroidTextToSpeech.LANG_MISSING_DATA)
                {
                    Tip.text += "语言数据丢失\n";
                }
                else if (res == AndroidTextToSpeech.LANG_NOT_SUPPORTED)
                {
                    Tip.text += "语言不支持\n";
                }
            }
        });
        AndroidTextToSpeech.SetPitch(1);
        AndroidTextToSpeech.SetSpeechRate(0.5f);
    }
    public void Speak()
    {
        if (!string.IsNullOrEmpty(InputField.text) && !AndroidTextToSpeech.IsSpeaking())
        {
            AndroidTextToSpeech.Speak(InputField.text, AndroidTextToSpeech.QUEUE_FLUSH);
        }
    }
    private void OnDestroy()
    {
        AndroidTextToSpeech.Stop();
        AndroidTextToSpeech.Shutdown();
    }
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值