初始版本
优化版本
优化内容:
- 原始版本使用NativeWebSocket插件,无法获取X-Tt-Logid,使用WebSocketSharp插件解决这个问题
- 提取两个插件的共性,可依据需要替换
示例
通信类
websocket通信基类
1using UnityEngine; 2using System; 3/// <summary> 4/// 文字转语音 5/// </summary> 6public abstract class BaseTextToSpeech : MonoBehaviour 7{ 8 public event Action OnConnectWeb; 9 public event Action OnConnectTTSSucess; 10 11 public event Action OnCreateSessionSucess; 12 public event Action OnSessionFinished; 13 14 public event Action OnSentenceStart; 15 public event Action OnSentenceEnd; 16 17 public event Action<byte[]> OnReceiveAudio; 18 19 public abstract void WebSocketConnect(); 20 21 public abstract void WebSocketDisconnect(); 22 23 public abstract void BeginConnectTTS(); 24 25 public abstract void BeginSession(); 26 27 public abstract void Session(string info); 28 29 public abstract void EndSession(); 30 31 public abstract void EndConnectTTS(); 32 33 protected void InvokeConnectWeb() 34 { 35 OnConnectWeb?.Invoke(); 36 } 37 protected void InvokeConnectTTSSucess() 38 { 39 OnConnectTTSSucess?.Invoke(); 40 } 41 protected void InvokeCreateSessionSucess() 42 { 43 OnCreateSessionSucess?.Invoke(); 44 } 45 protected void InvokeSessionFinished() 46 { 47 OnSessionFinished?.Invoke(); 48 } 49 protected void InvokeSentenceStart() 50 { 51 OnSentenceStart?.Invoke(); 52 } 53 protected void InvokeSentenceEnd() 54 { 55 OnSentenceEnd?.Invoke(); 56 } 57 protected void InvokeReceiveAudio(byte[] data) 58 { 59 OnReceiveAudio?.Invoke(data); 60 } 61} 62
使用NativeWebSocket插件
1using UnityEngine; 2using NativeWebSocket; 3using System; 4using System.Collections.Generic; 5/// <summary> 6/// 文字转语音 7/// NativeSocket 8/// </summary> 9public class TextToSpeech : BaseTextToSpeech 10{ 11 string wss = "wss://openspeech.bytedance.com/api/v3/tts/bidirection"; 12 string XApiAppId = ""; 13 string XApiAccessKey = ""; 14 string XApiResourceId = "seed-tts-2.0"; 15 [Header("发音人")] 16 [SerializeField] string speaker = "zh_female_vv_uranus_bigtts"; 17 [Header("采样率")] 18 [SerializeField] int sampleRate = 24000; 19 20 WebSocket webSocket; 21 string currentSessionId = null; 22 23 public override async void WebSocketConnect() 24 { 25 //请求参数 26 var id = Guid.NewGuid().ToString(); 27 28 //请求头 29 var headers = new Dictionary<string, string>(); 30 headers.Add("X-Api-App-Key", XApiAppId); 31 headers.Add("X-Api-Access-Key", XApiAccessKey); 32 headers.Add("X-Api-Resource-Id", XApiResourceId); 33 headers.Add("X-Api-Connect-Id", id); 34 35 //回调注册 36 webSocket = new WebSocket(wss, headers); 37 webSocket.OnError += OnWebSocketError; 38 webSocket.OnClose += OnWebSocketClose; 39 webSocket.OnOpen += OnWebSocketOpen; 40 webSocket.OnMessage += OnReceiveWebSocketMessage; 41 42 await webSocket.Connect(); 43 } 44 45 public override async void WebSocketDisconnect() 46 { 47 if (webSocket != null) 48 { 49 webSocket.OnError -= OnWebSocketError; 50 webSocket.OnClose -= OnWebSocketClose; 51 webSocket.OnOpen -= OnWebSocketOpen; 52 webSocket.OnMessage -= OnReceiveWebSocketMessage; 53 try 54 { 55 await webSocket.Close(); 56 } 57 catch (System.Exception e) 58 { 59 Debug.LogError(e.Message); 60 } 61 } 62 webSocket = null; 63 } 64 65 public override void BeginConnectTTS() 66 { 67 var msg = new Speech.Protocols.Message 68 { 69 MsgType = Speech.Protocols.MsgType.FullClientRequest, 70 MsgTypeFlag = Speech.Protocols.MsgTypeFlagBits.WithEvent, 71 EventType = Speech.Protocols.EventType.StartConnection, 72 Payload = System.Text.Encoding.UTF8.GetBytes("{}"), 73 }; 74 Send(msg.Marshal()); 75 } 76 77 public override void BeginSession() 78 { 79 currentSessionId = Guid.NewGuid().ToString(); 80 var payload = new SessionPayload 81 { 82 user = new UserInfo { uid = Guid.NewGuid().ToString() }, 83 @event = (int)Speech.Protocols.EventType.StartSession, 84 req_params = new ReqParams 85 { 86 speaker = speaker, 87 text = "", 88 audio_params = new AudioParams 89 { 90 format = "pcm", 91 sample_rate = sampleRate 92 }, 93 } 94 }; 95 string json = JsonUtility.ToJson(payload); 96 byte[] payloadBytes = System.Text.Encoding.UTF8.GetBytes(json); 97 98 var msg = new Speech.Protocols.Message 99 { 100 MsgType = Speech.Protocols.MsgType.FullClientRequest, 101 MsgTypeFlag = Speech.Protocols.MsgTypeFlagBits.WithEvent, 102 EventType = Speech.Protocols.EventType.StartSession, 103 SessionId = currentSessionId, 104 Payload = payloadBytes 105 }; 106 Send(msg.Marshal()); 107 } 108 109 public override void Session(string info) 110 { 111 var taskRequest = new SessionPayload(); 112 taskRequest.req_params = new ReqParams(); 113 taskRequest.req_params.audio_params = new AudioParams 114 { 115 format = "pcm", 116 sample_rate = 24000 117 }; 118 taskRequest.req_params.addtions = new Addtions() 119 { 120 disable_markdown_filter = true, 121 }; 122 taskRequest.req_params.text = info; 123 taskRequest.user = new UserInfo() { uid = Guid.NewGuid().ToString() }; 124 taskRequest.@event = (int)Speech.Protocols.EventType.TaskRequest; 125 126 string json = JsonUtility.ToJson(taskRequest); 127 byte[] payloadBytes = System.Text.Encoding.UTF8.GetBytes(json); 128 var msg = new Speech.Protocols.Message 129 { 130 MsgType = Speech.Protocols.MsgType.FullClientRequest, 131 MsgTypeFlag = Speech.Protocols.MsgTypeFlagBits.WithEvent, 132 EventType = Speech.Protocols.EventType.TaskRequest, 133 SessionId = currentSessionId, 134 Payload = payloadBytes 135 }; 136 Send(msg.Marshal()); 137 } 138 139 public override void EndSession() 140 { 141 byte[] payloadBytes = System.Text.Encoding.UTF8.GetBytes("{}"); 142 var msg = new Speech.Protocols.Message 143 { 144 MsgType = Speech.Protocols.MsgType.FullClientRequest, 145 MsgTypeFlag = Speech.Protocols.MsgTypeFlagBits.WithEvent, 146 EventType = Speech.Protocols.EventType.FinishSession, 147 SessionId = currentSessionId, 148 Payload = payloadBytes 149 }; 150 Send(msg.Marshal()); 151 } 152 153 public override void EndConnectTTS() 154 { 155 byte[] payloadBytes = System.Text.Encoding.UTF8.GetBytes("{}"); 156 var msg = new Speech.Protocols.Message 157 { 158 MsgType = Speech.Protocols.MsgType.FullClientRequest, 159 MsgTypeFlag = Speech.Protocols.MsgTypeFlagBits.WithEvent, 160 EventType = Speech.Protocols.EventType.FinishConnection, 161 Payload = payloadBytes 162 }; 163 Send(msg.Marshal()); 164 } 165 166 void OnWebSocketError(string info) 167 { 168 Debug.LogError("错误信息:" + info); 169 } 170 171 void OnWebSocketClose(WebSocketCloseCode closeCode) 172 { 173 Debug.Log("关闭:" + closeCode); 174 } 175 176 void OnWebSocketOpen() 177 { 178 InvokeConnectWeb(); 179 } 180 181 void OnReceiveWebSocketMessage(byte[] data) 182 { 183 try 184 { 185 var msg = Speech.Protocols.Message.FromBytes(data); 186 Debug.Log($"接收语音合成消息:{msg.MsgType},{msg.EventType},{msg.Payload.Length}"); 187 //接受音频数据 188 if (msg.MsgType == Speech.Protocols.MsgType.AudioOnlyServer) 189 { 190 Debug.Log("接收到音频消息"); 191 if (msg.Payload != null && msg.Payload.Length > 0) 192 { 193 Debug.Log("音频数据回调"); 194 //OnReceiveAuido?.Invoke(msg.Payload); 195 InvokeReceiveAudio(msg.Payload); 196 } 197 } 198 199 if (msg.MsgType == Speech.Protocols.MsgType.Error) 200 { 201 string reason = msg.Payload.Length > 0 202 ? System.Text.Encoding.UTF8.GetString(msg.Payload) 203 : "未知错误"; 204 Debug.LogError($"{msg.EventType}: {reason}"); 205 } 206 207 switch (msg.EventType) 208 { 209 case Speech.Protocols.EventType.ConnectionStarted: 210 //Debug.Log("连接成功,可以发送 StartSession"); 211 InvokeConnectTTSSucess(); 212 break; 213 case Speech.Protocols.EventType.SessionStarted: 214 //Debug.Log("会话已启动,可以发送 TaskRequest"); 215 InvokeCreateSessionSucess(); 216 break; 217 case Speech.Protocols.EventType.SessionFinished: 218 //Debug.Log("会话结束"); 219 InvokeSessionFinished(); 220 break; 221 case Speech.Protocols.EventType.TTSSentenceStart: 222 InvokeSentenceStart();//句子开始 223 break; 224 case Speech.Protocols.EventType.TTSSentenceEnd: 225 InvokeSentenceEnd();//句子结束 226 break; 227 case Speech.Protocols.EventType.ConnectionFailed: 228 case Speech.Protocols.EventType.SessionFailed: 229 string reason = msg.Payload.Length > 0 230 ? System.Text.Encoding.UTF8.GetString(msg.Payload) 231 : "未知错误"; 232 Debug.LogError($"{msg.EventType}: {reason}"); 233 break; 234 } 235 } 236 catch (Exception e) 237 { 238 Debug.LogError("接受消息:" + e.Message); 239 } 240 } 241 242 async void Send(byte[] bytes) 243 { 244 if (webSocket.State == WebSocketState.Open) 245 await webSocket.Send(bytes); 246 } 247 248 [System.Serializable] 249 public class SessionPayload 250 { 251 public UserInfo user; 252 public int @event; 253 public ReqParams req_params; 254 } 255 256 [System.Serializable] 257 public class UserInfo 258 { 259 public string uid; 260 } 261 262 [System.Serializable] 263 public class ReqParams 264 { 265 public string speaker; 266 public string text; // 可选,可以先不填或空字符串 267 public AudioParams audio_params; 268 public Addtions addtions; 269 } 270 271 [System.Serializable] 272 public class AudioParams 273 { 274 public string format; 275 public int sample_rate; 276 } 277 278 [System.Serializable] 279 public class Addtions 280 { 281 public bool disable_markdown_filter = true; 282 } 283} 284
使用WebSocketSharp插件
1using UnityEngine; 2using System; 3using WebSocketSharp; 4/// <summary> 5/// 文字转语音 6/// websocket-sharp 7/// </summary> 8public class TextToSpeechSharp : BaseTextToSpeech 9{ 10 string wss = "wss://openspeech.bytedance.com/api/v3/tts/bidirection"; 11 string XApiAppId = ""; 12 string XApiAccessKey = ""; 13 string XApiResourceId = "seed-tts-2.0"; 14 [Header("发音人")] 15 [SerializeField] string speaker = "zh_female_vv_uranus_bigtts"; 16 [Header("采样率")] 17 [SerializeField] int sampleRate = 24000; 18 19 WebSocket webSocket; 20 string currentSessionId = null; 21 22 public override void WebSocketConnect() 23 { 24 //请求参数 25 var id = Guid.NewGuid().ToString(); 26 27 //回调注册 28 webSocket = new WebSocket(wss); 29 //请求头 30 webSocket.SetUserHeader("X-Api-App-Key", XApiAppId); 31 webSocket.SetUserHeader("X-Api-Access-Key", XApiAccessKey); 32 webSocket.SetUserHeader("X-Api-Resource-Id", XApiResourceId); 33 webSocket.SetUserHeader("X-Api-Connect-Id", id); 34 35 webSocket.OnError += OnWebSocketError; 36 webSocket.OnClose += OnWebSocketClose; 37 webSocket.OnOpen += OnWebSocketOpen; 38 webSocket.OnMessage += OnReceiveWebSocketMessage; 39 40 webSocket.Connect(); 41 } 42 43 public override void WebSocketDisconnect() 44 { 45 if (webSocket != null) 46 { 47 webSocket.OnError -= OnWebSocketError; 48 webSocket.OnClose -= OnWebSocketClose; 49 webSocket.OnOpen -= OnWebSocketOpen; 50 webSocket.OnMessage -= OnReceiveWebSocketMessage; 51 try 52 { 53 webSocket.Close(); 54 } 55 catch (System.Exception e) 56 { 57 Debug.LogError(e.Message); 58 } 59 } 60 webSocket = null; 61 } 62 63 public override void BeginConnectTTS() 64 { 65 var msg = new Speech.Protocols.Message 66 { 67 MsgType = Speech.Protocols.MsgType.FullClientRequest, 68 MsgTypeFlag = Speech.Protocols.MsgTypeFlagBits.WithEvent, 69 EventType = Speech.Protocols.EventType.StartConnection, 70 Payload = System.Text.Encoding.UTF8.GetBytes("{}"), 71 }; 72 Send(msg.Marshal()); 73 } 74 75 public override void BeginSession() 76 { 77 currentSessionId = Guid.NewGuid().ToString(); 78 var payload = new SessionPayload 79 { 80 user = new UserInfo { uid = Guid.NewGuid().ToString() }, 81 @event = (int)Speech.Protocols.EventType.StartSession, 82 req_params = new ReqParams 83 { 84 speaker = speaker, 85 text = "", 86 audio_params = new AudioParams 87 { 88 format = "pcm", 89 sample_rate = sampleRate 90 }, 91 } 92 }; 93 string json = JsonUtility.ToJson(payload); 94 byte[] payloadBytes = System.Text.Encoding.UTF8.GetBytes(json); 95 96 var msg = new Speech.Protocols.Message 97 { 98 MsgType = Speech.Protocols.MsgType.FullClientRequest, 99 MsgTypeFlag = Speech.Protocols.MsgTypeFlagBits.WithEvent, 100 EventType = Speech.Protocols.EventType.StartSession, 101 SessionId = currentSessionId, 102 Payload = payloadBytes 103 }; 104 Send(msg.Marshal()); 105 } 106 107 public override void Session(string info) 108 { 109 var taskRequest = new SessionPayload(); 110 taskRequest.req_params = new ReqParams(); 111 taskRequest.req_params.audio_params = new AudioParams 112 { 113 format = "pcm", 114 sample_rate = 24000 115 }; 116 taskRequest.req_params.addtions = new Addtions() 117 { 118 disable_markdown_filter = true, 119 }; 120 taskRequest.req_params.text = info; 121 taskRequest.user = new UserInfo() { uid = Guid.NewGuid().ToString() }; 122 taskRequest.@event = (int)Speech.Protocols.EventType.TaskRequest; 123 124 string json = JsonUtility.ToJson(taskRequest); 125 byte[] payloadBytes = System.Text.Encoding.UTF8.GetBytes(json); 126 var msg = new Speech.Protocols.Message 127 { 128 MsgType = Speech.Protocols.MsgType.FullClientRequest, 129 MsgTypeFlag = Speech.Protocols.MsgTypeFlagBits.WithEvent, 130 EventType = Speech.Protocols.EventType.TaskRequest, 131 SessionId = currentSessionId, 132 Payload = payloadBytes 133 }; 134 Send(msg.Marshal()); 135 } 136 137 public override void EndSession() 138 { 139 byte[] payloadBytes = System.Text.Encoding.UTF8.GetBytes("{}"); 140 var msg = new Speech.Protocols.Message 141 { 142 MsgType = Speech.Protocols.MsgType.FullClientRequest, 143 MsgTypeFlag = Speech.Protocols.MsgTypeFlagBits.WithEvent, 144 EventType = Speech.Protocols.EventType.FinishSession, 145 SessionId = currentSessionId, 146 Payload = payloadBytes 147 }; 148 Send(msg.Marshal()); 149 } 150 151 public override void EndConnectTTS() 152 { 153 byte[] payloadBytes = System.Text.Encoding.UTF8.GetBytes("{}"); 154 var msg = new Speech.Protocols.Message 155 { 156 MsgType = Speech.Protocols.MsgType.FullClientRequest, 157 MsgTypeFlag = Speech.Protocols.MsgTypeFlagBits.WithEvent, 158 EventType = Speech.Protocols.EventType.FinishConnection, 159 Payload = payloadBytes 160 }; 161 Send(msg.Marshal()); 162 } 163 164 void OnWebSocketError(object sender, ErrorEventArgs args) 165 { 166 Debug.LogError("错误信息:" + args.Message); 167 } 168 169 void OnWebSocketClose(object sender, CloseEventArgs args) 170 { 171 Debug.Log("关闭:" + args.Code); 172 } 173 174 void OnWebSocketOpen(object sender, EventArgs args) 175 { 176 var headers = webSocket.HandshakeResponseHeaders; 177 Debug.Log(("X-Tt-Logid",headers["X-Tt-Logid"])); 178 InvokeConnectWeb(); 179 } 180 181 void OnReceiveWebSocketMessage(object sender, MessageEventArgs args) 182 { 183 try 184 { 185 var msg = Speech.Protocols.Message.FromBytes(args.RawData); 186 Debug.Log($"接收语音合成消息:{msg.MsgType},{msg.EventType},{msg.Payload.Length}"); 187 //接受音频数据 188 if (msg.MsgType == Speech.Protocols.MsgType.AudioOnlyServer) 189 { 190 Debug.Log("接收到音频消息"); 191 if (msg.Payload != null && msg.Payload.Length > 0) 192 { 193 Debug.Log("音频数据回调"); 194 //OnReceiveAuido?.Invoke(msg.Payload); 195 InvokeReceiveAudio(msg.Payload); 196 } 197 } 198 199 if (msg.MsgType == Speech.Protocols.MsgType.Error) 200 { 201 string reason = msg.Payload.Length > 0 202 ? System.Text.Encoding.UTF8.GetString(msg.Payload) 203 : "未知错误"; 204 Debug.LogError($"{msg.EventType}: {reason}"); 205 } 206 207 switch (msg.EventType) 208 { 209 case Speech.Protocols.EventType.ConnectionStarted: 210 //Debug.Log("连接成功,可以发送 StartSession"); 211 InvokeConnectTTSSucess(); 212 break; 213 case Speech.Protocols.EventType.SessionStarted: 214 //Debug.Log("会话已启动,可以发送 TaskRequest"); 215 InvokeCreateSessionSucess(); 216 break; 217 case Speech.Protocols.EventType.SessionFinished: 218 //Debug.Log("会话结束"); 219 InvokeSessionFinished(); 220 break; 221 case Speech.Protocols.EventType.TTSSentenceStart: 222 InvokeSentenceStart();//句子开始 223 break; 224 case Speech.Protocols.EventType.TTSSentenceEnd: 225 InvokeSentenceEnd();//句子结束 226 break; 227 case Speech.Protocols.EventType.ConnectionFailed: 228 case Speech.Protocols.EventType.SessionFailed: 229 string reason = msg.Payload.Length > 0 230 ? System.Text.Encoding.UTF8.GetString(msg.Payload) 231 : "未知错误"; 232 Debug.LogError($"{msg.EventType}: {reason}"); 233 break; 234 } 235 } 236 catch (Exception e) 237 { 238 Debug.LogError("接受消息:" + e.Message); 239 } 240 } 241 242 void Send(byte[] bytes) 243 { 244 if (webSocket.ReadyState == WebSocketState.Open) 245 webSocket.Send(bytes); 246 } 247 248 [System.Serializable] 249 public class SessionPayload 250 { 251 public UserInfo user; 252 public int @event; 253 public ReqParams req_params; 254 } 255 256 [System.Serializable] 257 public class UserInfo 258 { 259 public string uid; 260 } 261 262 [System.Serializable] 263 public class ReqParams 264 { 265 public string speaker; 266 public string text; // 可选,可以先不填或空字符串 267 public AudioParams audio_params; 268 public Addtions addtions; 269 } 270 271 [System.Serializable] 272 public class AudioParams 273 { 274 public string format; 275 public int sample_rate; 276 } 277 278 [System.Serializable] 279 public class Addtions 280 { 281 public bool disable_markdown_filter = true; 282 } 283} 284
语音合成流程类
连接TTS服务器成功后,不需要立即创建会话。
1using System.Text; 2using UnityEngine; 3 4public class TextToSpeechOut : MonoBehaviour 5{ 6 [Header("文字合成语音")] 7 [SerializeField] BaseTextToSpeech textToSpeech; 8 9 [Header("TTS音频流播放")] 10 [SerializeField] TTSAudioStreamPlay tTSAudioStreamPlay; 11 12 bool hasSession = false;//会话存在 13 bool isCreateSession;//创建会话 14 StringBuilder sentenceBuffer;//缓存文本 15 16 bool receivedAudioData = false; 17 bool requestEndSession = false; 18 float endSessionTimer = 0; 19 [Header("结束会话等待时间")] 20 [SerializeField] float endSessionRequestTime = 2f; 21 22 23 void Awake() 24 { 25 tTSAudioStreamPlay.CreateAudioStream(); 26 sentenceBuffer = new StringBuilder(); 27 textToSpeech.OnConnectWeb += OnConnectWeb; 28 textToSpeech.OnConnectTTSSucess += OnConnectTTSSucess; 29 textToSpeech.OnCreateSessionSucess += OnCreateSession; 30 textToSpeech.OnSessionFinished += OnSessionFinish; 31 textToSpeech.OnReceiveAudio += OnReceiveData; 32 textToSpeech.WebSocketConnect(); 33 } 34 35 void OnDestroy() 36 { 37 tTSAudioStreamPlay.ReleaseAudioStream(); 38 textToSpeech.OnConnectWeb -= OnConnectWeb; 39 textToSpeech.OnConnectTTSSucess -= OnConnectTTSSucess; 40 textToSpeech.OnCreateSessionSucess -= OnCreateSession; 41 textToSpeech.OnSessionFinished -= OnSessionFinish; 42 textToSpeech.OnReceiveAudio -= OnReceiveData; 43 textToSpeech.WebSocketDisconnect(); 44 } 45 46 void OnConnectWeb() 47 { 48 Debug.Log("连接服务器成功,开始连接TTS"); 49 textToSpeech.BeginConnectTTS(); 50 } 51 52 void OnConnectTTSSucess() 53 { 54 Debug.Log("连接TTS成功"); 55 //避免重复建立会话 56 //5s内不发送文本,服务器不返回音频数据,超出5s,再次发送也不会返回音频数据 57 //会话10s内有效,不提前建立会话,需要时建立 58 // if (hasSession == false && isCreateSession == false) 59 // { 60 // isCreateSession = true; 61 // //请求建立会话 62 // textToSpeech.BeginSession(); 63 // } 64 } 65 66 void OnCreateSession() 67 { 68 Debug.Log("建立会话成功"); 69 hasSession = true; 70 isCreateSession = false; 71 72 // 重置所有会话状态 73 receivedAudioData = false; 74 requestEndSession = false; 75 endSessionTimer = 0f; 76 77 //发送缓存内容 78 if (sentenceBuffer.Length > 0) 79 { 80 var content = sentenceBuffer.ToString(); 81 sentenceBuffer.Clear(); 82 Debug.Log("Send TaskRequest: " + content); 83 textToSpeech.Session(content); 84 } 85 } 86 87 void OnSessionFinish() 88 { 89 Debug.Log("会话结束"); 90 hasSession = false; 91 isCreateSession = false; 92 receivedAudioData = false; 93 requestEndSession = false; 94 endSessionTimer = 0; 95 } 96 97 void OnReceiveData(byte[] data) 98 { 99 receivedAudioData = true; 100 tTSAudioStreamPlay.WriteAudioData(data); 101 } 102 103 public void ReadText(string text) 104 { 105 if (hasSession) 106 { 107 Debug.Log("Send TaskRequest: " + text); 108 textToSpeech.Session(text); 109 } 110 else 111 { 112 //缓存文本 113 sentenceBuffer.Append(text); 114 //避免重复建立会话 115 if (isCreateSession == false) 116 { 117 isCreateSession = true; 118 //请求建立会话 119 textToSpeech.BeginSession(); 120 } 121 } 122 } 123 124 public void EndReadText() 125 { 126 if (hasSession) 127 { 128 endSessionTimer = 0; 129 requestEndSession = true; 130 //请求结束会话 131 //textToSpeech.EndSession(); 132 } 133 } 134 135 void Update() 136 { 137 if (requestEndSession) 138 { 139 if (receivedAudioData) 140 { 141 requestEndSession = false; 142 //请求结束会话 143 textToSpeech.EndSession(); 144 } 145 else 146 { 147 endSessionTimer += Time.deltaTime; 148 if (endSessionTimer >= endSessionRequestTime) 149 { 150 requestEndSession = false; 151 endSessionTimer = 0; 152 //请求结束会话 153 textToSpeech.EndSession(); 154 } 155 } 156 } 157 } 158} 159 160
《Unity之使用火山引擎实现流式语音合成|优化版本》 是转载文章,点击查看原文。