using cfg.ActorCfg; using cfg.AudioCfg; using CriWare; using Cysharp.Threading.Tasks; using Framework; using PhxhSDK; using System.Collections.Generic; using System.Linq; public class AlbumManager : Singlenton { public enum PlayMode { Order, Random, Single } PlayMode curPlayMode = PlayMode.Order; public PlayMode CurPlayMode => curPlayMode; List playOrderList = new(); private int curOrderIndex = 0; bool initialized = false; public string curMusicKey; Dictionary albumDic = new Dictionary(); List albumList = new List(); public readonly bool loadFromLocal = true; AlbumLocalData _saveData; public Timer playTimer = new(); void loadOrInit() { if(!initialized) { Init(); initialized = true; playTimer.onPlayEnd += NextAudio; } } public void Init() { albumDic.Clear(); var albumCfg = TableManager.Instance.Tables.AlbumConfig; foreach (var item in albumCfg.DataList) { albumDic.Add(item.Id, item); albumList.Add(item); } if (loadFromLocal) { _saveData = StorageMgr.Instance.GetStorage("ALBUM_LOCAL_DATA"); if (_saveData == null) { _saveData = new AlbumLocalData(); } //if (AlbumUnlocked(_saveData.curAlbumId))//如保存的专辑未解锁,则默认播放第一个专辑 //{ // _saveData.curAlbumId = 1; // _saveData.curPlayAudioIndex = 0; //} //if (_saveData.themeAlbumID != 0 && AlbumUnlocked(_saveData.themeAlbumID))//如保存的主题专辑未解锁,设为无主题专辑 //{ // _saveData.themeAlbumID = 0; //} curPlayMode = (PlayMode)_saveData.curOrderMode; SetPlayMode(curPlayMode); SetPlayList(); var curAudio = CurPlayAudio(); if (curAudio != null) { curMusicKey = curAudio.Key; } else { DebugUtil.LogError("CurAudio is null"); } } else { //TODO 服务器逻辑 } } public void Release() { albumDic.Clear(); albumList.Clear(); } public Dictionary AlbumsDic => albumDic; public List AlbumsLst => albumList; public bool AlbumUnlocked(int albumId) { loadOrInit(); if(albumDic.ContainsKey(albumId)) { if (albumDic[albumId].DefaultUnlock)//默认解锁专辑 { return true; } else { int itemID = albumDic[albumId].ItemID; if (CategoryManager.Instance.GetItemCount(itemID) > 0) { return true; } else { return false; } } } else { //int ItemID= DebugUtil.LogError(albumId + " not found in album config"); return false; } } public List AlbumUnlockCost(int albumId) { if (albumDic.ContainsKey(albumId)) { return albumDic[albumId].CostItems; } else { DebugUtil.LogError(albumId + " not found in album config"); return null; } } /// /// 当前专辑配置 /// /// public DataAlbum GetCurAlbum() { loadOrInit(); if (loadFromLocal) { loadSaveData(); return albumDic[_saveData.curAlbumId]; } else { DebugUtil.Log("服务器读取"); return null; //TODO 服务器逻辑 } } /// /// 获取当前播放的音乐在专辑中序号 /// /// public int GetCurAudioIndex() { loadOrInit(); loadSaveData(); return _saveData.curPlayAudioIndex; } /// /// 设置当前播放的专辑 /// /// /// public void SetCurAlbum(int albumId, int audioIndex) { loadOrInit(); if (albumDic.ContainsKey(albumId)) { loadSaveData(); _saveData.curAlbumId = albumId; _saveData.curPlayAudioIndex = audioIndex; if (albumId == _saveData.themeAlbumID) { _saveData.themeAlbumAudioIndex = audioIndex; } StorageMgr.Instance.SyncForce = true; } else { DebugUtil.LogError(albumId + " not found in album config"); } } /// /// 作为bgm播放的主题专辑 /// /// public int GetCurThemeAlbum() { loadOrInit(); loadSaveData(); return _saveData.themeAlbumID; } public int GetCurThemeAudioIndex() { loadOrInit(); loadSaveData(); return _saveData.themeAlbumAudioIndex; } public void SetCurThemeAlbum(int albumId) { loadOrInit(); loadSaveData(); if (albumDic.ContainsKey(albumId)) { _saveData.themeAlbumID = albumId; if(albumId == _saveData.curAlbumId) { _saveData.themeAlbumAudioIndex = _saveData.curPlayAudioIndex; } else { _saveData.themeAlbumAudioIndex = 0; } } else//取消主题专辑 { _saveData.themeAlbumID = 0; _saveData.themeAlbumAudioIndex = 0; } StorageMgr.Instance.SyncForce = true; } /// /// 专辑内容列表 /// /// public List AlbumPlayList(int albumID) { if(albumDic.ContainsKey(albumID)) { return albumDic[albumID].PlayList.ToList(); } else { DebugUtil.LogError(albumID + " not found in album config"); return null; } } public List CurAlbumPlayList() { loadSaveData(); return AlbumPlayList(_saveData.curAlbumId); } public DataAudio CurPlayAudio() { loadSaveData(); var playList = CurAlbumPlayList(); if (playList != null && playList.Count > 0) { return TableManager.Instance.Tables.Audios.GetByID(playList[_saveData.curPlayAudioIndex]); } else { return null; } } public int CurPlayAudioIndex() { loadSaveData(); return _saveData.curPlayAudioIndex; } public void SetPlayMode(PlayMode mode) { curPlayMode = mode; loadSaveData(); _saveData.curOrderMode = (int)mode; StorageMgr.Instance.SyncForce = true; SetPlayList(); } public void SetPlayList() { playOrderList.Clear(); loadSaveData(); for (int i = 0; i < AlbumPlayList(_saveData.curAlbumId).Count; i++) { playOrderList.Add(i); } switch (curPlayMode) { case PlayMode.Order: break; case PlayMode.Random: ShuffleOderLst(playOrderList); for (int i = 0; i < playOrderList.Count; i++) { if (playOrderList[i] == _saveData.curPlayAudioIndex) { playOrderList.RemoveAt(i); playOrderList.Insert(0, _saveData.curPlayAudioIndex); curOrderIndex = 0; break; } } break; case PlayMode.Single: int curIndex = _saveData.curPlayAudioIndex; for (int i = 0; i < playOrderList.Count; i++) { playOrderList[i] = curIndex; } break; default: break; } for (int i = 0; i < playOrderList.Count; i++) { if (playOrderList[i] == _saveData.curPlayAudioIndex) { curOrderIndex = i; break; } } } public bool CheckIsFavor(int audioID) { loadSaveData(); return _saveData.FavorAudioLst.Contains(audioID); } public void AddFavorAudio(int audio) { loadSaveData(); if (!_saveData.FavorAudioLst.Contains(audio)) { _saveData.FavorAudioLst.Add(audio); StorageMgr.Instance.SyncForce = true; } } public void RemoveFavorAudio(int audio) { loadSaveData(); if (_saveData.FavorAudioLst.Contains(audio)) { _saveData.FavorAudioLst.Remove(audio); StorageMgr.Instance.SyncForce = true; } } void ShuffleOderLst(List ts) { int favoriteIndex = 0; for (int i = 0; i < ts.Count; i++) { if (CheckIsFavor(AlbumPlayList(_saveData.curAlbumId)[i])) { (ts[favoriteIndex], ts[i]) = (ts[i], ts[favoriteIndex]); favoriteIndex++; } }//将喜欢的音频放在前面 for (int i = 0; i < favoriteIndex; i++) { int randomIndex = UnityEngine.Random.Range(i, favoriteIndex); (ts[randomIndex], ts[i]) = (ts[i], ts[randomIndex]); }//将喜欢的音频打乱 for (int i = favoriteIndex; i < ts.Count; i++) { int randomIndex = UnityEngine.Random.Range(i, ts.Count); (ts[randomIndex], ts[i]) = (ts[i], ts[randomIndex]); }//将后半部分打乱 } /// /// 以专辑逻辑播放音频,将由相关播放逻辑控制曲目的顺序 /// /// /// public async void PlayAlbumAudio(int albumID, int audioIndex) { if (albumDic.ContainsKey(albumID)) { var playList = AlbumPlayList(albumID); if (playList != null && playList.Count > 0) { if (audioIndex >= playList.Count) { audioIndex = 0; } await AudioManager.Instance.PlayAudioOld(playList[audioIndex]); curMusicKey = TableManager.Instance.Tables.Audios.GetByID(playList[audioIndex]).Key; SetCurAlbum(albumID, audioIndex); var totalSeconds = AlbumManager.Instance.GetAlbumLength(playList[audioIndex]); playTimer.Start(totalSeconds); } else { DebugUtil.LogError("PlayList is empty"); } } else { DebugUtil.LogError(albumID + " not found in album config"); } } public void PlayPreAudio() { var playList = CurAlbumPlayList(); if (playList != null && playList.Count > 0) { if (curPlayMode == PlayMode.Single) { curOrderIndex = _saveData.curPlayAudioIndex; } curOrderIndex--; if (curOrderIndex < 0) { curOrderIndex = playList.Count - 1; } if (curPlayMode == PlayMode.Single) { for (int i = 0; i < playOrderList.Count; i++) { playOrderList[i] = curOrderIndex; } curOrderIndex = 0; } PlayAlbumAudio(GetCurAlbum().Id, playOrderList[curOrderIndex]); } } #region 播放时长相关 /// /// 当前单曲播放进度 /// /// public float GetAlbumProgress()//_albumAudio { var _bgmAudio = AudioManager.Instance.AudioMgrObj.BgmAudio; if (_bgmAudio != null) { if (_bgmAudio.CriAtomExPlayback.GetTime() < 0) { DebugUtil.LogError("指定音频已被删除!!!"); } return _bgmAudio.CriAtomExPlayback.GetTime() / 1000f; } else { DebugUtil.Log("没有专辑音乐在播放!!!"); return 0; } } /// /// 单曲时长 /// /// public float GetAlbumLength(string key) { var _bgmAudio = AudioManager.Instance.AudioMgrObj.BgmAudio; if (_bgmAudio != null) { //string key = AlbumManager.Instance.curMusicKey; DataAudio audioData; var cueSheetName = _bgmAudio.GetCueSheetName(); audioData = TableManager.Instance.Tables.Audios.GetByKey(key); if (audioData == null) { DebugUtil.LogError("==== 播放的音频不存在!!!音频Key: {0}", key); return 0; } if (AudioManager.Instance.GetAcb(cueSheetName).GetCueInfo(audioData.CueID, out CriAtomEx.CueInfo info)) { if (info.length <= 0) { DebugUtil.LogWarning("专辑音乐长度非正数,正在尝试读取配置"); var len = audioData.Length; if (len > 0) { DebugUtil.Log("获取音频长度成功!!!" + len); return len; } else { DebugUtil.LogError("专辑音乐长度配置错误,音频key:" + key); } } return info.length / 1000f; } else { DebugUtil.LogError("==== 获取专辑音乐长度失败!!!"); return 0; } } else { DebugUtil.Log(key + "没有专辑音乐在播放!!!"); return 0; } } public float GetAlbumLength(int ID) { var _bgmAudio = AudioManager.Instance.AudioMgrObj.BgmAudio; if (_bgmAudio != null) { DataAudio audioData; audioData = TableManager.Instance.Tables.Audios.GetByID(ID); if (audioData == null) { DebugUtil.LogError("==== 播放的音频不存在!!!音频Key: {0}", ID); return 0; } var cueSheetName = _bgmAudio.GetCueSheetName(); if (AudioManager.Instance.GetAcb(cueSheetName).GetCueInfo(audioData.CueID, out CriAtomEx.CueInfo info)) { DebugUtil.Log("cue name: " + info.name); if (info.length <= 0) { DebugUtil.LogWarning("专辑音乐长度非正数,尝试读取配置"); var len = audioData.Length; if (len > 0) { DebugUtil.Log("获取音频长度成功!!!" + len); return len; } else { DebugUtil.LogError("专辑音乐长度配置错误,音频ID:" + ID); } } return info.length / 1000f; } else { DebugUtil.LogError("==== 获取专辑音乐长度失败!!!"); return 0; } } else { return 0; } } #endregion /// /// 尝试设置播放状态 /// /// /// public bool PauseAndResumeAlbum(bool pause) { var _bgmAudio = AudioManager.Instance.AudioMgrObj.BgmAudio; if (pause) { _bgmAudio?.Pause(); return true; } else { if (_bgmAudio != null && _bgmAudio.IsPaused) { _bgmAudio.Resume(); return true; } else { return false; } } } public void PlayNextAudio() { var playList = CurAlbumPlayList(); if (playList != null && playList.Count > 0) { if (curPlayMode == PlayMode.Single) { curOrderIndex = _saveData.curPlayAudioIndex; } curOrderIndex++; if (curOrderIndex >= playList.Count) { curOrderIndex = 0; } if (curPlayMode == PlayMode.Single) { for (int i = 0; i < playOrderList.Count; i++) { playOrderList[i] = curOrderIndex; } curOrderIndex = 0; } PlayAlbumAudio(GetCurAlbum().Id, playOrderList[curOrderIndex]); } } /// /// 播放完成回调 /// public void NextAudio() { var playList = CurAlbumPlayList(); if (playList != null && playList.Count > 0) { curOrderIndex++; if (curOrderIndex >= playList.Count) { curOrderIndex = 0; } PlayAlbumAudio(GetCurAlbum().Id, playOrderList[curOrderIndex]); } } /// /// 播放进度计时器 /// public class Timer { bool isPlaying; float audioLength = -1; public delegate void OnSecondChange(); public event OnSecondChange onSecondChange; public delegate void OnPlayEnd(); public event OnPlayEnd onPlayEnd; async UniTask AudioTimer() { while (isPlaying) { float totalSeconds = AlbumManager.Instance.GetAlbumProgress(); if (totalSeconds < 0) { isPlaying = false; break; } if (totalSeconds >= audioLength && audioLength > 0) { isPlaying = false; //AudioManager.Instance.StopMusicById(CurPlayAudio().ID); onPlayEnd?.Invoke(); break; } if (!AudioManager.Instance.AudioMgrObj.BgmAudio.IsPaused) onSecondChange?.Invoke(); await UniTask.Delay(100);//0.1s } } public void Start(float audiolen) { audioLength = audiolen; if (audiolen <= 0) { DebugUtil.LogWarning("当前传入音频长度非正数,请后续考虑更新代码"); } if (isPlaying) { return; } isPlaying = true; AudioTimer().Forget(); } public void Start() { if (isPlaying) { return; } isPlaying = true; AudioTimer().Forget(); } public void Stop() { isPlaying = false; } } /// /// _saveData未读取时的处理 /// void loadSaveData() { if (_saveData == null) { _saveData = StorageMgr.Instance.GetStorage("ALBUM_LOCAL_DATA"); if (AlbumUnlocked(_saveData.curAlbumId))//如保存的专辑未解锁,则默认播放第一个专辑 { SetCurAlbum(1, 0); } if (_saveData.themeAlbumID != 0 && AlbumUnlocked(_saveData.themeAlbumID))//如保存的主题专辑未解锁,设为无主题专辑 { SetCurThemeAlbum(0); } } } } public class AlbumLocalData { public int curAlbumId = 1; public int curPlayAudioIndex = 0; public int curOrderMode = 0; public int themeAlbumID = 0;//如果为0,则表示没有设置主题专辑 public int themeAlbumAudioIndex = 0;//主题专辑音频序号 public List FavorAudioLst = new List(); }