1/** 2 * 管理当前歌曲的歌词 3 */ 4 5import {isSameMediaItem} from '@/utils/mediaItem'; 6import PluginManager from './pluginManager'; 7import LyricParser from '@/utils/lrcParser'; 8import {GlobalState} from '@/utils/stateMapper'; 9import {EDeviceEvents} from '@/constants/commonConst'; 10import {DeviceEventEmitter} from 'react-native'; 11import Config from './config'; 12import LyricUtil from '@/native/lyricUtil'; 13import TrackPlayer from './trackPlayer'; 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 = TrackPlayer.getCurrentMusic(); 30 try { 31 if (!musicItem) { 32 lyricStateStore.setValue({ 33 loading: false, 34 lyrics: [], 35 }); 36 37 currentLyricStore.setValue({ 38 lrc: 'MusicFree', 39 time: 0, 40 }); 41 42 return; 43 } 44 45 lyricStateStore.setValue({ 46 loading: true, 47 lyrics: [], 48 }); 49 currentLyricStore.setValue(null); 50 51 const lrc = await PluginManager.getByMedia( 52 musicItem, 53 )?.methods?.getLyricText(musicItem); 54 const realtimeMusicItem = TrackPlayer.getCurrentMusic(); 55 if (isSameMediaItem(musicItem, realtimeMusicItem)) { 56 if (lrc) { 57 const parser = new LyricParser(lrc, musicItem); 58 lyricStateStore.setValue({ 59 loading: false, 60 lyricParser: parser, 61 lyrics: parser.getLyric(), 62 meta: parser.getMeta(), 63 }); 64 // 更新当前状态的歌词 65 const currentLyric = fromStart 66 ? parser.getLyric()[0] 67 : parser.getPosition( 68 (await TrackPlayer.getProgress()).position, 69 ).lrc; 70 currentLyricStore.setValue(currentLyric || null); 71 } else { 72 // 没有歌词 73 lyricStateStore.setValue({ 74 loading: false, 75 lyrics: [], 76 }); 77 } 78 } 79 } catch { 80 const realtimeMusicItem = TrackPlayer.getCurrentMusic(); 81 if (isSameMediaItem(musicItem, realtimeMusicItem)) { 82 // 异常情况 83 lyricStateStore.setValue({ 84 loading: false, 85 lyrics: [], 86 }); 87 } 88 } 89} 90 91// 获取歌词 92async function setup() { 93 DeviceEventEmitter.addListener(EDeviceEvents.REFRESH_LYRIC, refreshLyric); 94 95 if (Config.get('setting.lyric.showStatusBarLyric')) { 96 LyricUtil.showStatusBarLyric( 97 'MusicFree', 98 Config.get('setting.lyric') ?? {}, 99 ); 100 } 101 102 refreshLyric(); 103} 104 105const LyricManager = { 106 setup, 107 useLyricState: lyricStateStore.useValue, 108 getLyricState: lyricStateStore.getValue, 109 useCurrentLyric: currentLyricStore.useValue, 110 getCurrentLyric: currentLyricStore.getValue, 111 setCurrentLyric: currentLyricStore.setValue, 112}; 113 114export default LyricManager; 115