mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-07-04 02:32:09 +08:00
自定义源新增支持local
源的musicUrl
、pic
、lyric
的获取操作
This commit is contained in:
parent
4db5f0394c
commit
ed42640f0d
@ -149,13 +149,14 @@ globalThis.lx_setup = (key, id, name, description, version, author, homepage, ra
|
|||||||
const events = {
|
const events = {
|
||||||
request: null,
|
request: null,
|
||||||
}
|
}
|
||||||
const allSources = ['kw', 'kg', 'tx', 'wy', 'mg']
|
const allSources = ['kw', 'kg', 'tx', 'wy', 'mg', 'local']
|
||||||
const supportQualitys = {
|
const supportQualitys = {
|
||||||
kw: ['128k', '320k', 'flac', 'flac24bit'],
|
kw: ['128k', '320k', 'flac', 'flac24bit'],
|
||||||
kg: ['128k', '320k', 'flac', 'flac24bit'],
|
kg: ['128k', '320k', 'flac', 'flac24bit'],
|
||||||
tx: ['128k', '320k', 'flac', 'flac24bit'],
|
tx: ['128k', '320k', 'flac', 'flac24bit'],
|
||||||
wy: ['128k', '320k', 'flac', 'flac24bit'],
|
wy: ['128k', '320k', 'flac', 'flac24bit'],
|
||||||
mg: ['128k', '320k', 'flac', 'flac24bit'],
|
mg: ['128k', '320k', 'flac', 'flac24bit'],
|
||||||
|
local: [],
|
||||||
}
|
}
|
||||||
const supportActions = {
|
const supportActions = {
|
||||||
kw: ['musicUrl'],
|
kw: ['musicUrl'],
|
||||||
@ -164,7 +165,20 @@ globalThis.lx_setup = (key, id, name, description, version, author, homepage, ra
|
|||||||
wy: ['musicUrl'],
|
wy: ['musicUrl'],
|
||||||
mg: ['musicUrl'],
|
mg: ['musicUrl'],
|
||||||
xm: ['musicUrl'],
|
xm: ['musicUrl'],
|
||||||
|
local: ['musicUrl', 'lyric', 'pic'],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const verifyLyricInfo = (info) => {
|
||||||
|
if (typeof info != 'object' || typeof info.lyric != 'string') throw new Error('failed')
|
||||||
|
if (info.lyric.length > 4096) throw new Error('failed')
|
||||||
|
return {
|
||||||
|
lyric: info.lyric,
|
||||||
|
tlyric: (typeof info.tlyric == 'string' && info.tlyric.length < 4096) ? info.tlyric : null,
|
||||||
|
mlyric: typeof info.mlyric == 'string' && info.mlyric.length < 4096 ? info.mlyric : null,
|
||||||
|
lxlyric: typeof info.lxlyric == 'string' && info.lxlyric.length < 4096 ? info.lxlyric : null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const requestQueue = new Map()
|
const requestQueue = new Map()
|
||||||
let isInitedApi = false
|
let isInitedApi = false
|
||||||
let isShowedUpdateAlert = false
|
let isShowedUpdateAlert = false
|
||||||
@ -208,6 +222,7 @@ globalThis.lx_setup = (key, id, name, description, version, author, homepage, ra
|
|||||||
let result
|
let result
|
||||||
switch (data.action) {
|
switch (data.action) {
|
||||||
case 'musicUrl':
|
case 'musicUrl':
|
||||||
|
if (typeof response != 'string' || response.length > 2048 || !/^https?:/.test(response)) throw new Error('failed')
|
||||||
result = {
|
result = {
|
||||||
source: data.source,
|
source: data.source,
|
||||||
action: data.action,
|
action: data.action,
|
||||||
@ -217,6 +232,21 @@ globalThis.lx_setup = (key, id, name, description, version, author, homepage, ra
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
case 'lyric':
|
||||||
|
result = {
|
||||||
|
source: data.source,
|
||||||
|
action: data.action,
|
||||||
|
data: verifyLyricInfo(response),
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'pic':
|
||||||
|
if (typeof response != 'string' || response.length > 2048 || !/^https?:/.test(response)) throw new Error('failed')
|
||||||
|
result = {
|
||||||
|
source: data.source,
|
||||||
|
action: data.action,
|
||||||
|
data: response,
|
||||||
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
nativeCall(NATIVE_EVENTS_NAMES.response, { requestKey, status: true, result })
|
nativeCall(NATIVE_EVENTS_NAMES.response, { requestKey, status: true, result })
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
|
@ -104,7 +104,6 @@ export default async(setting: LX.AppSetting) => {
|
|||||||
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
// console.log(res)
|
// console.log(res)
|
||||||
if (!/^https?:/.test(res.data.url as string)) throw new Error('Get url failed')
|
|
||||||
return { type, url: res.data.url }
|
return { type, url: res.data.url }
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.log(err.message)
|
console.log(err.message)
|
||||||
@ -113,7 +112,62 @@ export default async(setting: LX.AppSetting) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
case 'lyric':
|
||||||
|
apis[source].getLyric = (songInfo: LX.Music.MusicInfo) => {
|
||||||
|
const requestKey = `request__${Math.random().toString().substring(2)}`
|
||||||
|
return {
|
||||||
|
canceleFn() {
|
||||||
|
// userApiRequestCancel(requestKey)
|
||||||
|
},
|
||||||
|
promise: sendUserApiRequest({
|
||||||
|
requestKey,
|
||||||
|
data: {
|
||||||
|
source,
|
||||||
|
action: 'lyric',
|
||||||
|
info: {
|
||||||
|
type,
|
||||||
|
musicInfo: songInfo,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
||||||
|
}).then(res => {
|
||||||
|
// console.log(res)
|
||||||
|
return res.data
|
||||||
|
}).catch(async err => {
|
||||||
|
console.log(err.message)
|
||||||
|
return Promise.reject(err)
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'pic':
|
||||||
|
apis[source].getPic = (songInfo: LX.Music.MusicInfo) => {
|
||||||
|
const requestKey = `request__${Math.random().toString().substring(2)}`
|
||||||
|
return {
|
||||||
|
canceleFn() {
|
||||||
|
// userApiRequestCancel(requestKey)
|
||||||
|
},
|
||||||
|
promise: sendUserApiRequest({
|
||||||
|
requestKey,
|
||||||
|
data: {
|
||||||
|
source,
|
||||||
|
action: 'pic',
|
||||||
|
info: {
|
||||||
|
type,
|
||||||
|
musicInfo: songInfo,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
||||||
|
}).then(res => {
|
||||||
|
// console.log(res)
|
||||||
|
return res.data
|
||||||
|
}).catch(async err => {
|
||||||
|
console.log(err.message)
|
||||||
|
return Promise.reject(err)
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,11 @@ import { updateListMusics } from '@/core/list'
|
|||||||
import {
|
import {
|
||||||
buildLyricInfo,
|
buildLyricInfo,
|
||||||
getCachedLyricInfo,
|
getCachedLyricInfo,
|
||||||
|
getOnlineOtherSourceLyricByLocal,
|
||||||
getOnlineOtherSourceLyricInfo,
|
getOnlineOtherSourceLyricInfo,
|
||||||
getOnlineOtherSourceMusicUrl,
|
getOnlineOtherSourceMusicUrl,
|
||||||
|
getOnlineOtherSourceMusicUrlByLocal,
|
||||||
|
getOnlineOtherSourcePicByLocal,
|
||||||
getOnlineOtherSourcePicUrl,
|
getOnlineOtherSourcePicUrl,
|
||||||
getOtherSource,
|
getOtherSource,
|
||||||
} from './utils'
|
} from './utils'
|
||||||
@ -73,6 +76,14 @@ export const getMusicUrl = async({ musicInfo, isRefresh, onToggleSource = () =>
|
|||||||
// console.log(path)
|
// console.log(path)
|
||||||
if (path) return path
|
if (path) return path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await getOnlineOtherSourceMusicUrlByLocal(musicInfo, isRefresh).then(({ url, quality, isFromCache }) => {
|
||||||
|
if (!isFromCache) void saveMusicUrl(musicInfo, quality, url)
|
||||||
|
return url
|
||||||
|
})
|
||||||
|
} catch {}
|
||||||
|
|
||||||
onToggleSource()
|
onToggleSource()
|
||||||
const otherSource = await getOtherSourceByLocal(musicInfo)
|
const otherSource = await getOtherSourceByLocal(musicInfo)
|
||||||
if (!otherSource.length) throw new Error('source not found')
|
if (!otherSource.length) throw new Error('source not found')
|
||||||
@ -102,6 +113,12 @@ export const getPicUrl = async({ musicInfo, listId, isRefresh, skipFilePic, onTo
|
|||||||
if (musicInfo.meta.picUrl) return musicInfo.meta.picUrl
|
if (musicInfo.meta.picUrl) return musicInfo.meta.picUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await getOnlineOtherSourcePicByLocal(musicInfo).then(({ url }) => {
|
||||||
|
return url
|
||||||
|
})
|
||||||
|
} catch {}
|
||||||
|
|
||||||
onToggleSource()
|
onToggleSource()
|
||||||
const otherSource = await getOtherSourceByLocal(musicInfo)
|
const otherSource = await getOtherSourceByLocal(musicInfo)
|
||||||
if (!otherSource.length) throw new Error('source not found')
|
if (!otherSource.length) throw new Error('source not found')
|
||||||
@ -143,6 +160,14 @@ export const getLyricInfo = async({ musicInfo, isRefresh, skipFileLyric, onToggl
|
|||||||
if (lyricInfo?.lyric) return buildLyricInfo(lyricInfo)
|
if (lyricInfo?.lyric) return buildLyricInfo(lyricInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
||||||
|
return await getOnlineOtherSourceLyricByLocal(musicInfo, isRefresh).then(({ lyricInfo, isFromCache }) => {
|
||||||
|
if (!isFromCache) void saveLyric(musicInfo, lyricInfo)
|
||||||
|
return buildLyricInfo(lyricInfo)
|
||||||
|
})
|
||||||
|
} catch {}
|
||||||
|
|
||||||
onToggleSource()
|
onToggleSource()
|
||||||
const otherSource = await getOtherSourceByLocal(musicInfo)
|
const otherSource = await getOtherSourceByLocal(musicInfo)
|
||||||
if (!otherSource.length) throw new Error('source not found')
|
if (!otherSource.length) throw new Error('source not found')
|
||||||
|
@ -10,6 +10,7 @@ import { assertApiSupport } from '@/utils/tools'
|
|||||||
import settingState from '@/store/setting/state'
|
import settingState from '@/store/setting/state'
|
||||||
import { requestMsg } from '@/utils/message'
|
import { requestMsg } from '@/utils/message'
|
||||||
import BackgroundTimer from 'react-native-background-timer'
|
import BackgroundTimer from 'react-native-background-timer'
|
||||||
|
import { apis } from '@/utils/musicSdk/api-source'
|
||||||
|
|
||||||
|
|
||||||
const getOtherSourcePromises = new Map()
|
const getOtherSourcePromises = new Map()
|
||||||
@ -145,6 +146,68 @@ export const getCachedLyricInfo = async(musicInfo: LX.Music.MusicInfo): Promise<
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getOnlineOtherSourceMusicUrlByLocal = async(musicInfo: LX.Music.MusicInfoLocal, isRefresh: boolean): Promise<{
|
||||||
|
url: string
|
||||||
|
quality: LX.Quality
|
||||||
|
isFromCache: boolean
|
||||||
|
}> => {
|
||||||
|
if (!await global.lx.apiInitPromise[0]) throw new Error('source init failed')
|
||||||
|
|
||||||
|
const quality = '128k'
|
||||||
|
|
||||||
|
const cachedUrl = await getStoreMusicUrl(musicInfo, quality)
|
||||||
|
if (cachedUrl && !isRefresh) return { url: cachedUrl, quality, isFromCache: true }
|
||||||
|
|
||||||
|
let reqPromise
|
||||||
|
try {
|
||||||
|
reqPromise = apis('local').getMusicUrl(toOldMusicInfo(musicInfo), null).promise
|
||||||
|
} catch (err: any) {
|
||||||
|
reqPromise = Promise.reject(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return reqPromise.then(({ url }: { url: string }) => {
|
||||||
|
return { url, quality, isFromCache: false }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getOnlineOtherSourceLyricByLocal = async(musicInfo: LX.Music.MusicInfoLocal, isRefresh: boolean): Promise<{
|
||||||
|
lyricInfo: LX.Music.LyricInfo
|
||||||
|
isFromCache: boolean
|
||||||
|
}> => {
|
||||||
|
if (!await global.lx.apiInitPromise[0]) throw new Error('source init failed')
|
||||||
|
|
||||||
|
const lyricInfo = await getCachedLyricInfo(musicInfo)
|
||||||
|
if (lyricInfo && !isRefresh) return { lyricInfo, isFromCache: true }
|
||||||
|
|
||||||
|
let reqPromise
|
||||||
|
try {
|
||||||
|
reqPromise = apis('local').getLyric(toOldMusicInfo(musicInfo)).promise
|
||||||
|
} catch (err: any) {
|
||||||
|
reqPromise = Promise.reject(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return reqPromise.then((lyricInfo: LX.Music.LyricInfo) => {
|
||||||
|
return { lyricInfo, isFromCache: false }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getOnlineOtherSourcePicByLocal = async(musicInfo: LX.Music.MusicInfoLocal): Promise<{
|
||||||
|
url: string
|
||||||
|
}> => {
|
||||||
|
if (!await global.lx.apiInitPromise[0]) throw new Error('source init failed')
|
||||||
|
|
||||||
|
let reqPromise
|
||||||
|
try {
|
||||||
|
reqPromise = apis('local').getPic(toOldMusicInfo(musicInfo)).promise
|
||||||
|
} catch (err: any) {
|
||||||
|
reqPromise = Promise.reject(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return reqPromise.then((url: string) => {
|
||||||
|
return { url }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const getPlayQuality = (highQuality: boolean, musicInfo: LX.Music.MusicInfoOnline): LX.Quality => {
|
export const getPlayQuality = (highQuality: boolean, musicInfo: LX.Music.MusicInfoOnline): LX.Quality => {
|
||||||
let type: LX.Quality = '128k'
|
let type: LX.Quality = '128k'
|
||||||
let list = global.lx.qualityList[musicInfo.source]
|
let list = global.lx.qualityList[musicInfo.source]
|
||||||
|
2
src/types/user_api.d.ts
vendored
2
src/types/user_api.d.ts
vendored
@ -1,7 +1,7 @@
|
|||||||
declare namespace LX {
|
declare namespace LX {
|
||||||
namespace UserApi {
|
namespace UserApi {
|
||||||
type UserApiSourceInfoType = 'music'
|
type UserApiSourceInfoType = 'music'
|
||||||
type UserApiSourceInfoActions = 'musicUrl'
|
type UserApiSourceInfoActions = 'musicUrl' | 'lyric' | 'pic'
|
||||||
|
|
||||||
interface UserApiSourceInfo {
|
interface UserApiSourceInfo {
|
||||||
name: string
|
name: string
|
||||||
|
Loading…
x
Reference in New Issue
Block a user