115 lines
4.3 KiB
C#
115 lines
4.3 KiB
C#
using NAudio.Wave;
|
||
using System;
|
||
using System.Collections;
|
||
using System.IO;
|
||
using System.Text;
|
||
using System.Text.RegularExpressions;
|
||
using UnityEngine;
|
||
using UnityEngine.Networking;
|
||
|
||
public class ZXKTTS : TTS
|
||
{
|
||
public int maxRetries = 3;
|
||
public string authorizationToken = "Bearer LB-krrBLcSkpWCqL8KmwU6ryg5Y4oNKKJcH26ZqSkgghsNLu7ea2EZv";
|
||
public string role = "longsanshu";
|
||
private UnityWebRequest currentRequest;
|
||
private bool coroutineRunning = false;
|
||
public override void StartSpeak(string _msg, Action<AudioClip> _callback)
|
||
{
|
||
base.StartSpeak(_msg, _callback);
|
||
StartCoroutine(CallAudioAPI(_msg, _callback));
|
||
}
|
||
IEnumerator CallAudioAPI(string input,Action<AudioClip> callBack)
|
||
{
|
||
CleanupCurrentRequest();
|
||
coroutineRunning = true;
|
||
currentRequest = null;
|
||
bool success = false;
|
||
int retryCount = 0;
|
||
|
||
// ´´½¨ÇëÇóÌåÊý¾Ý
|
||
StringBuilder requestData = new();
|
||
requestData.Append("{");
|
||
requestData.Append("\"appId\": \""+ Guid.NewGuid().ToString() +"\",");
|
||
requestData.Append("\"input\": \"" + Regex.Replace(input, @"[\p{P}\p{S}]", "") + "\",");
|
||
requestData.Append("\"ttsConfig\":");
|
||
requestData.Append("{\"type\":\" model \",");
|
||
requestData.Append("\"model\":\"cosyvoice-v2\",");
|
||
requestData.Append("\"voice\":\""+ role +"\"}}");
|
||
Debug.Log(requestData.ToString());
|
||
while (retryCount < maxRetries && !success)
|
||
{
|
||
currentRequest = new(m_PostURL, "POST");
|
||
currentRequest.timeout = 15;
|
||
currentRequest.SetRequestHeader("Authorization", authorizationToken);
|
||
currentRequest.SetRequestHeader("Content-Type", "application/json");
|
||
byte[] data = Encoding.UTF8.GetBytes(requestData.ToString());
|
||
currentRequest.uploadHandler = new UploadHandlerRaw(data);
|
||
currentRequest.downloadHandler = new DownloadHandlerBuffer();
|
||
yield return currentRequest.SendWebRequest();
|
||
if (currentRequest.responseCode == 200 && coroutineRunning)
|
||
{
|
||
callBack?.Invoke(ConvertMp3ToAudioClip(currentRequest.downloadHandler.data));
|
||
success = true;
|
||
}
|
||
else if(coroutineRunning)
|
||
{
|
||
retryCount++;
|
||
if (retryCount < maxRetries)
|
||
{
|
||
Debug.Log("ÕýÔÚÖØÊÔ£¬µÚ " + (retryCount + 1) + " ´Î...");
|
||
yield return new WaitForSeconds(1f); // µÈ´ý 1 ÃëºóÖØÊÔ
|
||
}
|
||
}
|
||
// ÇåÀíµ±Ç°ÇëÇó
|
||
CleanupCurrentRequest();
|
||
}
|
||
if (!success && coroutineRunning)
|
||
{
|
||
callBack?.Invoke(null);
|
||
}
|
||
//½áÊø¼ÆÊ±
|
||
stopwatch.Stop();
|
||
// ±ê¼ÇгÌÒѽáÊø
|
||
coroutineRunning = false;
|
||
}
|
||
AudioClip ConvertMp3ToAudioClip(byte[] mp3Data)
|
||
{
|
||
// ´´½¨Ò»¸öÄÚ´æÁ÷À´´æ´¢MP3Êý¾Ý
|
||
using (MemoryStream ms = new MemoryStream(mp3Data))
|
||
using (Mp3FileReader mp3Reader = new Mp3FileReader(ms))
|
||
using (WaveStream pcmStream = WaveFormatConversionStream.CreatePcmStream(mp3Reader))
|
||
{
|
||
// ¼ÆËãÑù±¾ÊýÁ¿£¬¼ÙÉèÊÇ16λÒôƵ
|
||
int sampleCount = (int)(pcmStream.Length / 2);
|
||
float[] samples = new float[sampleCount];
|
||
WaveBuffer waveBuffer = new WaveBuffer((int)pcmStream.Length);
|
||
int bytesRead = pcmStream.Read(waveBuffer.ByteBuffer, 0, (int)pcmStream.Length);
|
||
|
||
// ½«¶ÌÕûÐ͵ÄPCMÊý¾Ýת»»Îª-1µ½1Ö®¼äµÄ¸¡µãÊý
|
||
for (int i = 0; i < sampleCount; i++)
|
||
{
|
||
short sample = (short)(waveBuffer.ShortBuffer[i]);
|
||
samples[i] = sample / 32768f;
|
||
}
|
||
|
||
// ´´½¨AudioClip¶ÔÏó
|
||
AudioClip audioClip = AudioClip.Create("DecodedAudio", sampleCount, pcmStream.WaveFormat.Channels, pcmStream.WaveFormat.SampleRate, false);
|
||
audioClip.SetData(samples, 0);
|
||
return audioClip;
|
||
}
|
||
}
|
||
// ÇåÀíµ±Ç°ÇëÇóµÄ·½·¨
|
||
private void CleanupCurrentRequest()
|
||
{
|
||
if (currentRequest != null)
|
||
{
|
||
Debug.Log("CleanupCurrentRequest");
|
||
currentRequest.uploadHandler?.Dispose();
|
||
currentRequest.downloadHandler?.Dispose();
|
||
currentRequest.Dispose();
|
||
currentRequest = null;
|
||
}
|
||
}
|
||
}
|