mirror of
https://codeberg.org/lucida/lucida.git
synced 2026-11-09 13:07:25 -05:00
add lyrics support to deezer, bump version
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lucida",
|
||||
"version": "2.0.0-46",
|
||||
"version": "2.0.0-47",
|
||||
"description": "A modular music downloader tool",
|
||||
"main": "build/index.js",
|
||||
"type": "module",
|
||||
|
||||
@@ -25,7 +25,8 @@ import {
|
||||
parseAlbum,
|
||||
parseArtist,
|
||||
parseTrack,
|
||||
parsePlaylistMetadata
|
||||
parsePlaylistMetadata,
|
||||
DeezerLyrics
|
||||
} from './parse.js'
|
||||
import { Readable, Transform } from 'stream'
|
||||
import { Blowfish } from 'blowfish-cbc'
|
||||
@@ -51,6 +52,7 @@ interface APIMethod {
|
||||
}
|
||||
'deezer.pageTrack': {
|
||||
DATA: DeezerTrack
|
||||
LYRICS?: DeezerLyrics
|
||||
}
|
||||
'deezer.pagePlaylist': {
|
||||
DATA: DeezerPlaylistMetadata
|
||||
@@ -318,7 +320,7 @@ export default class Deezer implements StreamerWithLogin {
|
||||
|
||||
const data = {
|
||||
metadata: { ...parseAlbum(DATA), trackCount: SONGS.data.length },
|
||||
tracks: SONGS.data.map(parseTrack)
|
||||
tracks: SONGS.data.map((t) => parseTrack(t))
|
||||
}
|
||||
|
||||
if (!data.metadata.trackCount) data.metadata.trackCount = data.tracks.length
|
||||
@@ -345,18 +347,16 @@ export default class Deezer implements StreamerWithLogin {
|
||||
return {
|
||||
type: 'playlist',
|
||||
metadata: parsePlaylistMetadata(playlistMetadata),
|
||||
tracks: playlistTracks.map(parseTrack)
|
||||
tracks: playlistTracks.map((t) => parseTrack(t))
|
||||
}
|
||||
}
|
||||
|
||||
// Track
|
||||
|
||||
async #getTrackData(id: number): Promise<DeezerTrack> {
|
||||
return (
|
||||
await this.#apiCall('deezer.pageTrack', {
|
||||
sng_id: id
|
||||
})
|
||||
).DATA
|
||||
async #getTrackPage(id: number): Promise<APIMethod['deezer.pageTrack']> {
|
||||
return await this.#apiCall('deezer.pageTrack', {
|
||||
sng_id: id
|
||||
})
|
||||
}
|
||||
|
||||
async #getStream(track: DeezerTrack): Promise<GetStreamResponse> {
|
||||
@@ -531,12 +531,12 @@ export default class Deezer implements StreamerWithLogin {
|
||||
}
|
||||
}
|
||||
case 'track': {
|
||||
const track = await this.#getTrackData(id)
|
||||
const trackPage = await this.#getTrackPage(id)
|
||||
return {
|
||||
type: 'track',
|
||||
metadata: parseTrack(track),
|
||||
metadata: parseTrack(trackPage.DATA, trackPage.LYRICS),
|
||||
getStream: () => {
|
||||
return this.#getStream(track)
|
||||
return this.#getStream(trackPage.DATA)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Album, Artist, CoverArtwork, Playlist, Track } from '../../types.js'
|
||||
import { Album, Artist, CoverArtwork, LyricLine, Playlist, Track } from '../../types.js'
|
||||
import { SIZES } from './constants.js'
|
||||
|
||||
export enum DeezerFormat {
|
||||
@@ -69,7 +69,7 @@ export function parseArtist(
|
||||
)
|
||||
|
||||
let parsedTracks
|
||||
if (tracks) parsedTracks = tracks.map(parseTrack)
|
||||
if (tracks) parsedTracks = tracks.map((t) => parseTrack(t))
|
||||
|
||||
let parsedAlbums
|
||||
if (albums) parsedAlbums = albums.map(parseAlbum)
|
||||
@@ -142,7 +142,20 @@ export interface DeezerTrack {
|
||||
FALLBACK?: DeezerTrack
|
||||
}
|
||||
|
||||
export function parseTrack(track: DeezerTrack): Track {
|
||||
export interface DeezerLyrics {
|
||||
LYRICS_ID: string
|
||||
LYRICS_SYNC_JSON: DeezerSyncedLine[]
|
||||
LYRICS_TEXT: string
|
||||
}
|
||||
|
||||
export interface DeezerSyncedLine {
|
||||
lrc_timestamp?: string
|
||||
milliseconds?: string
|
||||
duration?: string
|
||||
line: string
|
||||
}
|
||||
|
||||
export function parseTrack(track: DeezerTrack, lyricsData?: DeezerLyrics): Track {
|
||||
const addt: {
|
||||
regions?: string[]
|
||||
copyright?: string
|
||||
@@ -158,6 +171,39 @@ export function parseTrack(track: DeezerTrack): Track {
|
||||
if (track.SNG_CONTRIBUTORS?.composer) addt.composers = track.SNG_CONTRIBUTORS?.composer
|
||||
if (track.SNG_CONTRIBUTORS?.composer) addt.lyricists = track.SNG_CONTRIBUTORS?.lyricist
|
||||
|
||||
let lyrics
|
||||
if (lyricsData) {
|
||||
const lines: LyricLine[] = []
|
||||
|
||||
const syncedLyrics = lyricsData.LYRICS_SYNC_JSON
|
||||
if (syncedLyrics) {
|
||||
let lastLineEnd = 0
|
||||
for (const line of syncedLyrics) {
|
||||
if (!line.line) {
|
||||
const lastLine = lines[lines.length - 1]
|
||||
if (lastLine) lastLine.endTimeMs = lastLineEnd
|
||||
continue
|
||||
}
|
||||
|
||||
lines.push({
|
||||
text: line.line,
|
||||
startTimeMs: parseInt(line.milliseconds!)
|
||||
})
|
||||
lastLineEnd = parseInt(line.milliseconds!) + parseInt(line.duration!)
|
||||
}
|
||||
} else {
|
||||
lines.push({
|
||||
text: lyricsData.LYRICS_TEXT
|
||||
})
|
||||
}
|
||||
|
||||
lyrics = {
|
||||
id: lyricsData.LYRICS_ID,
|
||||
source: 'deezer',
|
||||
lines
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
title: track.VERSION ? `${track.SNG_TITLE} ${track.VERSION}` : track.SNG_TITLE,
|
||||
id: track.SNG_ID,
|
||||
@@ -174,6 +220,7 @@ export function parseTrack(track: DeezerTrack): Track {
|
||||
}),
|
||||
durationMs: parseInt(track.DURATION) * 1e3,
|
||||
coverArtwork: parseArtwork(track.ALB_PICTURE),
|
||||
lyrics,
|
||||
...addt
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user