AudioPlayer.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. using System;
  2. using UnityEngine;
  3. namespace QFramework
  4. {
  5. public class AudioPlayer : IPoolable, IPoolType
  6. {
  7. private IAudioLoader mLoader;
  8. private AudioSource mAudioSource;
  9. private string mName;
  10. public string Name
  11. {
  12. get { return mName; }
  13. }
  14. private bool mIsLoop;
  15. private AudioClip mAudioClip;
  16. private TimeItem mTimeItem;
  17. private bool mUsedCache = true;
  18. private bool mIsCache = false;
  19. private Action<AudioPlayer> mOnStartListener;
  20. private Action<AudioPlayer> mOnFinishListener;
  21. private bool mIsPause = false;
  22. private float mLeftDelayTime = -1;
  23. private int mPlayCount = 0;
  24. private int mCustomEventID;
  25. public AudioSource AudioSource
  26. {
  27. get { return mAudioSource; }
  28. }
  29. public int customEventID
  30. {
  31. get { return mCustomEventID; }
  32. set { mCustomEventID = -1; }
  33. }
  34. public static AudioPlayer Allocate()
  35. {
  36. return SafeObjectPool<AudioPlayer>.Instance.Allocate();
  37. }
  38. public void SetOnStartListener(Action<AudioPlayer> l)
  39. {
  40. mOnStartListener = l;
  41. }
  42. public void SetOnFinishListener(Action<AudioPlayer> l)
  43. {
  44. mOnFinishListener = l;
  45. }
  46. public bool usedCache
  47. {
  48. get { return mUsedCache; }
  49. set { mUsedCache = false; }
  50. }
  51. public int playCount
  52. {
  53. get { return mPlayCount; }
  54. }
  55. public bool IsRecycled
  56. {
  57. get { return mIsCache; }
  58. set { mIsCache = value; }
  59. }
  60. public void SetAudioExt( GameObject root, AudioClip clip, string name, bool loop)
  61. {
  62. if (clip == null || mName == name)
  63. {
  64. return;
  65. }
  66. if (mAudioSource == null)
  67. {
  68. mAudioSource = root.AddComponent<AudioSource>();
  69. }
  70. CleanResources();
  71. mIsLoop = loop;
  72. mName = name;
  73. mAudioClip = clip;
  74. PlayAudioClip();
  75. }
  76. public void SetAudio(GameObject root, string name, bool loop)
  77. {
  78. if (string.IsNullOrEmpty(name))
  79. {
  80. return;
  81. }
  82. if (mName == name)
  83. {
  84. return;
  85. }
  86. if (mAudioSource == null)
  87. {
  88. mAudioSource = root.AddComponent<AudioSource>();
  89. }
  90. //防止卸载后立马加载的情况
  91. var preLoader = mLoader;
  92. mLoader = null;
  93. CleanResources();
  94. mLoader = AudioKit.Config.AudioLoaderPool.AllocateLoader();
  95. mIsLoop = loop;
  96. mName = name;
  97. var keys = AudioSearchKeys.Allocate();
  98. keys.AssetName = name;
  99. mLoader.LoadClipAsync(keys, OnResLoadFinish);
  100. keys.Recycle2Cache();
  101. if (preLoader != null)
  102. {
  103. preLoader.Unload();
  104. AudioKit.Config.AudioLoaderPool.RecycleLoader(preLoader);
  105. preLoader = null;
  106. }
  107. // if (mLoader != null)
  108. // {
  109. // mLoader.LoadAsync();
  110. // }
  111. }
  112. public void Stop()
  113. {
  114. Release();
  115. }
  116. public void Pause()
  117. {
  118. if (mIsPause)
  119. {
  120. return;
  121. }
  122. mLeftDelayTime = -1;
  123. //暂停
  124. if (mTimeItem != null)
  125. {
  126. mLeftDelayTime = mTimeItem.SortScore - QFramework.Timer.Instance.currentScaleTime;
  127. mTimeItem.Cancel();
  128. mTimeItem = null;
  129. }
  130. mIsPause = true;
  131. mAudioSource.Pause();
  132. }
  133. public void Resume()
  134. {
  135. if (!mIsPause)
  136. {
  137. return;
  138. }
  139. if (mLeftDelayTime >= 0)
  140. {
  141. mTimeItem = QFramework.Timer.Instance.Post2Scale(OnResumeTimeTick, mLeftDelayTime);
  142. }
  143. mIsPause = false;
  144. mAudioSource.Play();
  145. }
  146. public void SetVolume(float volume)
  147. {
  148. if (null != mAudioSource)
  149. {
  150. mAudioSource.volume = volume;
  151. }
  152. }
  153. private void OnResLoadFinish(bool result, AudioClip clip)
  154. {
  155. if (!result)
  156. {
  157. Release();
  158. return;
  159. }
  160. mAudioClip =clip;
  161. if (mAudioClip == null)
  162. {
  163. Debug.LogError("Asset Is Invalid AudioClip:" + mName);
  164. Release();
  165. return;
  166. }
  167. PlayAudioClip();
  168. }
  169. private void PlayAudioClip()
  170. {
  171. if (mAudioSource == null || mAudioClip == null)
  172. {
  173. Release();
  174. return;
  175. }
  176. mAudioSource.clip = mAudioClip;
  177. mAudioSource.loop = mIsLoop;
  178. mAudioSource.volume = 1.0f;
  179. int loopCount = 1;
  180. if (mIsLoop)
  181. {
  182. loopCount = -1;
  183. }
  184. mTimeItem = Timer.Instance.Post2Scale(OnSoundPlayFinish, mAudioClip.length, loopCount);
  185. if (null != mOnStartListener)
  186. {
  187. mOnStartListener(this);
  188. }
  189. mAudioSource.Play();
  190. }
  191. private void OnResumeTimeTick(int repeatCount)
  192. {
  193. OnSoundPlayFinish(repeatCount);
  194. if (mIsLoop)
  195. {
  196. mTimeItem = QFramework.Timer.Instance.Post2Scale(OnSoundPlayFinish, mAudioClip.length, -1);
  197. }
  198. }
  199. private void OnSoundPlayFinish(int count)
  200. {
  201. ++mPlayCount;
  202. if (mOnFinishListener != null)
  203. {
  204. mOnFinishListener(this);
  205. }
  206. if (mCustomEventID > 0)
  207. {
  208. // QEventSystem.Instance.Send(mCustomEventID, this);
  209. }
  210. if (!mIsLoop)
  211. {
  212. Release();
  213. }
  214. }
  215. private void Release()
  216. {
  217. CleanResources();
  218. if (mUsedCache)
  219. {
  220. Recycle2Cache();
  221. }
  222. }
  223. private void CleanResources()
  224. {
  225. mName = null;
  226. mPlayCount = 0;
  227. mIsPause = false;
  228. mOnFinishListener = null;
  229. mLeftDelayTime = -1;
  230. mCustomEventID = -1;
  231. if (mTimeItem != null)
  232. {
  233. mTimeItem.Cancel();
  234. mTimeItem = null;
  235. }
  236. if (mAudioSource != null)
  237. {
  238. if (mAudioSource.clip == mAudioClip)
  239. {
  240. mAudioSource.Stop();
  241. mAudioSource.clip = null;
  242. }
  243. }
  244. mAudioClip = null;
  245. if (mLoader != null)
  246. {
  247. mLoader.Unload();
  248. AudioKit.Config.AudioLoaderPool.RecycleLoader(mLoader);
  249. mLoader = null;
  250. }
  251. }
  252. public void OnRecycled()
  253. {
  254. CleanResources();
  255. }
  256. public void Recycle2Cache()
  257. {
  258. if (!SafeObjectPool<AudioPlayer>.Instance.Recycle(this))
  259. {
  260. if (mAudioSource != null)
  261. {
  262. GameObject.Destroy(mAudioSource);
  263. mAudioSource = null;
  264. }
  265. }
  266. }
  267. }
  268. }