1.火山平台大模型语音合成管理页面获取appid\accesstoken火山方舟管理控制台
2.大模型语音合成文档大模型语音合成API--语音技术-火山引擎
3.根据文档,四处抄或者AI写代码,简单写一下:
using UnityEngine;
using System.Collections;
using System.Text;
using System;
using UnityEngine.Networking;
using Newtonsoft.Json;
using System.IO;
public class SimpleTTS : MonoBehaviour
{
// 替换为你的火山引擎参数
public string appId = "your_appid";
public string accessToken = "your_access_token";
public string voiceType = "zh_male_M392_conversation_wvae_bigtts"; // 音色ID
[SerializeField] private AudioSource _audioSource;
/// <summary>
/// 合成语音(简化版)
/// </summary>
public void Synthesize(string text)
{
StartCoroutine(CallTTSAPI(text));
}
IEnumerator CallTTSAPI(string text)
{
// 构造请求体
var data = new TTSRequest
{
app = new App
{
appid = appId,
token = accessToken,
cluster = "volcano_tts"
},
user = new User
{
uid = "uid123",
},
audio = new Audio
{
voice_type = voiceType,
encoding = "mp3",
speed_ratio = 1.0f
},
request = new Request
{
reqid = Guid.NewGuid().ToString(),
text = text,
operation = "query"
}
};
// 转换为JSON
string json = JsonUtility.ToJson(data);
byte[] body = Encoding.UTF8.GetBytes(json);
// 创建请求
using (UnityWebRequest req = new UnityWebRequest("https://openspeech.bytedance.com/api/v1/tts", "POST"))
{
req.uploadHandler = new UploadHandlerRaw(body);
req.downloadHandler = new DownloadHandlerBuffer();
req.SetRequestHeader("Content-Type", "application/json");
req.SetRequestHeader("Authorization", "Bearer;" + accessToken); // 注意分号
// 发送请求
yield return req.SendWebRequest();
// 处理结果
if (req.result == UnityWebRequest.Result.Success)
{
//Debug.Log("合成成功!音频Base64:" + req.downloadHandler.text);
// 这里可以添加解析Base64并播放音频的逻辑
var fragment = JsonUtility.FromJson<RootEntity>(req.downloadHandler.text);
Debug.Log(fragment.data);
StartCoroutine(ConvertBase64ToAudioClip(fragment.data, _audioSource));
}
else
{
Debug.LogError("错误:" + req.error);
}
}
}
/// <summary>
/// Base64 编码的 MP3 音频数据转换为 Unity 可播放的AudioClip并通过AudioSource播放
/// </summary>
/// <param name="base64EncodedMp3String"></param>
/// <param name="audioSource"></param>
/// <returns></returns>
IEnumerator ConvertBase64ToAudioClip(string base64EncodedMp3String, AudioSource audioSource)
{
// 1. 解码Base64字符串为字节数组
// Convert.FromBase64String 是 .NET 提供的静态方法,用于将Base64编码的字符串转换为原始字节数组
// 此步骤是处理音频数据的第一步,确保获取正确的二进制音频数据
var audioBytes = Convert.FromBase64String(base64EncodedMp3String);
// 2. 生成临时文件路径
// Application.persistentDataPath 是Unity提供的持久化数据路径,不同平台路径不同(如Android/ios/PC等)
// 注意:原代码缺少路径分隔符 "/",这里应使用 Path.Combine 或手动添加分隔符
// 正确写法:Application.persistentDataPath + "/tmpMP3Base64.mp3"
var tempPath = Application.persistentDataPath + "tmpMP3Base64.mp3";
// 3. 将字节数组写入临时文件
// File.WriteAllBytes 会创建新文件并写入数据,若文件已存在则覆盖
// 此步骤是为了让 UnityWebRequest 能通过文件路径加载音频文件
File.WriteAllBytes(tempPath, audioBytes);
// 4. 创建UnityWebRequest用于加载音频文件
// UnityWebRequestMultimedia.GetAudioClip 是Unity提供的便捷方法,专门用于加载音频文件
// 参数1:文件路径(本地路径或网络路径)
// 参数2:AudioType.MPEG 表示加载MP3格式(MPEG Audio Layer III)
UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(tempPath, AudioType.MPEG);
// 5. 发送请求并等待完成
// yield return 会暂停协程执行,直到请求完成(异步处理,避免阻塞主线程)
// SendWebRequest() 是UnityWebRequest的发送方法,返回一个异步操作对象
yield return request.SendWebRequest();
// 6. 检查请求是否成功
// request.result 表示请求的结果状态,常见状态包括 Success、ConnectionError、ProtocolError等
// 这里先判断是否为连接错误(如文件路径错误、权限不足等)
if (request.result.Equals(UnityWebRequest.Result.ConnectionError))
{
// 打印错误信息(如 "File not found" 或 "Permission denied")
Debug.LogError(request.error);
}
else
{
// 7. 提取解码后的AudioClip对象
// DownloadHandlerAudioClip.GetContent(request) 从请求中获取解码后的音频剪辑
// 注意:此方法仅在请求成功且音频格式正确时有效
audioSource.clip = DownloadHandlerAudioClip.GetContent(request);
// 8. 播放音频
// AudioSource.Play() 会立即开始播放关联的AudioClip
audioSource.Play();
}
// 9. 删除临时文件
// 清理不再需要的临时文件,释放存储空间
// 注意:在某些平台(如iOS)上,删除正在播放的文件可能导致播放中断,建议延迟删除
File.Delete(tempPath);
}
private void Start()
{
//调用测试
Synthesize("你好,这是豆包语音合成测试!希望能给你一些帮助!");
}
}
#region 请求体 实体
[Serializable]
public class TTSRequest
{
public App app;
public User user;
public Audio audio;
public Request request;
}
[Serializable]
public class App
{
public string appid;
public string token;
public string cluster;
}
[Serializable]
public class User
{
public string uid;
}
[Serializable]
public class Audio
{
public string voice_type;
public string encoding;
public float speed_ratio;
}
[Serializable]
public class Request
{
public string reqid;
public string text;
public string operation;
}
#endregion
#region 接收体 实体
[Serializable]
public class RootEntity
{
public string reqid;
public long code;
public string operation;
public string message;
public long sequence;
public string data;
public AdditionEntity addition;
}
[Serializable]
public class AdditionEntity
{
public string duration;
}
#endregion