1*afb5c234S猫头猫import {internalSerialzeKey, StorageKeys} from '@/constants/commonConst'; 2*afb5c234S猫头猫import mp3Util, {IBasicMeta} from '@/native/mp3Util'; 3*afb5c234S猫头猫import {isSameMediaItem} from '@/utils/mediaItem'; 4*afb5c234S猫头猫import StateMapper from '@/utils/stateMapper'; 5*afb5c234S猫头猫import {getStorage, setStorage} from '@/utils/storage'; 6*afb5c234S猫头猫import {FileSystem} from 'react-native-file-access'; 7*afb5c234S猫头猫 8*afb5c234S猫头猫let localSheet: IMusic.IMusicItem[] = []; 9*afb5c234S猫头猫const localSheetStateMapper = new StateMapper(() => localSheet); 10*afb5c234S猫头猫 11*afb5c234S猫头猫export async function setup() { 12*afb5c234S猫头猫 const sheets = await getStorage(StorageKeys.LocalMusicSheet); 13*afb5c234S猫头猫 if (sheets) { 14*afb5c234S猫头猫 localSheet = sheets; 15*afb5c234S猫头猫 } else { 16*afb5c234S猫头猫 await setStorage(StorageKeys.LocalMusicSheet, []); 17*afb5c234S猫头猫 } 18*afb5c234S猫头猫 localSheetStateMapper.notify(); 19*afb5c234S猫头猫} 20*afb5c234S猫头猫 21*afb5c234S猫头猫export async function addMusic( 22*afb5c234S猫头猫 musicItem: IMusic.IMusicItem | IMusic.IMusicItem[], 23*afb5c234S猫头猫) { 24*afb5c234S猫头猫 if (!Array.isArray(musicItem)) { 25*afb5c234S猫头猫 musicItem = [musicItem]; 26*afb5c234S猫头猫 } 27*afb5c234S猫头猫 let newSheet = [...localSheet]; 28*afb5c234S猫头猫 musicItem.forEach(mi => { 29*afb5c234S猫头猫 if (localSheet.findIndex(_ => isSameMediaItem(mi, _)) === -1) { 30*afb5c234S猫头猫 newSheet.push(mi); 31*afb5c234S猫头猫 } 32*afb5c234S猫头猫 }); 33*afb5c234S猫头猫 await setStorage(StorageKeys.LocalMusicSheet, newSheet); 34*afb5c234S猫头猫 localSheet = newSheet; 35*afb5c234S猫头猫 localSheetStateMapper.notify(); 36*afb5c234S猫头猫} 37*afb5c234S猫头猫 38*afb5c234S猫头猫export async function removeMusic( 39*afb5c234S猫头猫 musicItem: IMusic.IMusicItem, 40*afb5c234S猫头猫 deleteOriginalFile = false, 41*afb5c234S猫头猫) { 42*afb5c234S猫头猫 const idx = localSheet.findIndex(_ => isSameMediaItem(_, musicItem)); 43*afb5c234S猫头猫 let newSheet = [...localSheet]; 44*afb5c234S猫头猫 if (idx !== -1) { 45*afb5c234S猫头猫 newSheet.splice(idx, 1); 46*afb5c234S猫头猫 if (deleteOriginalFile && musicItem[internalSerialzeKey]?.localPath) { 47*afb5c234S猫头猫 await FileSystem.unlink(musicItem[internalSerialzeKey].localPath); 48*afb5c234S猫头猫 } 49*afb5c234S猫头猫 } 50*afb5c234S猫头猫 localSheet = newSheet; 51*afb5c234S猫头猫 localSheetStateMapper.notify(); 52*afb5c234S猫头猫} 53*afb5c234S猫头猫 54*afb5c234S猫头猫function parseFilename(fn: string): Partial<IMusic.IMusicItem> | null { 55*afb5c234S猫头猫 const data = fn.slice(0, fn.lastIndexOf('.')).split('@'); 56*afb5c234S猫头猫 const [platform, id, title, artist] = data; 57*afb5c234S猫头猫 if (!platform || !id) { 58*afb5c234S猫头猫 return null; 59*afb5c234S猫头猫 } 60*afb5c234S猫头猫 return { 61*afb5c234S猫头猫 id, 62*afb5c234S猫头猫 platform, 63*afb5c234S猫头猫 title, 64*afb5c234S猫头猫 artist, 65*afb5c234S猫头猫 }; 66*afb5c234S猫头猫} 67*afb5c234S猫头猫 68*afb5c234S猫头猫export async function importFolder(folderPath: string) { 69*afb5c234S猫头猫 const dirFiles = await FileSystem.statDir(folderPath); 70*afb5c234S猫头猫 const musicFiles = dirFiles.filter( 71*afb5c234S猫头猫 _ => _.type === 'file' && _.filename.endsWith('.mp3'), 72*afb5c234S猫头猫 ); 73*afb5c234S猫头猫 74*afb5c234S猫头猫 const musicItems: IMusic.IMusicItem[] = await Promise.all( 75*afb5c234S猫头猫 musicFiles.map(async mf => { 76*afb5c234S猫头猫 let {platform, id, title, artist} = 77*afb5c234S猫头猫 parseFilename(mf.filename) ?? {}; 78*afb5c234S猫头猫 79*afb5c234S猫头猫 const decodedPath = decodeURIComponent(mf.path); 80*afb5c234S猫头猫 let meta: IBasicMeta | null; 81*afb5c234S猫头猫 try { 82*afb5c234S猫头猫 meta = await mp3Util.getBasicMeta(mf.path); 83*afb5c234S猫头猫 } catch { 84*afb5c234S猫头猫 meta = null; 85*afb5c234S猫头猫 } 86*afb5c234S猫头猫 if (!platform || !id) { 87*afb5c234S猫头猫 platform = '本地'; 88*afb5c234S猫头猫 id = await FileSystem.hash(mf.path, 'MD5'); 89*afb5c234S猫头猫 } 90*afb5c234S猫头猫 return { 91*afb5c234S猫头猫 id, 92*afb5c234S猫头猫 platform, 93*afb5c234S猫头猫 title: title ?? meta?.title ?? '未知名称', 94*afb5c234S猫头猫 artist: artist ?? meta?.artist ?? '未知歌手', 95*afb5c234S猫头猫 duration: parseInt(meta?.duration ?? '0') / 1000, 96*afb5c234S猫头猫 album: meta?.album ?? '', 97*afb5c234S猫头猫 artwork: '', 98*afb5c234S猫头猫 [internalSerialzeKey]: { 99*afb5c234S猫头猫 localPath: decodedPath, 100*afb5c234S猫头猫 }, 101*afb5c234S猫头猫 }; 102*afb5c234S猫头猫 }), 103*afb5c234S猫头猫 ); 104*afb5c234S猫头猫 addMusic(musicItems); 105*afb5c234S猫头猫} 106