Trouble streaming audio from WWW: plays only part of file

I’m trying to figure out how to stream in audio from a website using WWW. I’ve read through the documentation and an example or two I found online, and I’ve come up with the code below.

Unfortunately, it seems that no matter what I try, I can’t get the file to play correctly. In a nutshell, what I’m doing is:

  • Start a download
  • Wait for the download to reach X percent complete
  • Extract the clip with GetAudioClip, which is supposed to give you a streaming clip
  • Add to an Audiosource and play

I’m seeing very strange behaviour, and I’m trying to figure out if it’s a bug or if I’m misunderstanding something. The behaviour is inconsistent: if I try to buffer the clip to 25% complete I see one thing, if I try to buffer to 90% I see another thing, and neither is right.

  • If I set the buffer low, say 10% or 25% (www.progress < 0.25f), the audio only plays about a half second, pops a couple times, and dies.
  • If I set the buffer high, say 55-90%, it only plays the a second of audio in the middle or end (of a 4 second clip).

I’m hosting a random sample clip here that I’m testing against: Earth Data Portal.

Is there a different way I should be doing this? Any best practices or samples? Or is what I’m seeing a Unity bug?

private IEnumerator playAudio(string audioFile)
{
    //set up a 2D audiosource to play the clip
    AudioSource audioSource = gameObject.AddComponent<AudioSource>();
    audioSource.playOnAwake = false;

    WWW download = new WWW(audioFile);

    //wait for the download to build up a buffer
    while (download.progress < 0.55f)
        yield return null;

    //Get a reference to the audio clip - this should allow us to stream it
    AudioClip clip = download.GetAudioClip(false, true);

    //just in case the isReadyToPlay bit hasn't been flipped
    Debug.Log("Set up audiosource.  Clip ready: " + clip.isReadyToPlay);
    while (!clip.isReadyToPlay)
        yield return null;

    audioSource.clip = clip;

    //start playing when the clip is ready
    audioSource.Play();
    Debug.Log("Playing audio: " + audioSource.isPlaying);

    //wait for the audio to finish
    while (audioSource.isPlaying || audioSource.timeSamples < clip.samples)
        yield return null;

    Debug.Log("Finished playing the audio clip.  Cleaning up");
}

I have filed two bugs with Unity after further testing. One relates to trying to stream audio, and the other is for inconsistent behaviour between Play() and PlayOneShot().

The first bug was accepted, and the second is a duplicate of a known bug. In the meantime I’ve simply disabled streaming and wait for the full audio to download.

See bug 575799 in the issue tracker.