1e14deecfS猫头猫import MusicSheet from '@/core/musicSheet'; 2bf6e62f2S猫头猫import {check, PERMISSIONS, request} from 'react-native-permissions'; 35500cea7S猫头猫import RNTrackPlayer, { 45500cea7S猫头猫 AppKilledPlaybackBehavior, 55500cea7S猫头猫 Capability, 65500cea7S猫头猫} from 'react-native-track-player'; 7bf6e62f2S猫头猫import 'react-native-get-random-values'; 8e22d5e4fS猫头猫import Config from '@/core/config'; 90d39db21S猫头猫import RNBootSplash from 'react-native-bootsplash'; 106780f402S猫头猫import pathConst from '@/constants/pathConst'; 11be0a3650S猫头猫import {checkAndCreateDir} from '@/utils/fileUtils'; 121e263108S猫头猫import {errorLog, trace} from '@/utils/log'; 1343eb30bfS猫头猫import MediaMeta from '@/core/mediaMeta.old'; 1443eb30bfS猫头猫import Cache from '@/core/cache.old'; 15927dbe93S猫头猫import PluginManager from '@/core/pluginManager'; 16ef714860S猫头猫import Network from '@/core/network'; 17c30d30e1S猫头猫import {ImgAsset} from '@/constants/assetsConst'; 180e4173cdS猫头猫import LocalMusicSheet from '@/core/localMusicSheet'; 199c72192fS猫头猫import {Linking} from 'react-native'; 20a27adc20S猫头猫import Theme from '@/core/theme'; 2157277364S猫头猫import LyricManager from '@/core/lyricManager'; 22a84a85c5S猫头猫import Toast from '@/utils/toast'; 23a84a85c5S猫头猫import {localPluginHash, supportLocalMediaType} from '@/constants/commonConst'; 245500cea7S猫头猫import TrackPlayer from '@/core/trackPlayer'; 255500cea7S猫头猫import musicHistory from '@/core/musicHistory'; 26*0dd58d38S猫头猫import PersistStatus from '@/core/persistStatus'; 27bf6e62f2S猫头猫 288b88e961S猫头猫/** app加载前执行 298b88e961S猫头猫 * 1. 检查权限 308b88e961S猫头猫 * 2. 数据初始化 318b88e961S猫头猫 * 3. 328b88e961S猫头猫 */ 3394a1b1fcS猫头猫async function _bootstrap() { 34927dbe93S猫头猫 // 1. 检查权限 35bf6e62f2S猫头猫 const [readStoragePermission, writeStoragePermission] = await Promise.all([ 36bf6e62f2S猫头猫 check(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE), 37bf6e62f2S猫头猫 check(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE), 38bf6e62f2S猫头猫 ]); 39bf6e62f2S猫头猫 if ( 40bf6e62f2S猫头猫 !( 41bf6e62f2S猫头猫 readStoragePermission === 'granted' && 42bf6e62f2S猫头猫 writeStoragePermission === 'granted' 43bf6e62f2S猫头猫 ) 44bf6e62f2S猫头猫 ) { 45bf6e62f2S猫头猫 await request(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE); 46bf6e62f2S猫头猫 await request(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE); 47bf6e62f2S猫头猫 } 48bf6e62f2S猫头猫 49927dbe93S猫头猫 // 2. 数据初始化 506780f402S猫头猫 /** 初始化路径 */ 516780f402S猫头猫 await setupFolder(); 521e263108S猫头猫 trace('文件夹初始化完成'); 53bf6e62f2S猫头猫 // 加载配置 54ef714860S猫头猫 await Promise.all([ 55ef714860S猫头猫 Config.setup(), 56ef714860S猫头猫 MediaMeta.setup(), 57ef714860S猫头猫 MusicSheet.setup(), 58ef714860S猫头猫 Network.setup(), 595500cea7S猫头猫 musicHistory.setupMusicHistory(), 60ef714860S猫头猫 ]); 611e263108S猫头猫 trace('配置初始化完成'); 62bf6e62f2S猫头猫 // 加载插件 6394a1b1fcS猫头猫 try { 645500cea7S猫头猫 await RNTrackPlayer.setupPlayer({ 65b882a19dS猫头猫 maxCacheSize: 66b882a19dS猫头猫 Config.get('setting.basic.maxCacheSize') ?? 1024 * 1024 * 512, 67cfa0fc07S猫头猫 }); 6894a1b1fcS猫头猫 } catch (e: any) { 6994a1b1fcS猫头猫 if ( 704060c00aS猫头猫 e?.message !== 714060c00aS猫头猫 'The player has already been initialized via setupPlayer.' 7294a1b1fcS猫头猫 ) { 7394a1b1fcS猫头猫 throw e; 7494a1b1fcS猫头猫 } 7594a1b1fcS猫头猫 } 765500cea7S猫头猫 await RNTrackPlayer.updateOptions({ 772aa88193S猫头猫 icon: ImgAsset.logoTransparent, 78e2257bd6S猫头猫 progressUpdateEventInterval: 1, 795500cea7S猫头猫 android: { 805500cea7S猫头猫 alwaysPauseOnInterruption: true, 815500cea7S猫头猫 appKilledPlaybackBehavior: 825500cea7S猫头猫 AppKilledPlaybackBehavior.ContinuePlayback, 835500cea7S猫头猫 }, 84bf6e62f2S猫头猫 capabilities: [ 85bf6e62f2S猫头猫 Capability.Play, 86bf6e62f2S猫头猫 Capability.Pause, 87bf6e62f2S猫头猫 Capability.SkipToNext, 88bf6e62f2S猫头猫 Capability.SkipToPrevious, 89bf6e62f2S猫头猫 ], 90bf6e62f2S猫头猫 compactCapabilities: [ 91bf6e62f2S猫头猫 Capability.Play, 92bf6e62f2S猫头猫 Capability.Pause, 93bf6e62f2S猫头猫 Capability.SkipToNext, 94bf6e62f2S猫头猫 Capability.SkipToPrevious, 95bf6e62f2S猫头猫 ], 96bf6e62f2S猫头猫 notificationCapabilities: [ 97bf6e62f2S猫头猫 Capability.Play, 98bf6e62f2S猫头猫 Capability.Pause, 99bf6e62f2S猫头猫 Capability.SkipToNext, 100bf6e62f2S猫头猫 Capability.SkipToPrevious, 1010d39db21S猫头猫 ], 1020d39db21S猫头猫 }); 1031e263108S猫头猫 trace('播放器初始化完成'); 1044060c00aS猫头猫 await Cache.setup(); 1051e263108S猫头猫 trace('缓存初始化完成'); 1068b88e961S猫头猫 await PluginManager.setup(); 1071e263108S猫头猫 trace('插件初始化完成'); 1085500cea7S猫头猫 await TrackPlayer.setupTrackPlayer(); 1091e263108S猫头猫 trace('播放列表初始化完成'); 1100e4173cdS猫头猫 await LocalMusicSheet.setup(); 1110e4173cdS猫头猫 trace('本地音乐初始化完成'); 112a27adc20S猫头猫 Theme.setup(); 113a27adc20S猫头猫 trace('主题初始化完成'); 11457277364S猫头猫 await LyricManager.setup(); 1158b88e961S猫头猫 116b3a3a048S猫头猫 extraMakeup(); 117c79c8a57S猫头猫 ErrorUtils.setGlobalHandler(error => { 118c79c8a57S猫头猫 errorLog('未捕获的错误', error); 119c79c8a57S猫头猫 }); 120bf6e62f2S猫头猫} 1216c6f45bdS猫头猫 1226c6f45bdS猫头猫/** 初始化 */ 1236c6f45bdS猫头猫async function setupFolder() { 1246780f402S猫头猫 await Promise.all([ 125be0a3650S猫头猫 checkAndCreateDir(pathConst.dataPath), 1267f771613S猫头猫 checkAndCreateDir(pathConst.logPath), 1277f771613S猫头猫 checkAndCreateDir(pathConst.cachePath), 128c79c8a57S猫头猫 checkAndCreateDir(pathConst.pluginPath), 12994a1b1fcS猫头猫 checkAndCreateDir(pathConst.lrcCachePath), 1300e4173cdS猫头猫 checkAndCreateDir(pathConst.downloadPath).then(() => { 1310e4173cdS猫头猫 checkAndCreateDir(pathConst.downloadMusicPath); 1320e4173cdS猫头猫 }), 1336780f402S猫头猫 ]); 1346c6f45bdS猫头猫} 13594a1b1fcS猫头猫 13694a1b1fcS猫头猫export default async function () { 13794a1b1fcS猫头猫 try { 13894a1b1fcS猫头猫 await _bootstrap(); 13994a1b1fcS猫头猫 } catch (e) { 14094a1b1fcS猫头猫 errorLog('初始化出错', e); 14194a1b1fcS猫头猫 } 14294a1b1fcS猫头猫 // 隐藏开屏动画 14394a1b1fcS猫头猫 console.log('HIDE'); 14494a1b1fcS猫头猫 RNBootSplash.hide({fade: true}); 14594a1b1fcS猫头猫} 146b3a3a048S猫头猫 147b3a3a048S猫头猫/** 不需要阻塞的 */ 148b3a3a048S猫头猫async function extraMakeup() { 149a84a85c5S猫头猫 // 自动更新 150b3a3a048S猫头猫 try { 151b3a3a048S猫头猫 if (Config.get('setting.basic.autoUpdatePlugin')) { 152*0dd58d38S猫头猫 const lastUpdated = PersistStatus.get('app.pluginUpdateTime') || 0; 153b3a3a048S猫头猫 const now = Date.now(); 154b3a3a048S猫头猫 if (Math.abs(now - lastUpdated) > 86400000) { 155*0dd58d38S猫头猫 PersistStatus.set('app.pluginUpdateTime', now); 156b3a3a048S猫头猫 const plugins = PluginManager.getValidPlugins(); 157b3a3a048S猫头猫 for (let i = 0; i < plugins.length; ++i) { 158b3a3a048S猫头猫 const srcUrl = plugins[i].instance.srcUrl; 159b3a3a048S猫头猫 if (srcUrl) { 160b3a3a048S猫头猫 await PluginManager.installPluginFromUrl(srcUrl); 161b3a3a048S猫头猫 } 162b3a3a048S猫头猫 } 163b3a3a048S猫头猫 } 164b3a3a048S猫头猫 } 165b3a3a048S猫头猫 } catch {} 166a84a85c5S猫头猫 167a84a85c5S猫头猫 async function handleLinkingUrl(url: string) { 168a84a85c5S猫头猫 // 插件 169a84a85c5S猫头猫 try { 170eea2f34fS猫头猫 if (url.startsWith('musicfree://install/')) { 171eea2f34fS猫头猫 const plugins = url 172eea2f34fS猫头猫 .slice(20) 173eea2f34fS猫头猫 .split(',') 174eea2f34fS猫头猫 .map(decodeURIComponent); 175eea2f34fS猫头猫 await Promise.all( 176eea2f34fS猫头猫 plugins.map(it => 177eea2f34fS猫头猫 PluginManager.installPluginFromUrl(it).catch(() => {}), 178eea2f34fS猫头猫 ), 179eea2f34fS猫头猫 ); 180eea2f34fS猫头猫 Toast.success('安装成功~'); 181eea2f34fS猫头猫 } else if (url.endsWith('.js')) { 182e36e2599S猫头猫 PluginManager.installPlugin(url, { 183e36e2599S猫头猫 notCheckVersion: Config.get( 184e36e2599S猫头猫 'setting.basic.notCheckPluginVersion', 185e36e2599S猫头猫 ), 186e36e2599S猫头猫 }) 187a84a85c5S猫头猫 .then(res => { 188a84a85c5S猫头猫 Toast.success(`插件「${res.name}」安装成功~`); 189a84a85c5S猫头猫 }) 190a84a85c5S猫头猫 .catch(e => { 191a84a85c5S猫头猫 console.log(e); 192a84a85c5S猫头猫 Toast.warn(e?.message ?? '无法识别此插件'); 193a84a85c5S猫头猫 }); 194a84a85c5S猫头猫 } else if (supportLocalMediaType.some(it => url.endsWith(it))) { 195a84a85c5S猫头猫 // 本地播放 196a84a85c5S猫头猫 const musicItem = await PluginManager.getByHash( 197a84a85c5S猫头猫 localPluginHash, 198a84a85c5S猫头猫 )?.instance?.importMusicItem?.(url); 199a84a85c5S猫头猫 console.log(musicItem); 200a84a85c5S猫头猫 if (musicItem) { 2015500cea7S猫头猫 TrackPlayer.play(musicItem); 202a84a85c5S猫头猫 } 203a84a85c5S猫头猫 } 204a84a85c5S猫头猫 } catch {} 205a84a85c5S猫头猫 } 206a84a85c5S猫头猫 207a84a85c5S猫头猫 // 开启监听 208a84a85c5S猫头猫 Linking.addEventListener('url', data => { 209a84a85c5S猫头猫 if (data.url) { 210a84a85c5S猫头猫 handleLinkingUrl(data.url); 211a84a85c5S猫头猫 } 212a84a85c5S猫头猫 }); 213a84a85c5S猫头猫 const initUrl = await Linking.getInitialURL(); 214a84a85c5S猫头猫 if (initUrl) { 215a84a85c5S猫头猫 handleLinkingUrl(initUrl); 216a84a85c5S猫头猫 } 217aaa0db32S猫头猫 218aaa0db32S猫头猫 if (Config.get('setting.basic.autoPlayWhenAppStart')) { 2195500cea7S猫头猫 TrackPlayer.play(); 220aaa0db32S猫头猫 } 221b3a3a048S猫头猫} 222