yne / dzr

Accountless deezer.com Player (CLI & VSCode)
The Unlicense
202 stars 13 forks source link

[Feature request] Lyrics at the terminal #18

Closed Eidansoft closed 2 years ago

Eidansoft commented 2 years ago

Is there any possibility to show the lyrics into the terminal at the same time it is playing the song ?? That would be a lovely feature for the terminal/tmux lovers (like me 😸 ) in order to get rid of the oficial app.

Eidansoft commented 2 years ago

Investigating about this, looks like at the SNG_NFO reply there is a field for the lyric: [...] "GENRE_ID": "7", "ISRC": "GBBXH0300037", "LYRICS_ID": 1793618, "PHYSICAL_RELEASE_DATE": "2008-12-01", "PROVIDER_ID": "2", [...]

But no idea to what endpoint asks for that LYRICS_ID. Any suggestion?

yne commented 2 years ago

The webapp use https://pipe.deezer.com/api graphql endpoint to fetch it lyrics

await fetch("https://pipe.deezer.com/api", {
  headers: {
    authorization: "Bearer ...",
    "content-type": "application/json"
  },
  method: "POST",
  body: JSON.encode({
    operationName: "SynchronizedTrackLyrics",
    query: "...see below...",
    variables: {trackId: "1115044"}) // Aqua - Barbie Girl (api.deezer.com/track/1115044)
}).then(r=>r.json())

with the following body payload

query SynchronizedTrackLyrics($trackId: String!) {
  track(trackId: $trackId) {
    ...SynchronizedTrackLyrics
    __typename
  }
}

fragment SynchronizedTrackLyrics on Track {
  id
  lyrics {
    ...Lyrics
    __typename
  }
  album {
    cover {
      small: urls(pictureRequest: {width: 100, height: 100})
      medium: urls(pictureRequest: {width: 264, height: 264})
      large: urls(pictureRequest: {width: 800, height: 800})
      explicitStatus
      __typename
    }
    __typename
  }
  __typename
}

fragment Lyrics on Lyrics {
  id
  copyright
  text
  writers
  synchronizedLines {
    ...LyricsSynchronizedLines
    __typename
  }
  __typename
}

fragment LyricsSynchronizedLines on LyricsSynchronizedLine {
  lrcTimestamp
  line
  lineTranslated
  milliseconds
  duration
  __typename
}

But I don't see how to keep the player synchronised with the lyrics. So you'll have to keep using the webplayer for your karaoke sessions.

yne commented 2 years ago

More compact version

ARL=abcdef12345678...
JWT=$(curl -s 'https://auth.deezer.com/login/arl?i=c&jo=p&rto=n' -Hcookie:arl=$ARL -d '' | jq -r .jwt)
curl -s https://pipe.deezer.com/api -H "authorization: Bearer $JWT" -Hcontent-type:application/json -d '{
  "variables":{"trackId":"370334421"},
  "query":"query($trackId:String\u0021){track(trackId:$trackId){lyrics{text}}}"
}' | jq -r .data.track.lyrics.text

It won't be implemented since it use a private API (a login is required to get an ARL)

Ryan5453 commented 2 years ago

You can use the song.getLyrics endpoint on the gw-light.php API to get lyrics. It takes sng_id as a parameter/data

yne commented 2 years ago

Confirmed working, thank you @ryan5453

I've created a dzr-srt script to output a track lyrics as srt file

This can be used as argument to MPV to get real-time lyrics on the terminal

PLAYER='mpv --sub-file=<(dzr-srt $id) -' dzr /track/14408104

See: https://github.com/yne/dzr#real-time-lyrics

image