mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-07-03 17:22:09 +08:00
180 lines
5.2 KiB
JavaScript
180 lines
5.2 KiB
JavaScript
// import BackgroundTimer from 'react-native-background-timer'
|
|
import { httpGet, httpFetch } from '../../request'
|
|
export { default as decodeLyric } from './decodeLyric'
|
|
|
|
const kw_token = {
|
|
token: null,
|
|
isGetingToken: false,
|
|
}
|
|
|
|
// const translationMap = {
|
|
// "{'": '{"',
|
|
// "'}\n": '"}',
|
|
// "'}": '"}',
|
|
// "':'": '":"',
|
|
// "','": '","',
|
|
// "':{'": '":{"',
|
|
// "':['": '":["',
|
|
// "'}],'": '"}],"',
|
|
// "':[{'": '":[{"',
|
|
// "'},'": '"},"',
|
|
// "'},{'": '"},{"',
|
|
// "':[],'": '":[],"',
|
|
// "':{},'": '":{},"',
|
|
// "'}]}": '"}]}',
|
|
// }
|
|
|
|
// export const objStr2JSON = str => {
|
|
// return JSON.parse(str.replace(/(^{'|'}\n$|'}$|':'|','|':\[{'|'}\],'|':{'|'},'|'},{'|':\['|':\[\],'|':{},'|'}]})/g, s => translationMap[s]))
|
|
// }
|
|
|
|
export const objStr2JSON = str => {
|
|
return JSON.parse(str.replace(/('(?=(,\s*')))|('(?=:))|((?<=([:,]\s*))')|((?<={)')|('(?=}))/g, '"'))
|
|
}
|
|
|
|
|
|
export const formatSinger = rawData => rawData.replace(/&/g, '、')
|
|
|
|
export const matchToken = headers => {
|
|
try {
|
|
return headers['set-cookie'].match(/kw_token=(\w+)/)[1]
|
|
} catch (err) {
|
|
return null
|
|
}
|
|
}
|
|
|
|
const wait = time => new Promise(resolve => setTimeout(() => resolve(), time))
|
|
|
|
|
|
export const getToken = (retryNum = 0) => new Promise((resolve, reject) => {
|
|
if (retryNum > 2) return Promise.reject(new Error('try max num'))
|
|
|
|
if (kw_token.isGetingToken) return wait(1000).then(() => getToken(retryNum).then(token => resolve(token)))
|
|
if (kw_token.token) return resolve(kw_token.token)
|
|
kw_token.isGetingToken = true
|
|
httpGet('http://www.kuwo.cn/', (err, resp) => {
|
|
kw_token.isGetingToken = false
|
|
if (err) return getToken(++retryNum)
|
|
if (resp.statusCode != 200) return reject(new Error('获取失败'))
|
|
const token = kw_token.token = matchToken(resp.headers)
|
|
resolve(token)
|
|
})
|
|
})
|
|
|
|
export const tokenRequest = async(url, options = {}) => {
|
|
let token = kw_token.token
|
|
if (!token) token = await getToken()
|
|
if (!options.headers) {
|
|
options.headers = {
|
|
Referer: 'http://www.kuwo.cn/',
|
|
csrf: token,
|
|
cookie: 'kw_token=' + token,
|
|
}
|
|
}
|
|
const requestObj = httpFetch(url, options)
|
|
requestObj.promise = requestObj.promise.then(resp => {
|
|
// console.log(resp)
|
|
if (resp.statusCode == 200) {
|
|
kw_token.token = matchToken(resp.headers)
|
|
}
|
|
return resp
|
|
})
|
|
return requestObj
|
|
}
|
|
|
|
export const lrcTools = {
|
|
rxps: {
|
|
wordLine: /^(\[\d{1,2}:.*\d{1,4}\])\s*(\S+(?:\s+\S+)*)?\s*/,
|
|
tagLine: /\[(ver|ti|ar|al|offset|by|kuwo):\s*(\S+(?:\s+\S+)*)\s*\]/,
|
|
wordTimeAll: /<(-?\d+),(-?\d+)(?:,-?\d+)?>/g,
|
|
wordTime: /<(-?\d+),(-?\d+)(?:,-?\d+)?>/,
|
|
},
|
|
offset: 1,
|
|
offset2: 1,
|
|
isOK: false,
|
|
lines: [],
|
|
tags: [],
|
|
getWordInfo(str, str2, prevWord) {
|
|
const offset = parseInt(str)
|
|
const offset2 = parseInt(str2)
|
|
let startTime = Math.abs((offset + offset2) / (this.offset * 2))
|
|
let endTime = Math.abs((offset - offset2) / (this.offset2 * 2)) + startTime
|
|
if (prevWord) {
|
|
if (startTime < prevWord.endTime) {
|
|
prevWord.endTime = startTime
|
|
if (prevWord.startTime > prevWord.endTime) {
|
|
prevWord.startTime = prevWord.endTime
|
|
}
|
|
|
|
prevWord.newTimeStr = `<${prevWord.startTime},${prevWord.endTime - prevWord.startTime}>`
|
|
// console.log(prevWord)
|
|
}
|
|
}
|
|
return {
|
|
startTime,
|
|
endTime,
|
|
timeStr: `<${startTime},${endTime - startTime}>`,
|
|
}
|
|
},
|
|
parseLine(line) {
|
|
if (line.length < 6) return
|
|
let result = this.rxps.wordLine.exec(line)
|
|
if (result) {
|
|
const time = result[1]
|
|
let words = result[2]
|
|
if (words == null) {
|
|
words = ''
|
|
}
|
|
const wordTimes = words.match(this.rxps.wordTimeAll)
|
|
if (!wordTimes) return
|
|
// console.log(wordTimes)
|
|
let preTimeInfo
|
|
for (const timeStr of wordTimes) {
|
|
const result = this.rxps.wordTime.exec(timeStr)
|
|
const wordInfo = this.getWordInfo(result[1], result[2], preTimeInfo)
|
|
words = words.replace(timeStr, wordInfo.timeStr)
|
|
if (preTimeInfo?.newTimeStr) words = words.replace(preTimeInfo.timeStr, preTimeInfo.newTimeStr)
|
|
preTimeInfo = wordInfo
|
|
}
|
|
this.lines.push(time + words)
|
|
return
|
|
}
|
|
result = this.rxps.tagLine.exec(line)
|
|
if (!result) return
|
|
if (result[1] == 'kuwo') {
|
|
let content = result[2]
|
|
if (content != null && content.includes('][')) {
|
|
content = content.substring(0, content.indexOf(']['))
|
|
}
|
|
const valueOf = parseInt(content, 8)
|
|
this.offset = Math.trunc(valueOf / 10)
|
|
this.offset2 = Math.trunc(valueOf % 10)
|
|
if (this.offset == 0 || Number.isNaN(this.offset) || this.offset2 == 0 || Number.isNaN(this.offset2)) {
|
|
this.isOK = false
|
|
}
|
|
} else {
|
|
this.tags.push(line)
|
|
}
|
|
},
|
|
parse(lrc) {
|
|
// console.log(lrc)
|
|
const lines = lrc.split(/\r\n|\r|\n/)
|
|
const tools = Object.create(this)
|
|
tools.isOK = true
|
|
tools.offset = 1
|
|
tools.offset2 = 1
|
|
tools.lines = []
|
|
tools.tags = []
|
|
|
|
for (const line of lines) {
|
|
if (!tools.isOK) throw new Error('failed')
|
|
tools.parseLine(line)
|
|
}
|
|
if (!tools.lines.length) return ''
|
|
let lrcs = tools.lines.join('\n')
|
|
if (tools.tags.length) lrcs = `${tools.tags.join('\n')}\n${lrcs}`
|
|
// console.log(lrcs)
|
|
return lrcs
|
|
},
|
|
}
|