using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; using Coolape; using E7.Native; using System; public class MyAudioPlayerByUrl : MonoBehaviour { public AudioSource audioSource; public string mUrl; public AudioType mDefaultAudioType = AudioType.MPEG; public UnityWebRequest www; public AudioClip myClip; public object finishCallback; public object progressCallback; public bool isPlaying = false; public bool isNativeAudio = false; //===native public NativeAudioPointer latestLoadedAudioPointer; public NativeSource latestUsedNativeSource; public void Start() { } public void Initialize(int bufferSize = -1) { #if UNITY_EDITOR //You should have a fallback to normal AudioSource playing in your game so you can also hear sounds while developing. Debug.Log("Please try this in a real device!"); return; #elif UNITY_ANDROID if (bufferSize <= 0) { DeviceAudioInformation deviceAudioInformation = NativeAudio.GetDeviceAudioInformation(); bufferSize = deviceAudioInformation.optimalBufferSize; } NativeAudio.Initialize(new NativeAudio.InitializationOptions { androidAudioTrackCount = 2, androidMinimumBufferSize = Mathf.RoundToInt(bufferSize) }); #endif } public UnityWebRequest getAudioClip(string url, object callback) { StartCoroutine(_getAudioClip(url, mDefaultAudioType, callback)); return www; } public UnityWebRequest getAudioClip(string url, AudioType audioType, object callback) { StartCoroutine(_getAudioClip(url, audioType, callback)); return www; } public IEnumerator _getAudioClip(string url, AudioType audioType, object callback) { if (string.IsNullOrEmpty(url)) { yield return null; } www = UnityWebRequestMultimedia.GetAudioClip(url, audioType); www.certificateHandler = new AcceptAllCertificatesSignedWithASpecificKeyPublicKey(); using (www) { yield return www.SendWebRequest(); try { if (www.isNetworkError) { Debug.Log(www.error); } else { myClip = DownloadHandlerAudioClip.GetContent(www); Utl.doCallback(callback, myClip, www.downloadHandler.data); } } catch(Exception e) { Debug.LogError(e); } www.certificateHandler.Dispose(); } } public void play(AudioClip clip, object progressCb, object finishCb) { release(); if (clip == null) return; isNativeAudio = false; progressCallback = progressCb; finishCallback = finishCb; audioSource.clip = myClip; audioSource.time = 0; audioSource.Play(); } public void playByNative(AudioClip clip, object progressCb, object finishCb) { try { release(); if (NotRealDevice() || clip == null) return; isNativeAudio = true; progressCallback = progressCb; finishCallback = finishCb; //Loading via AudioClip will pull out and send the audio byte array to C side directly. latestLoadedAudioPointer = NativeAudio.Load(clip); latestUsedNativeSource = NativeAudio.GetNativeSourceAuto(); isPlaying = true; latestUsedNativeSource.Play(latestLoadedAudioPointer); }catch(Exception e) { Debug.LogError(e); } } public void playByNative(string clipPath, object progressCb, object finishCb) { try { release(); if (NotRealDevice() || string.IsNullOrEmpty(clipPath)) return; isNativeAudio = true; progressCallback = progressCb; finishCallback = finishCb; //Loading via AudioClip will pull out and send the audio byte array to C side directly. latestLoadedAudioPointer = NativeAudio.Load(clipPath); latestUsedNativeSource = NativeAudio.GetNativeSourceAuto(); isPlaying = true; latestUsedNativeSource.Play(latestLoadedAudioPointer); } catch (Exception e) { Debug.LogError(e); } } /// /// If you overwrite the pointer without unloading, you lose a way of unloading that audio permanently! /// private void UnloadIfLoaded4Native() { if (latestLoadedAudioPointer != null) { latestLoadedAudioPointer.Unload(); latestUsedNativeSource = default(NativeSource); latestLoadedAudioPointer = null; } } public bool NotRealDevice() { #if UNITY_EDITOR //You should have a fallback to normal AudioSource playing in your game so you can also hear sounds while developing. Debug.Log("Please try this in a real device!"); return true; #else return false; #endif } public float getNativeSourceTime() { if (NotRealDevice()) return 0; if (latestUsedNativeSource.IsValid) { return latestUsedNativeSource.GetPlaybackTime(); } return 0; } private void Update() { if (isNativeAudio) { if (latestLoadedAudioPointer == null || (!latestUsedNativeSource.IsValid)) return; if (isPlaying && Mathf.Abs(getNativeSourceTime() - latestLoadedAudioPointer.Length) <= 0.1) { isPlaying = false; Utl.doCallback(finishCallback, audioSource.clip); } else if (isPlaying) { Utl.doCallback(progressCallback, getNativeSourceTime() / latestLoadedAudioPointer.Length, getNativeSourceTime()); } } else { if (audioSource == null || audioSource.clip == null) return; if (!audioSource.isPlaying && isPlaying && Mathf.Abs(1 - audioSource.time / audioSource.clip.length) <= 0.01) { isPlaying = audioSource.isPlaying; Utl.doCallback(finishCallback, audioSource.clip); //stop(); audioSource.time = 0; } else if (audioSource.isPlaying) { isPlaying = audioSource.isPlaying; Utl.doCallback(progressCallback, audioSource.time / audioSource.clip.length, audioSource.time); } } } public float progress() { if (isNativeAudio) { if (latestLoadedAudioPointer == null || (!latestUsedNativeSource.IsValid)) return 0; return getNativeSourceTime() / latestLoadedAudioPointer.Length; } else { if (audioSource == null || audioSource.clip == null) { return 0; } return audioSource.time / audioSource.clip.length; } } public void stop() { if (isNativeAudio) { #if NATIVE_TOUCH_INTEGRATION Debug.Log("Native touch started!!"); staticPointer = nativeAudioPointer; NativeTouch.RegisterCallback(NTCallback); NativeTouch.Start(new NativeTouch.StartOption { disableUnityTouch = true }); NativeTouch.WarmUp(); return; #endif if (NotRealDevice()) return; if (latestUsedNativeSource.IsValid) { latestUsedNativeSource.Stop(); } } else { audioSource.Stop(); } } public void release() { stop(); if (audioSource.clip != null) { Destroy(audioSource.clip); audioSource.clip = null; } UnloadIfLoaded4Native(); } public void pause() { if (isNativeAudio) { if (NotRealDevice()) return; if (latestUsedNativeSource.IsValid) { latestUsedNativeSource.Resume(); } } else { audioSource.Pause(); } } public void rePlay() { if (isNativeAudio) { if (latestUsedNativeSource.IsValid) { latestUsedNativeSource.Pause(); } } else { audioSource.UnPause(); if (!audioSource.isPlaying) { audioSource.Play(); } } } public void seek(float persent) { if (isNativeAudio) { if (NotRealDevice()) return; if (latestLoadedAudioPointer != null) { float sec = latestLoadedAudioPointer.Length * persent; var options = NativeSource.PlayOptions.defaultOptions; options.offsetSeconds = sec; latestUsedNativeSource = NativeAudio.GetNativeSourceAuto(); latestUsedNativeSource.Play(latestLoadedAudioPointer, options); } } else { if (audioSource != null) { float sec = audioSource.clip.length * persent; audioSource.time = sec; if (!audioSource.isPlaying) { audioSource.Play(); } } } } }