using OWML.Common; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using UnityEngine; using UnityEngine.Networking; namespace NewHorizons.Utility { public static class AudioUtilities { private static Dictionary _loadedAudioClips = new Dictionary(); public static void SetAudioClip(OWAudioSource source, string audio, IModBehaviour mod) { if (audio.Contains(".wav") || audio.Contains(".ogg") || audio.Contains(".mp3")) { try { var clip = LoadAudio(mod.ModHelper.Manifest.ModFolderPath + "/" + audio); source._audioLibraryClip = AudioType.None; source._clipArrayIndex = 0; source._clipArrayLength = 0; source._clipSelectionOnPlay = OWAudioSource.ClipSelectionOnPlay.MANUAL; source.clip = clip; return; } catch { Logger.LogError($"Could not load file {audio}"); } } try { var audioType = (AudioType)Enum.Parse(typeof(AudioType), audio); source._audioLibraryClip = audioType; } catch { var audioClip = SearchUtilities.FindResourceOfTypeAndName(audio); if (audioClip == null) Logger.Log($"Couldn't find audio clip {audio}"); else source.clip = audioClip; } } public static AudioClip LoadAudio(string path) { try { if (_loadedAudioClips.ContainsKey(path)) { Logger.LogVerbose($"Already loaded audio at path: {path}"); return _loadedAudioClips[path]; } Logger.LogVerbose($"Loading audio at path: {path}"); var task = Task.Run(async () => await GetAudioClip(path)); task.Wait(); _loadedAudioClips.Add(path, task.Result); return task.Result; } catch(Exception ex) { Logger.LogError($"Couldn't load Audio at {path} : {ex}"); return null; } } public static void ClearCache() { Logger.LogVerbose("Clearing audio cache"); foreach (var audioClip in _loadedAudioClips.Values) { if (audioClip == null) continue; UnityEngine.Object.Destroy(audioClip); } _loadedAudioClips.Clear(); } private static async Task GetAudioClip(string filePath) { var extension = filePath.Split(new char[] { '.' }).Last(); UnityEngine.AudioType audioType; switch (extension) { case ("wav"): audioType = UnityEngine.AudioType.WAV; break; case ("ogg"): audioType = UnityEngine.AudioType.OGGVORBIS; break; case ("mp3"): audioType = UnityEngine.AudioType.MPEG; break; default: Logger.LogError($"Invalid audio file extension ({extension}) must be .wav or .ogg or .mp3"); return null; } if (audioType == UnityEngine.AudioType.MPEG) { string fileProtocolPath = $"file://{filePath}"; DownloadHandlerAudioClip dh = new DownloadHandlerAudioClip(fileProtocolPath, UnityEngine.AudioType.MPEG); dh.compressed = true; using (UnityWebRequest www = new UnityWebRequest(fileProtocolPath, "GET", dh, null)) { var result = www.SendWebRequest(); while (!result.isDone) { await Task.Delay(100); } if (www.isNetworkError) { Debug.Log(www.error); return null; } else { return dh.audioClip; } } } else { using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(filePath, audioType)) { var result = www.SendWebRequest(); while (!result.isDone) { await Task.Delay(100); } if (www.isNetworkError) { Debug.Log(www.error); return null; } else { return DownloadHandlerAudioClip.GetContent(www); } } } } } }