mapluisch / OpenAI-Text-To-Speech-for-Unity

Implementation of OpenAI's Text-To-Speech in Unity. Synthesize any text and play it via any AudioSource.
MIT License
43 stars 10 forks source link

bytes[] to AudioClip #3

Closed CelaldoganGunes closed 5 months ago

CelaldoganGunes commented 5 months ago

Hi, we are using ReadyPlayerMe for our avatars and NPCs. We want to let the NPCs speak with this plugin. ReadyPlayerMe has its own "speak" animation. All it needs is a audioclip to play. Your system gives us audio as byte array ( bytes[] ). How can we convert it to AudioClip inside Unity on real time?

mapluisch commented 5 months ago

Hey,

OpenAI's API returns a .mp3 file, which I download as byte[] and then turn it back into a .mp3 within Unity, which can then be used as AudioClip; it's actually implemented already in my AudioPlayer.cs file:

public void ProcessAudioBytes(byte[] audioData)
{
    string filePath = Path.Combine(Application.persistentDataPath, "audio.mp3");
    File.WriteAllBytes(filePath, audioData);

    StartCoroutine(LoadAndPlayAudio(filePath));
}

private IEnumerator LoadAndPlayAudio(string filePath)
{
    using UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip("file://" + filePath, AudioType.MPEG);
    yield return www.SendWebRequest();

    if (www.result == UnityWebRequest.Result.Success)
    {
        AudioClip audioClip = DownloadHandlerAudioClip.GetContent(www);
        audioSource.clip = audioClip;
        audioSource.Play();
    }
    else Debug.LogError("Audio file loading error: " + www.error);

    if (deleteCachedFile) File.Delete(filePath);
}

The LoadAndPlayAudio func expects the temporary filepath to the .mp3 file that automatically gets created from the byte[]. As far as I know, there's no immediate constructor for byte[] -> AudioClip, but this workaround works :)

You can adapt my script and add your own function to grab the AudioClip from

if (www.result == UnityWebRequest.Result.Success)
{
    AudioClip audioClip = DownloadHandlerAudioClip.GetContent(www);
    audioSource.clip = audioClip;
    audioSource.Play();
}

Hope that helps!

CelaldoganGunes commented 5 months ago

Thank you so much, i edited the last if statement you shared in your message and played the audio clip directly from Ready Player Me avatar system.

         if (www.result == UnityWebRequest.Result.Success)
        {
            AudioClip audioClip = DownloadHandlerAudioClip.GetContent(www);
            avatarObject.GetComponent<VoiceHandler>().PlayAudioClip(audioClip);
            //audioSource.clip = audioClip;
            //audioSource.Play();
        }
mapluisch commented 5 months ago

Perfect, glad it works!