Skip to content

Commit

Permalink
feat: 播放页增加歌词显示
Browse files Browse the repository at this point in the history
  • Loading branch information
zonemeen committed Jun 8, 2023
1 parent 360f2ae commit 8c8de4d
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 35 deletions.
9 changes: 9 additions & 0 deletions src/qrcode/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import qrcode from 'qrcode-terminal'
import open from 'open'
import express, { NextFunction, Request, Response } from 'express'
import search from '../services/search'
import lyric from '../services/lyric'
import { getNetworkAddress } from '../utils'
import { ServiceType, SearchProps } from '../types'

Expand Down Expand Up @@ -55,6 +56,14 @@ export default async ({
pageNum,
pageSize,
} as SearchProps)
const lyricList = await Promise.all(
searchSongs.map(async ({ lyricUrl }: { lyricUrl: string }) => {
return await lyric[service as ServiceType](null, lyricUrl)
})
)
searchSongs.forEach((song: any, index: number) => {
song.lrc = lyricList[index]
})
res.send({ searchSongs, totalSongCount })
})

Expand Down
14 changes: 10 additions & 4 deletions src/services/lyric/kugou.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@ import got from 'got'
import { createWriteStream } from 'fs'
import { decodeLyric, parseLyric } from '../../utils'

export default async (lrcPath: string, lyricDownloadUrl: string) => {
export default async (lrcPath: string | null, lyricDownloadUrl: string) => {
let lrc, lrcFileWriteStream
const { candidates } = await got(lyricDownloadUrl).json()
const lrcFileWriteStream = createWriteStream(lrcPath)
if (lrcPath) {
lrcFileWriteStream = createWriteStream(lrcPath)
}
if (candidates.length) {
const { id, accesskey } = candidates[0]
const lyricDetailUrl = `http://lyrics.kugou.com/download?ver=1&client=pc&id=${id}&accesskey=${accesskey}&fmt=krc&charset=utf8`
const { content = '' } = await got(lyricDetailUrl).json()
const decode = await decodeLyric(content)
const { lyric = '' } = parseLyric(decode as string)
lrcFileWriteStream.write(lyric)
lrcFileWriteStream?.write(lyric)
lrc = lyric
} else {
lrcFileWriteStream.write(`[00:00.00]${lrcPath.split('.')[0]}`)
lrc = `[00:00.00]${lrcPath?.split('.')[0]}`
lrcFileWriteStream?.write(lrc)
}
if (!lrcPath) return lrc
}
25 changes: 21 additions & 4 deletions src/services/lyric/kuwo.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
import got from 'got'
import { createWriteStream } from 'fs'

export default async (lrcPath: string, lyricDownloadUrl: string) => {
function convertToStandardTime(timeStr: string) {
const timeInSec = parseFloat(timeStr)
const hours = Math.floor(timeInSec / 3600)
const minutes = Math.floor((timeInSec - hours * 3600) / 60)
const seconds = Math.floor(timeInSec - hours * 3600 - minutes * 60)
const milliseconds = Math.round((timeInSec - Math.floor(timeInSec)) * 100)

const minutesStr = minutes.toString().padStart(2, '0')
const secondsStr = seconds.toString().padStart(2, '0')
const millisecondsStr = milliseconds.toString().padStart(2, '0')

return `${minutesStr}:${secondsStr}.${millisecondsStr}`
}

export default async (lrcPath: string | null, lyricDownloadUrl: string) => {
const {
data: { lrclist },
} = await got(lyricDownloadUrl).json()
let lyric = ''
for (const lrc of lrclist) {
lyric += `[${lrc.time}] ${lrc.lineLyric}\n`
lyric += `[${convertToStandardTime(lrc.time)}]${lrc.lineLyric}\n`
}
if (lrcPath) {
const lrcFileWriteStream = createWriteStream(lrcPath)
lrcFileWriteStream.write(lyric)
}
const lrcFileWriteStream = createWriteStream(lrcPath)
lrcFileWriteStream.write(lyric)
if (!lrcPath) return lyric
}
17 changes: 15 additions & 2 deletions src/services/lyric/migu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@ import got from 'got'
import { pipeline } from 'stream/promises'
import { createWriteStream } from 'fs'

export default async (lrcPath: string, lyricDownloadUrl: string) => {
await pipeline(got.stream(lyricDownloadUrl), createWriteStream(lrcPath))
async function streamToString(stream: any) {
const chunks = []
for await (const chunk of stream) {
chunks.push(Buffer.from(chunk))
}
return Buffer.concat(chunks).toString('utf-8')
}

export default async (lrcPath: string | null, lyricDownloadUrl: string) => {
const stream = got.stream(lyricDownloadUrl)
if (lrcPath) {
await pipeline(stream, createWriteStream(lrcPath))
} else {
return await streamToString(stream)
}
}
14 changes: 10 additions & 4 deletions src/services/lyric/wangyi.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import got from 'got'
import { createWriteStream } from 'fs'

export default async (lrcPath: string, lyricDownloadUrl: string) => {
export default async (lrcPath: string | null, lyricDownloadUrl: string) => {
let lrc, lrcFileWriteStream
const {
lrc: { lyric },
} = await got(lyricDownloadUrl).json()
const lrcFileWriteStream = createWriteStream(lrcPath)
if (lrcPath) {
lrcFileWriteStream = createWriteStream(lrcPath)
}
if (lyric) {
lrcFileWriteStream.write(lyric)
lrcFileWriteStream?.write(lyric)
lrc = lyric
} else {
lrcFileWriteStream.write(`[00:00.00]${lrcPath.split('.')[0]}`)
lrc = `[00:00.00]${lrcPath?.split('.')[0]}`
lrcFileWriteStream?.write(lrc)
}
if (!lrcPath) return lrc
}
46 changes: 25 additions & 21 deletions template/music.html
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
dataSource: [],
loading: false,
downLoading: false,
scrollHeight: window.innerHeight - 260,
scrollHeight: window.innerHeight - 280,
services: [
{
label: '咪咕',
Expand Down Expand Up @@ -156,6 +156,7 @@
container: document.getElementById('aplayer'),
listMaxHeight: 450,
listFolded: true,
lrcType: 1,
audio: [],
})
},
Expand Down Expand Up @@ -188,41 +189,44 @@
const { searchSongs, totalSongCount } = res.data
const list = searchSongs
.filter(({ disabled }) => !disabled)
.map(({ id, DC_TARGETID, songName, url, imgItems, hts_MVPIC, artists }) => {
const name = songName.split('-')[1].split('.')[0].trim()
const artist = songName.split('-')[0].trim()
return {
name,
artist,
url,
id: service === 'kuwo' ? DC_TARGETID : id,
cover:
service === 'migu'
? imgItems[0]?.img
: service === 'kuwo'
? hts_MVPIC
: service === 'wangyi'
? artists[0]?.img1v1Url
: '',
.map(
({ id, DC_TARGETID, hash, songName, url, imgItems, hts_MVPIC, artists, lrc }) => {
const name = songName.split('-')[1].split('.')[0].trim()
const artist = songName.split('-')[0].trim()
return {
name,
artist,
lrc,
url,
id: service === 'kuwo' ? DC_TARGETID : service === 'kugou' ? hash : id,
cover:
service === 'migu'
? imgItems[0]?.img
: service === 'kuwo'
? hts_MVPIC
: service === 'wangyi'
? artists[0]?.img1v1Url
: '',
}
}
})
this.player.list.add(list)
)
this.dataSource = searchSongs.map((song) => {
song.name = `${song.songName.split('-')[1].split('.')[0].trim()} - ${song.songName
.split('-')[0]
.trim()}`
return song
})
this.pagination.total = ~~totalSongCount
this.player.list.add(list)
},
onParamsChange({ current }) {
this.params.pageNum = current ?? 1
this.pagination.current = current ?? 1
this.getDataSource()
},
onButtonClick({ id: songId, DC_TARGETID }) {
onButtonClick({ id: songId, DC_TARGETID, hash }) {
const index = this.player.list.audios.findIndex(
({ id }) => id === songId ?? DC_TARGETID
({ id }) => id === (songId ?? DC_TARGETID ?? hash)
)
this.player.list.switch(index)
this.player.play()
Expand Down

1 comment on commit 8c8de4d

@vercel
Copy link

@vercel vercel bot commented on 8c8de4d Jun 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

musicn – ./

musicn-zonemeen.vercel.app
musicn-git-main-zonemeen.vercel.app
musicn-one.vercel.app

Please sign in to comment.