Last active
November 12, 2024 14:12
-
-
Save Invertex/7224c4a4168f31aaf2c35cc6d8599ad2 to your computer and use it in GitHub Desktop.
Unity streaming audio playback example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using UnityEngine; | |
using UnityEngine.Networking; | |
namespace Invertex.Unity.Audio | |
{ | |
/// <summary> | |
/// Component that allows playback of an audio file from a server or locally that begins playing before the file is completely downloaded. | |
/// </summary> | |
public class StreamingAudioPlayer : MonoBehaviour | |
{ | |
public AudioSource audioSrc; | |
public string streamAudio; | |
public AudioType audioStreamType = AudioType.UNKNOWN; | |
[Min(1024)] public int bytesToDownloadBeforePlaying = 100000; | |
private void Start() | |
{ | |
//Example usage that can be called from other scripts | |
PlayAudioAsync(streamAudio); | |
} | |
/// <summary> | |
/// Play audio with the currently assigned values. | |
/// </summary> | |
public void PlayAudioAsync() | |
{ | |
PlayAudioAsync(streamAudio); | |
} | |
/// <summary> | |
/// Play audio from given URL, using component's current values. | |
/// </summary> | |
/// <param name="streamURL">The source URL of the audio you want to play</param> | |
public void PlayAudioAsync(string streamURL) | |
{ | |
PlayAudioAsync(streamURL, audioStreamType, (ulong)bytesToDownloadBeforePlaying); | |
} | |
/// <summary> | |
/// Play audio from given URL, using custom AudioType and byte buffering. | |
/// </summary> | |
/// <param name="streamURL">The source URL of the audio you want to play</param> | |
/// <param name="audioType"></param> | |
/// <param name="bytesBeforePlayback">How many bytes to download first before starting playback. Useful to buffer longer for slow downloads.</param> | |
public void PlayAudioAsync(string streamURL, AudioType audioType, ulong bytesBeforePlayback = 10000) | |
{ | |
StartCoroutine(PlayAudioAsyncCoroutine(streamURL, audioType, bytesBeforePlayback)); | |
} | |
private IEnumerator PlayAudioAsyncCoroutine(string streamURL, AudioType audioType, ulong bytesBeforePlayback = 10000) | |
{ | |
if(string.IsNullOrWhiteSpace(streamURL)) { Debug.LogWarning("No audio stream URL provided. Playback skipped."); yield break; } | |
using (var uwr = UnityWebRequestMultimedia.GetAudioClip(streamURL, audioType)) | |
{ | |
DownloadHandlerAudioClip dlHandler = (DownloadHandlerAudioClip)uwr.downloadHandler; | |
//Allow AudioClip to be played before it's finished downloading | |
dlHandler.streamAudio = true; | |
//Begin downloading the clip | |
var download = uwr.SendWebRequest(); | |
yield return null; | |
//Wait for enough bytes to download | |
while (uwr.downloadedBytes < bytesBeforePlayback) | |
{ | |
if (uwr.result == UnityWebRequest.Result.ConnectionError || uwr.result == UnityWebRequest.Result.ProtocolError) | |
{ | |
Debug.LogWarning($"Error downloading audio stream from:{streamURL} : {uwr.error}"); | |
yield break; | |
} | |
yield return null; | |
} | |
AudioClip audioClip = dlHandler.audioClip; | |
//It will be null if it wasn't able to format the audio | |
if (audioClip == null) | |
{ | |
Debug.Log("Couldn't process audio stream."); | |
yield break; | |
} | |
//Assign the streaming clip and play it now that we're ready. | |
audioSrc.clip = audioClip; | |
audioSrc.Play(); | |
Debug.Log("Playing audio stream!"); | |
//Continue downloading the rest of the audio stream. | |
yield return download; | |
Debug.Log("Finished downloading audio stream!"); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment