1import MusicQueue from '@/core/musicQueue'; 2import MusicSheet from '@/core/musicSheet'; 3import {check, PERMISSIONS, request} from 'react-native-permissions'; 4import TrackPlayer, {Capability} from 'react-native-track-player'; 5import 'react-native-get-random-values'; 6import Config from '@/core/config'; 7import RNBootSplash from 'react-native-bootsplash'; 8import pathConst from '@/constants/pathConst'; 9import {checkAndCreateDir} from '@/utils/fileUtils'; 10import {errorLog, trace} from '@/utils/log'; 11import MediaMeta from '@/core/mediaMeta'; 12import Cache from '@/core/cache'; 13import PluginManager from '@/core/pluginManager'; 14import Network from '@/core/network'; 15import {ImgAsset} from '@/constants/assetsConst'; 16import LocalMusicSheet from '@/core/localMusicSheet'; 17import {StatusBar} from 'react-native'; 18 19/** app加载前执行 20 * 1. 检查权限 21 * 2. 数据初始化 22 * 3. 23 */ 24async function _bootstrap() { 25 // 1. 检查权限 26 const [readStoragePermission, writeStoragePermission] = await Promise.all([ 27 check(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE), 28 check(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE), 29 ]); 30 if ( 31 !( 32 readStoragePermission === 'granted' && 33 writeStoragePermission === 'granted' 34 ) 35 ) { 36 await request(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE); 37 await request(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE); 38 } 39 40 // 2. 数据初始化 41 /** 初始化路径 */ 42 await setupFolder(); 43 trace('文件夹初始化完成'); 44 // 加载配置 45 await Promise.all([ 46 Config.setup(), 47 MediaMeta.setup(), 48 MusicSheet.setup(), 49 Network.setup(), 50 ]); 51 trace('配置初始化完成'); 52 // 加载插件 53 try { 54 await TrackPlayer.setupPlayer({ 55 maxCacheSize: 56 Config.get('setting.basic.maxCacheSize') ?? 1024 * 1024 * 512, 57 }); 58 } catch (e: any) { 59 if ( 60 e?.message !== 61 'The player has already been initialized via setupPlayer.' 62 ) { 63 throw e; 64 } 65 } 66 await TrackPlayer.updateOptions({ 67 icon: ImgAsset.logoTransparent, 68 progressUpdateEventInterval: 1, 69 alwaysPauseOnInterruption: true, 70 capabilities: [ 71 Capability.Play, 72 Capability.Pause, 73 Capability.SkipToNext, 74 Capability.SkipToPrevious, 75 ], 76 compactCapabilities: [ 77 Capability.Play, 78 Capability.Pause, 79 Capability.SkipToNext, 80 Capability.SkipToPrevious, 81 ], 82 notificationCapabilities: [ 83 Capability.Play, 84 Capability.Pause, 85 Capability.SkipToNext, 86 Capability.SkipToPrevious, 87 ], 88 }); 89 trace('播放器初始化完成'); 90 await Cache.setup(); 91 trace('缓存初始化完成'); 92 await PluginManager.setup(); 93 trace('插件初始化完成'); 94 await MusicQueue.setup(); 95 trace('播放列表初始化完成'); 96 await LocalMusicSheet.setup(); 97 trace('本地音乐初始化完成'); 98 99 StatusBar.setBackgroundColor('transparent'); 100 StatusBar.setTranslucent(true); 101 102 ErrorUtils.setGlobalHandler(error => { 103 errorLog('未捕获的错误', error); 104 }); 105} 106 107/** 初始化 */ 108async function setupFolder() { 109 await Promise.all([ 110 checkAndCreateDir(pathConst.dataPath), 111 checkAndCreateDir(pathConst.logPath), 112 checkAndCreateDir(pathConst.cachePath), 113 checkAndCreateDir(pathConst.pluginPath), 114 checkAndCreateDir(pathConst.lrcCachePath), 115 checkAndCreateDir(pathConst.downloadPath).then(() => { 116 checkAndCreateDir(pathConst.downloadMusicPath); 117 }), 118 ]); 119} 120 121export default async function () { 122 try { 123 await _bootstrap(); 124 } catch (e) { 125 errorLog('初始化出错', e); 126 console.log(e); 127 } 128 // 隐藏开屏动画 129 console.log('HIDE'); 130 RNBootSplash.hide({fade: true}); 131} 132