1import PluginManager from '@/core/pluginManager'; 2import minDistance from './minDistance'; 3 4/** 5 * 6 * @param musicItem 音乐类型 7 * @param type 媒体类型 8 * @param abortFunction 如果函数为true,则中断 9 * @returns 10 */ 11export default async function <T extends ICommon.SupportMediaType>( 12 musicItem: IMusic.IMusicItem, 13 type: T = 'music' as T, 14 abortFunction?: () => boolean, 15): Promise<ICommon.SupportMediaItemBase[T] | null> { 16 const keyword = musicItem.alias || musicItem.title; 17 const plugins = PluginManager.getSearchablePlugins(type); 18 19 let distance = Infinity; 20 let minDistanceMusicItem; 21 let targetPlugin; 22 23 const startTime = Date.now(); 24 25 for (let plugin of plugins) { 26 // 超时时间:8s 27 if (abortFunction?.() || Date.now() - startTime > 8000) { 28 break; 29 } 30 if (plugin.name === musicItem.platform) { 31 continue; 32 } 33 const results = await plugin.methods 34 .search(keyword, 1, type) 35 .catch(() => null); 36 37 // 取前两个 38 const firstTwo = results?.data?.slice(0, 2) || []; 39 40 for (let item of firstTwo) { 41 if (item.title === keyword && item.artist === musicItem.artist) { 42 distance = 0; 43 minDistanceMusicItem = item; 44 targetPlugin = plugin; 45 break; 46 } else { 47 const dist = 48 minDistance(keyword, musicItem.title) + 49 minDistance(item.artist, musicItem.artist); 50 if (dist < distance) { 51 distance = dist; 52 minDistanceMusicItem = item; 53 targetPlugin = plugin; 54 } 55 } 56 } 57 58 if (distance === 0) { 59 break; 60 } 61 } 62 if (minDistanceMusicItem && targetPlugin) { 63 return minDistanceMusicItem as ICommon.SupportMediaItemBase[T]; 64 } 65 66 return null; 67} 68