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,

View file

@ -2,9 +2,11 @@ CREATE TABLE IF NOT EXISTS "AccountData" ("id" text NOT NULL,"json" text NOT NUL
CREATE TABLE IF NOT EXISTS "Album" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" int NOT NULL, PRIMARY KEY (id));
CREATE TABLE IF NOT EXISTS "ArtistAlbum" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" int NOT NULL, PRIMARY KEY (id));
CREATE TABLE IF NOT EXISTS "Artist" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" int NOT NULL, PRIMARY KEY (id));
CREATE TABLE IF NOT EXISTS "Audio" ("id" integer NOT NULL,"br" int NOT NULL,"type" text NOT NULL,"source" text NOT NULL,"updatedAt" int NOT NULL, PRIMARY KEY (id));
CREATE TABLE IF NOT EXISTS "Lyric" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" integer NOT NULL, PRIMARY KEY (id));
CREATE TABLE IF NOT EXISTS "Playlist" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" int NOT NULL, PRIMARY KEY (id));
CREATE TABLE IF NOT EXISTS "Track" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" int NOT NULL, PRIMARY KEY (id));
CREATE TABLE IF NOT EXISTS "CoverColor" ("id" integer NOT NULL,"color" text NOT NULL, PRIMARY KEY (id));
CREATE TABLE IF NOT EXISTS "AppData" ("id" text NOT NULL,"value" text, PRIMARY KEY (id));
CREATE TABLE IF NOT EXISTS "CoverColor" ("id" integer NOT NULL,"color" text NOT NULL, "queriedAt" int NOT NULL, PRIMARY KEY (id));
CREATE TABLE IF NOT EXISTS "Audio" ("id" integer NOT NULL,"br" int NOT NULL,"type" text NOT NULL,"source" text NOT NULL,"updatedAt" int NOT NULL, "queriedAt" int NOT NULL, PRIMARY KEY (id));
CREATE TABLE IF NOT EXISTS "VideoCover" ("id" integer NOT NULL,"url" text NOT NULL,"updatedAt" int NOT NULL, "queriedAt" int NOT NULL, PRIMARY KEY (id));

View file

@ -9,7 +9,7 @@
"dev": "node scripts/build.main.mjs --watch",
"build": "node scripts/build.main.mjs",
"pack": "electron-builder build -c .electron-builder.config.js",
"test:types": "tsc --noEmit --project src/main/tsconfig.json",
"test:types": "tsc --noEmit --project ./tsconfig.json",
"lint": "eslint --ext .ts,.js ./",
"format": "prettier --write './**/*.{ts,js,tsx,jsx}'"
},
@ -29,6 +29,7 @@
"electron-store": "^8.0.1",
"express": "^4.18.1",
"fast-folder-size": "^1.7.0",
"m3u8-parser": "^4.7.1",
"pretty-bytes": "^6.0.0"
},
"devDependencies": {