Load sounds at runtime

Hi,

is there a way to load any sound at runtime, e.g. using an command line argument with the path to a certain audio file? It wouldn’t be a problem to be forced to put the sounds into a certain folder but as far as I see it’s not possible to use the resources-folder which doesn’t exist as a folder after building.

Thanks

Using the Resource folder after a build still works.

public AudioClip music;

void Start(){
//Load the sound
music = (AudioClip) Resources.Load("Music");
//Play the sound
GameObject m = new GameObject("Music");
m.AddComponent<AudioSource>();
m.GetComponent<AudioSource>().clip = music;
m.GetComponent<AudioSource>().Play();
}

Indeed, loading files from Resource-folder works but you’re not able to put new files in it.

I guess the only way would be by putting all the files you need into the Resources folder prior to making a build.

Since Unity 5, you can use
AudioClip.LoadAudioData();

More info here here

Thank you for you reply but I’ve got the WWW-solution working yesterday.
For anyone who is interested in, here’s the code:

          WWW audioLoader = new WWW(text);
          while (!audioLoader.isDone)
                    System.Threading.Thread.Sleep(100);

          sound =audioLoader.GetAudioClip(true, false);

          int counter = 0;
          while (sound == null){
                    //do not load longer than 5seconds
                    if (counter++ > 50)
                              break;
                    else
                              System.Threading.Thread.Sleep(100);
                        }

          sound = audioLoader.audioClip;

Sincerely

past this code in your project…

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using System.IO;

public class PlayList : MonoBehaviour {

    string path;
    public List<AudioClip> Cliplist;
    AudioClip[] clips;

    public List<string> audioname;

    void Start ()
    {
        path = Application.persistentDataPath;
        
      
        if (Directory.Exists(path))
        {
            DirectoryInfo info = new DirectoryInfo(path);
          
            foreach (FileInfo item in info.GetFiles("*.wav"))
            {
              
                audioname.Add(item.Name);
            }
          
        }
        StartCoroutine(LoadAudioFile());
    }
  
    IEnumerator LoadAudioFile()
    {
        for (int i = 0; i <audioname.Count; i++)
        {
            UnityWebRequest AudioFiles = UnityWebRequestMultimedia.GetAudioClip(path + string.Format("{0}", audioname[i]),AudioType.WAV);
            yield return AudioFiles.SendWebRequest();
            if(AudioFiles.isNetworkError)
            {
                Debug.Log(AudioFiles.error);
                Debug.Log(path + string.Format("{0}", audioname[i]));
            }
            else
            {
                AudioClip clip = DownloadHandlerAudioClip.GetContent(AudioFiles);
                clip.name = audioname[i];
                Cliplist.Add(clip);
                Debug.Log(path + string.Format("{0}", audioname[i]));
            }
        }
      
    }
}

For those looking for a solution using async/await and potentially needing to first fetch the file and then play here, I posted an example generating an audio file using text to speech and then loading it into a clip to play it.

Also, you can store the downloaded/generated file in Application.dataPath to easily get it back (the asset folder).

Script: Unity script to generate and load an audio clip using Azure Cognitive Services (github.com)
Full project (see readme): mattetti/UnityAzureSpeechSynthesis: Quick demo showing how to use Azure Speech Synthesis (tts) from Unity and loading/playing the generated file in game. (github.com)

The short version is that you can use an async function such as:

 public async Task<AudioClip> GetAudioClip(string filePath, AudioType fileType)
    {

        using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(filePath, fileType))
        {
            var result = www.SendWebRequest();

            while (!result.isDone) { await Task.Delay(100); }

            if (www.result == UnityWebRequest.Result.ConnectionError)
            {
                Debug.Log(www.error);
                return null;
            }
            else
            {
                return DownloadHandlerAudioClip.GetContent(www);
            }
        }
    }

And call it to populate a predefined audio clip (or a new variable):

_audioClip = await GetAudioClip(outputPath, AudioType.WAV);

The clip can then be played via an AudioSource instance.

Note that this approach works for remote files as well as local files.