1/** 2 * 管理当前歌曲的歌词 3 */ 4 5import {isSameMediaItem} from '@/utils/mediaItem'; 6import MusicQueue from './musicQueue'; 7import PluginManager from './pluginManager'; 8import LyricParser from '@/utils/lrcParser'; 9import {GlobalState} from '@/utils/stateMapper'; 10import {EDeviceEvents} from '@/constants/commonConst'; 11import {DeviceEventEmitter} from 'react-native'; 12import Config from './config'; 13import LyricUtil from '@/native/lyricUtil'; 14 15const lyricStateStore = new GlobalState<{ 16 loading: boolean; 17 lyricParser?: LyricParser; 18 lyrics: ILyric.IParsedLrc; 19 meta?: Record<string, string>; 20}>({ 21 loading: true, 22 lyrics: [], 23}); 24 25const currentLyricStore = new GlobalState<ILyric.IParsedLrcItem | null>(null); 26 27// 重新获取歌词 28async function refreshLyric(fromStart?: boolean) { 29 const musicItem = MusicQueue.getCurrentMusicItem(); 30 try { 31 lyricStateStore.setValue({ 32 loading: true, 33 lyrics: [], 34 }); 35 currentLyricStore.setValue(null); 36 37 const lrc = await PluginManager.getByMedia( 38 musicItem, 39 )?.methods?.getLyricText(musicItem); 40 const realtimeMusicItem = MusicQueue.getCurrentMusicItem(); 41 if (isSameMediaItem(musicItem, realtimeMusicItem)) { 42 if (lrc) { 43 const parser = new LyricParser(lrc, musicItem); 44 lyricStateStore.setValue({ 45 loading: false, 46 lyricParser: parser, 47 lyrics: parser.getLyric(), 48 meta: parser.getMeta(), 49 }); 50 // 更新当前状态的歌词 51 const currentLyric = fromStart 52 ? parser.getLyric()[0] 53 : parser.getPosition(await MusicQueue.getPosition()).lrc; 54 currentLyricStore.setValue(currentLyric || null); 55 } else { 56 // 没有歌词 57 lyricStateStore.setValue({ 58 loading: false, 59 lyrics: [], 60 }); 61 } 62 } 63 } catch { 64 const realtimeMusicItem = MusicQueue.getCurrentMusicItem(); 65 if (isSameMediaItem(musicItem, realtimeMusicItem)) { 66 // 异常情况 67 lyricStateStore.setValue({ 68 loading: false, 69 lyrics: [], 70 }); 71 } 72 } 73} 74 75// 获取歌词 76async function setup() { 77 DeviceEventEmitter.addListener(EDeviceEvents.REFRESH_LYRIC, refreshLyric); 78 79 if (Config.get('setting.lyric.showStatusBarLyric')) { 80 LyricUtil.showStatusBarLyric( 81 'MusicFree', 82 Config.get('setting.lyric') ?? {}, 83 ); 84 } 85 86 refreshLyric(); 87} 88 89const LyricManager = { 90 setup, 91 useLyricState: lyricStateStore.useValue, 92 getLyricState: lyricStateStore.getValue, 93 useCurrentLyric: currentLyricStore.useValue, 94 getCurrentLyric: currentLyricStore.getValue, 95 setCurrentLyric: currentLyricStore.setValue, 96}; 97 98export default LyricManager; 99