Unity 调用火山大模型语音合成API

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值