feat: updates

This commit is contained in:
qier222 2022-06-12 15:29:14 +08:00
parent 196a974a64
commit 8f4c3d8e5b
No known key found for this signature in database
GPG key ID: 9C85007ED905F14D
24 changed files with 572 additions and 93 deletions

View file

@ -0,0 +1,84 @@
import { logger } from '@sentry/utils'
import axios from 'axios'
// 'https://mvod.itunes.apple.com/itunes-assets/HLSMusic116/v4/de/52/95/de52957b-fcf1-ae96-b114-0445cb8c41d4/P359420813_default.m3u8'
const searchAlbum = async (
keyword: string
): Promise<
| {
id: string
href: string
attributes: {
artistName: string
url: string
name: string
editorialNotes?: {
standard: string
short: string
}
}
}
| undefined
> => {
const r = await axios.get(
`https://amp-api.music.apple.com/v1/catalog/cn/search`,
{
params: {
term: keyword,
l: 'zh-cn',
platform: 'web',
types: 'albums',
limit: 1,
},
headers: {
authorization: 'Bearer xxxxxx', // required token
},
}
)
return r.data?.results?.albums?.data?.[0]
}
export const getCoverVideo = async ({
name,
artists,
}: {
name: string
artists: string[]
}): Promise<string | undefined> => {
const keyword = `${artists.join(' ')} ${name}`
logger.debug(`[appleMusic] getCoverVideo: ${keyword}`)
const album = await searchAlbum(keyword).catch(e => {
console.log(e)
logger.debug('[appleMusic] Search album error', e)
})
const url = album?.attributes.url
if (!url) {
logger.info('[appleMusic] no url')
return
}
let { data: html } = await axios.get(url)
if (!html) return
const regex =
/<script type="fastboot\/shoebox" id="shoebox-media-api-cache-amp-music">(.*?)<\/script>/
html = html
.match(regex)[0]
.replace(
'<script type="fastboot/shoebox" id="shoebox-media-api-cache-amp-music">',
''
)
.replace('</script>', '')
html = JSON.parse(html)
const data = JSON.parse(html[Object.keys(html)[1]])
const m3u8 =
data?.d?.[0]?.attributes?.editorialVideo?.motionSquareVideo1x1?.video
logger.debug(`[appleMusic] ${m3u8}`)
return m3u8
}

View file

@ -31,8 +31,9 @@ class Cache {
break
}
case APIs.Track: {
if (!data.songs) return
const tracks = (data as FetchTracksResponse).songs.map(t => ({
const res = data as FetchTracksResponse
if (!res.songs) return
const tracks = res.songs.map(t => ({
id: t.id,
json: JSON.stringify(t),
updatedAt: Date.now(),
@ -106,6 +107,16 @@ class Cache {
db.upsert(Tables.CoverColor, {
id: data.id,
color: data.color,
queriedAt: Date.now(),
})
break
}
case APIs.VideoCover: {
if (!data.id) return
db.upsert(Tables.VideoCover, {
id: data.id,
url: data.url || 'no',
queriedAt: Date.now(),
})
}
}
@ -196,6 +207,10 @@ class Cache {
if (isNaN(Number(params?.id))) return
return db.find(Tables.CoverColor, params.id)?.color
}
case APIs.VideoCover: {
if (isNaN(Number(params?.id))) return
return db.find(Tables.VideoCover, params.id)?.url
}
}
}
@ -278,7 +293,7 @@ class Cache {
br,
type: type as TablesStructures[Tables.Audio]['type'],
source,
updatedAt: Date.now(),
queriedAt: Date.now(),
})
log.info(`[cache] cacheAudio ${id}-${br}.${type}`)

View file

@ -18,6 +18,7 @@ export const enum Tables {
AccountData = 'AccountData',
CoverColor = 'CoverColor',
AppData = 'AppData',
VideoCover = 'VideoCover',
}
interface CommonTableStructure {
id: number
@ -50,16 +51,22 @@ export interface TablesStructures {
| 'qq'
| 'bilibili'
| 'joox'
updatedAt: number
queriedAt: number
}
[Tables.CoverColor]: {
id: number
color: string
queriedAt: number
}
[Tables.AppData]: {
id: 'appVersion' | 'skippedVersion'
value: string
}
[Tables.VideoCover]: {
id: number
url: string
queriedAt: number
}
}
type TableNames = keyof TablesStructures

View file

@ -12,6 +12,7 @@ import { Thumbar } from './windowsTaskbar'
import fastFolderSize from 'fast-folder-size'
import path from 'path'
import prettyBytes from 'pretty-bytes'
import { getCoverVideo } from './appleMusic'
const on = <T extends keyof IpcChannelsParams>(
channel: T,
@ -20,6 +21,16 @@ const on = <T extends keyof IpcChannelsParams>(
ipcMain.on(channel, listener)
}
const handle = <T extends keyof IpcChannelsParams>(
channel: T,
listener: (
event: Electron.IpcMainInvokeEvent,
params: IpcChannelsParams[T]
) => void
) => {
return ipcMain.handle(channel, listener)
}
export function initIpcMain(
win: BrowserWindow | null,
tray: YPMTray | null,
@ -143,6 +154,22 @@ function initOtherIpcMain() {
)
})
/**
*
*/
on(IpcChannels.SetVideoCover, (event, args) => {
const { id, url } = args
cache.set(APIs.VideoCover, { id, url })
})
/**
*
*/
on(IpcChannels.GetVideoCover, (event, args) => {
const { id } = args
event.returnValue = cache.get(APIs.VideoCover, { id })
})
/**
* tables到json文件便table大小dev环境
*/

View file

@ -11,6 +11,7 @@ contextBridge.exposeInMainWorld('log', log)
contextBridge.exposeInMainWorld('ipcRenderer', {
sendSync: ipcRenderer.sendSync,
invoke: ipcRenderer.invoke,
send: ipcRenderer.send,
on: (
channel: IpcChannels,