diff --git a/README.md b/README.md index bfef8c8..2204fd6 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,28 @@ You may also define the playlist directory using the `PLAYLIST_DIRECTORY` enviro In `share/playlists` you find example playlists. Thus, the command `PLAYLIST_DIRECTORY=share/playlists fuzic` launches this application with access to these example playlists. +📜 Lyrics +--------- +By using the key `L` (normal mode), the lyrics of the selected track are displayed. +The lyrics are taken from (in that order) +1. the lyrics stored using `fuzic`, or +2. from the `.lrc` file with the same name as the audio file, or +3. from the audio-file tags (requires `ffprobe`), or +4. from a custom script. + +To specify the custom script, you can set the `LYRICS_FETCH_CUSTOM` environment variable to point to an executable. +The executable reads a JSON string on the standard input, and is supposed to print the lyrics (see `share/lyrics/example.sh`). + +You may also skip the first three sources and directly make a call to your custom script by using the key `Y` (normal mode). + +The key `alt-L` opens the lyrics in a new window using the `EDITOR`. +This requires one of the following terminal emulators (`kitty`, `x-terminal-emulator`, `gnome-terminal`, `xterm`). +If you use another terminal emulator, you may specify the environment variable `EXTERNALEDIT` to hold the string such that +```sh +$ExTERNALEDIT "$file" +``` +spawns a text editor with `$file` loaded inside a terminal emulator. + 🧭 Planned Features ------------------- The following features are planned: diff --git a/share/lyrics/example.sh b/share/lyrics/example.sh new file mode 100755 index 0000000..bf65748 --- /dev/null +++ b/share/lyrics/example.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +# Example script for `fuzic` to display the lyrics of a track. This script +# reads from stdin a JSON string and stores it in the variable `j`. The +# variable `tj` contains the JSON string of the track. +j="$(cat)" +tj="$(echo "$j" | jq -r '.trackid as $tid | .release.media[].tracks[] | select(.id == $tid)')" +# The following four variables are self-explanatory: +track_name="$(echo "$tj" | jq -r '.title')" +artist_name="$(echo "$tj" | jq -r '."artist-credit" | map([.name, .joinphrase] | join("")) | join("")')" +album_name="$(echo "$j" | jq -r '.release.title')" +duration="$(echo "$tj" | jq -r '.length / 1000 | round')" +# Now, you may call an API to fetch the lyrics for this track, +# +# curl \ +# --get \ +# --silent \ +# --data-urlencode "track_name=$track_name" \ +# --data-urlencode "artist_name=$artist_name" \ +# --data-urlencode "album_name=$album_name" \ +# --data-urlencode "duration=$duration" \ +# "$URL" +# +# or simply print a template to write the lyrics yourself: +printf "Lyrics '%s' by '%s' (album: %s, duration: %s seconds)\n" "$track_name" "$artist_name" "$album_name" "$duration" diff --git a/src/sh/lyrics.sh b/src/sh/lyrics.sh index ec74154..1d40bdc 100644 --- a/src/sh/lyrics.sh +++ b/src/sh/lyrics.sh @@ -17,10 +17,9 @@ if [ ! "${LYRICS_LOADED:-}" ]; then # Custom command to fetch lyrics # - # This command reads from stdin the json object of the track and prints the - # lyrics. - LYRICS_FETCH_CUSTOM="${LYRICS_FETCH_CUSTOM:-"$JQ '.trackid as \$tid | .release.media[].tracks[] | select(.id == \$tid) | .title'"}" - #LYRICS_FETCH_CUSTOM="${LYRICS_FETCH_CUSTOM:-"$JQ '.trackid as \$trid | \"Lyrics for \" + .media[].tracks[] | select(.id == \$trid) | .title'"}" + # This command reads from stdin the json object of the release and prints the + # lyrics of the track. + LYRICS_FETCH_CUSTOM="${LYRICS_FETCH_CUSTOM:-""}" export LYRICS_FETCH_CUSTOM export LYRICS_LOADED=1 @@ -51,13 +50,21 @@ store_lyrics() { # # @argument $1: MusicBrainz release ID # @argument $2: MusicBrainz track ID +# +# The custom script is executed only if the environment variable is set. Else +# the message stored in `$LYRICS_NO_LYRICS` is saved. store_lyrics_custom() { rlid="${1:-}" mbid="${2:-}" - mb_release "$rlid" | - $JQ --arg mbid "$mbid" '{release: ., trackid: $mbid}' | - sh -c "$LYRICS_FETCH_CUSTOM" | - store_lyrics "$mbid" + if [ "$LYRICS_FETCH_CUSTOM" ]; then + mb_release "$rlid" | + $JQ --arg mbid "$mbid" '{release: ., trackid: $mbid}' | + sh -c "$LYRICS_FETCH_CUSTOM" | + store_lyrics "$mbid" + else + echo "$LYRICS_NO_LYRICS" | + store_lyrics "$mbid" + fi } # Print lyrics diff --git a/src/sh/theme.sh b/src/sh/theme.sh index 8c51ff6..8ad5647 100644 --- a/src/sh/theme.sh +++ b/src/sh/theme.sh @@ -399,5 +399,10 @@ if [ ! "${THEME_LOADED:-}" ]; then PLYSTORE_PLAYLIST="${PLYSTORE_PLAYLIST:-"🎼 ${CPURPLE}%f${OFF}"}" export TITLE_PLYLST TITLE_PLYLST_STORE PLYSTORE_PLAYLIST + # Lyrics + # ====== + LYRICS_NO_LYRICS="${LYRICS_NO_LYRICS:-"(no lyrics)"}" + export LYRICS_NO_LYRICS + export THEME_LOADED=1 fi