Compare commits
4 Commits
4343521a46
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| ed12cef7e4 | |||
| 06485fbce7 | |||
| 214a1cda4c | |||
| d13436b963 |
27
README.md
27
README.md
@@ -12,6 +12,7 @@ Control playback from your terminal while browsing the vast world of music relea
|
|||||||
- Handle metadata without touching your audio files
|
- Handle metadata without touching your audio files
|
||||||
- Fast and hackable application with [vim](https://www.vim.org)-like keybindings
|
- Fast and hackable application with [vim](https://www.vim.org)-like keybindings
|
||||||
- Save and load playlists
|
- Save and load playlists
|
||||||
|
- Lyrics support
|
||||||
|
|
||||||
🎞️ Screenshot
|
🎞️ Screenshot
|
||||||
-------------
|
-------------
|
||||||
@@ -19,7 +20,7 @@ Control playback from your terminal while browsing the vast world of music relea
|
|||||||
The MusicBrainz database is automatically searched after entering a query.
|
The MusicBrainz database is automatically searched after entering a query.
|
||||||
In the screenshot below, the emoji 🔆 indicates that some tracks of _Mc Solaar_ are available in the local music library.
|
In the screenshot below, the emoji 🔆 indicates that some tracks of _Mc Solaar_ are available in the local music library.
|
||||||
They are played by hitting `<enter>`.
|
They are played by hitting `<enter>`.
|
||||||

|

|
||||||
|
|
||||||
### Browse Local Music Library
|
### Browse Local Music Library
|
||||||
Here, we fuzzily search an album of _Daft Punk._
|
Here, we fuzzily search an album of _Daft Punk._
|
||||||
@@ -119,7 +120,7 @@ $ fuzic --decorate ~/Music/Daft\ Punk/Random\ Access\ Memories
|
|||||||
Info: Decorating /home/amin/Music/Daft Punk/Random Access Memories as release 5000a285-b67e-4cfc-b54b-2b98f1810d2e
|
Info: Decorating /home/amin/Music/Daft Punk/Random Access Memories as release 5000a285-b67e-4cfc-b54b-2b98f1810d2e
|
||||||
$ fuzic --decorate-as ~/Music/Mc\ Solaar/Prose\ Combat 69e5cf67-7cea-4fe8-9129-9779f0a93d69
|
$ fuzic --decorate-as ~/Music/Mc\ Solaar/Prose\ Combat 69e5cf67-7cea-4fe8-9129-9779f0a93d69
|
||||||
Info: Decorating /home/amin/Music/Mc Solaar/Prose Combat as the release Prose Combat by MC Solaar
|
Info: Decorating /home/amin/Music/Mc Solaar/Prose Combat as the release Prose Combat by MC Solaar
|
||||||
Info: We discovered the following associatoin:
|
Info: We discovered the following association:
|
||||||
Track 'Aubade' File './01 Aubade.m4a'
|
Track 'Aubade' File './01 Aubade.m4a'
|
||||||
Track 'Obsolète' File './02 Obsolète.m4a'
|
Track 'Obsolète' File './02 Obsolète.m4a'
|
||||||
Track 'Nouveau western' File './03 Nouveau western.m4a'
|
Track 'Nouveau western' File './03 Nouveau western.m4a'
|
||||||
@@ -176,6 +177,28 @@ You may also define the playlist directory using the `PLAYLIST_DIRECTORY` enviro
|
|||||||
In `share/playlists` you find example playlists.
|
In `share/playlists` you find example playlists.
|
||||||
Thus, the command `PLAYLIST_DIRECTORY=share/playlists fuzic` launches this application with access to these 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
|
🧭 Planned Features
|
||||||
-------------------
|
-------------------
|
||||||
The following features are planned:
|
The following features are planned:
|
||||||
|
|||||||
25
share/lyrics/example.sh
Executable file
25
share/lyrics/example.sh
Executable file
@@ -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"
|
||||||
@@ -443,7 +443,7 @@ case "${1:-}" in
|
|||||||
;;
|
;;
|
||||||
"--playlists")
|
"--playlists")
|
||||||
# List available playlists
|
# List available playlists
|
||||||
stored_playlists
|
stored_playlists | cut -d "$(printf '\t')" -f 1
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
"--print-playlist")
|
"--print-playlist")
|
||||||
@@ -474,7 +474,7 @@ GENERAL OPTIONS:
|
|||||||
--playlists List stored playlists and exit
|
--playlists List stored playlists and exit
|
||||||
--load-playlist <playlist> Load specified playlist
|
--load-playlist <playlist> Load specified playlist
|
||||||
--print-playlist <playlist> Print specified playlist and exit
|
--print-playlist <playlist> Print specified playlist and exit
|
||||||
--lyrics <release> <mbid> Show lyrics specified track and exit
|
--lyrics <relid> <mbid> Show lyrics of track <mbid> in release <relid> and exit
|
||||||
|
|
||||||
MANAGE LOCAL MUSIC:
|
MANAGE LOCAL MUSIC:
|
||||||
--decorate <path> Decorate directory containing a tagged release
|
--decorate <path> Decorate directory containing a tagged release
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ END { for (i in id) print title[i], id[i], fname[i] }
|
|||||||
' "$tmpj" "$tmpf" >"$assocfile"
|
' "$tmpj" "$tmpf" >"$assocfile"
|
||||||
rm -f "$tmpj" "$tmpf"
|
rm -f "$tmpj" "$tmpf"
|
||||||
# Ask user if this is ok
|
# Ask user if this is ok
|
||||||
info "We discovered the following associatoin:"
|
info "We discovered the following association:"
|
||||||
while IFS= read -r line; do
|
while IFS= read -r line; do
|
||||||
t="$(echo "$line" | cut -d "$(printf '\t')" -f 1)"
|
t="$(echo "$line" | cut -d "$(printf '\t')" -f 1)"
|
||||||
f="$(echo "$line" | cut -d "$(printf '\t')" -f 3)"
|
f="$(echo "$line" | cut -d "$(printf '\t')" -f 3)"
|
||||||
|
|||||||
@@ -17,10 +17,9 @@ if [ ! "${LYRICS_LOADED:-}" ]; then
|
|||||||
|
|
||||||
# Custom command to fetch lyrics
|
# Custom command to fetch lyrics
|
||||||
#
|
#
|
||||||
# This command reads from stdin the json object of the track and prints the
|
# This command reads from stdin the json object of the release and prints the
|
||||||
# lyrics.
|
# lyrics of the track.
|
||||||
LYRICS_FETCH_CUSTOM="${LYRICS_FETCH_CUSTOM:-"$JQ '.trackid as \$tid | .release.media[].tracks[] | select(.id == \$tid) | .title'"}"
|
LYRICS_FETCH_CUSTOM="${LYRICS_FETCH_CUSTOM:-""}"
|
||||||
#LYRICS_FETCH_CUSTOM="${LYRICS_FETCH_CUSTOM:-"$JQ '.trackid as \$trid | \"Lyrics for \" + .media[].tracks[] | select(.id == \$trid) | .title'"}"
|
|
||||||
export LYRICS_FETCH_CUSTOM
|
export LYRICS_FETCH_CUSTOM
|
||||||
|
|
||||||
export LYRICS_LOADED=1
|
export LYRICS_LOADED=1
|
||||||
@@ -51,13 +50,21 @@ store_lyrics() {
|
|||||||
#
|
#
|
||||||
# @argument $1: MusicBrainz release ID
|
# @argument $1: MusicBrainz release ID
|
||||||
# @argument $2: MusicBrainz track 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() {
|
store_lyrics_custom() {
|
||||||
rlid="${1:-}"
|
rlid="${1:-}"
|
||||||
mbid="${2:-}"
|
mbid="${2:-}"
|
||||||
mb_release "$rlid" |
|
if [ "$LYRICS_FETCH_CUSTOM" ]; then
|
||||||
$JQ --arg mbid "$mbid" '{release: ., trackid: $mbid}' |
|
mb_release "$rlid" |
|
||||||
sh -c "$LYRICS_FETCH_CUSTOM" |
|
$JQ --arg mbid "$mbid" '{release: ., trackid: $mbid}' |
|
||||||
store_lyrics "$mbid"
|
sh -c "$LYRICS_FETCH_CUSTOM" |
|
||||||
|
store_lyrics "$mbid"
|
||||||
|
else
|
||||||
|
echo "$LYRICS_NO_LYRICS" |
|
||||||
|
store_lyrics "$mbid"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Print lyrics
|
# Print lyrics
|
||||||
|
|||||||
@@ -399,5 +399,10 @@ if [ ! "${THEME_LOADED:-}" ]; then
|
|||||||
PLYSTORE_PLAYLIST="${PLYSTORE_PLAYLIST:-"🎼 ${CPURPLE}%f${OFF}"}"
|
PLYSTORE_PLAYLIST="${PLYSTORE_PLAYLIST:-"🎼 ${CPURPLE}%f${OFF}"}"
|
||||||
export TITLE_PLYLST TITLE_PLYLST_STORE PLYSTORE_PLAYLIST
|
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
|
export THEME_LOADED=1
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user