2026-03-24 11:39:01 +08:00

115 lines
4.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}