add lyricsify

This commit is contained in:
2026-05-05 18:03:25 -05:00
parent ffb5cafaf3
commit c0c7364e4a
3 changed files with 122 additions and 3 deletions
+1
View File
@@ -56,6 +56,7 @@ process_inputs() {
download_with_lrclib
download_with_spotify
download_with_deezer
download_with_lyricsify
)
local numInputs="${#INPUTS[@]}"
+7 -3
View File
@@ -95,6 +95,8 @@ check_required_utils() {
jq
librelyrics
spotify # uv tool install --python 3.8 spotify-cli
docker
node
)
local missing=false
for util in "${utils[@]}"; do
@@ -131,11 +133,13 @@ cache_command() {
hash="$(sha256sum <<<"${cmd[*]}")" || return 1
read -r cacheFile _ <<<"${hash}"
cacheFilePath="${CACHE_DIR}/${cacheFile}"
if [[ -f "${cacheFilePath}" && ${DRY_RUN} == false ]]; then
if [[ -f "${cacheFilePath}" ]]; then
mapfile -t cmdArr <<<"${cmd[*]}"
local skipLines="${#cmdArr[@]}"
mapfile -t contents <"${cacheFilePath}"
ret=$?
# skip first line since it is the command
printf '%s\n' "${contents[@]:1}"
# skip N lines respective to the command length
printf '%s\n' "${contents[@]:${skipLines}}"
else
cmdOut="$(dry "${cmd[@]}")"
ret=$?
+114
View File
@@ -0,0 +1,114 @@
#!/usr/bin/env bash
FLARESOLVERR_PORT="${FLARESOLVERR_PORT:-8191}"
validate_flaresolverr() {
local checkMsg="$(curl --connect-timeout 1 -s localhost:${FLARESOLVERR_PORT} | jq -r .msg)"
if [[ "${checkMsg}" == 'FlareSolverr is ready!' ]]; then
return 0
fi
debug echo_debug 'flaresolverr not running, attempting to start with docker'
local containerName='flaresolverr'
docker inspect ${containerName} &>/dev/null && docker container rm ${containerName}
echo_if_fail docker run -d \
--name=flaresolverr \
-p ${FLARESOLVERR_PORT}:${FLARESOLVERR_PORT} \
-e LOG_LEVEL=info \
--restart unless-stopped \
ghcr.io/flaresolverr/flaresolverr:latest
local startupRet=$?
[[ ${startupRet} -ne 0 ]] && return ${startupRet}
# wait a little to make sure the container is ready
sleep 3
return ${startupRet}
}
get_lyricsify_response() {
local isrc="$1"
validate_flaresolverr || return 1
local deezerResponse=''
deezerResponse="$(get_deezer_isrc_response "${isrc}")" || return 1
# lyricsify uses artist - song name for URL
# so obtain data from deezer
local deezerMetadata=(
"track .title"
"artist .artist.name"
)
for data in "${deezerMetadata[@]}"; do
IFS=' ' read -r env jqFilter <<<"${data}"
jqResult="$(jq -r "${jqFilter}" <<<"${deezerResponse}")"
if ! jq_result_valid "${jqResult}"; then
echo_fail "could not determine lyricsify ${env} for ${isrc}"
return 1
fi
declare "${env}=${jqResult}"
debug echo_debug "${env}=${jqResult}"
done
# variables assigned above
# shellcheck disable=SC2154
artist="${artist,,}"
track="${track,,}"
artist="${artist// /-}"
track="${track// /-}"
local lyricsifyUrl="https://www.lyricsify.com/lyrics/${artist}/${track}"
debug echo_debug "using ${lyricsifyUrl}"
local jsonPayload
jsonPayload="$(
jq -n \
--arg cmd 'request.get' \
--arg url "${lyricsifyUrl}" \
--argjson timeout 60000 \
'{cmd: $cmd, url: $url, maxTimeout: $timeout}'
)" || return 1
cache_command \
curl \
-L \
-X POST \
"http://localhost:${FLARESOLVERR_PORT}/v1" \
-H 'Content-Type: application/json' \
--data-raw "${jsonPayload}"
}
process_lyricsify_response() {
local response="$1"
local responseMessage="$(jq -r '.message' <<<"${response}")"
if [[ "${responseMessage}" != 'Challenge solved!' ]]; then
debug echo_fail "could not solve challenge"
return 1
fi
local solution="$(jq -r '.solution.response' <<<"${response}")"
local variableSearch='lrcText'
while read -r line; do
if [[ "${line}" == *"var ${variableSearch} = "* ]]; then
node -e "${line} ; console.log(${variableSearch})"
return $?
fi
done <<<"${solution}"
return 1
}
DOWNLOAD_FUNCTIONS+=(download_with_lyricsify)
download_with_lyricsify() {
local isrc="$1"
local output="$2"
local lyricsifyResponse syncedLyrics
lyricsifyResponse="$(get_lyricsify_response "${isrc}")" || return 1
syncedLyrics="$(process_lyricsify_response "${lyricsifyResponse}")" || return 1
echo "${syncedLyrics}" >"${output}"
}