- Add all the existing files.

This commit is contained in:
2026-04-10 18:46:38 +02:00
parent deba3dd53f
commit 5b141b45cf
14 changed files with 2219 additions and 0 deletions

597
usr/lib/rx3/music.bash Normal file
View File

@@ -0,0 +1,597 @@
#!/bin/bash
if [[ "${MUSIC_BASH}" != "" ]]
then
return
fi
# Includes
#-----------------------------------------------------------------------------------------------------------------------------------
. /usr/global/lib/default.bash
# Global Variable
#-----------------------------------------------------------------------------------------------------------------------------------
declare -g MUSIC_BASH=1
declare -Ag FLAC_2_MP3_TAB=(
[TRACKNUMBER]=TRCK
[TRACKTOTAL]=TRCK
[TITLE]=TIT2
[ALBUM]=TALB
[ARTIST]=TPE1
[COMPOSER]=TCOM
[ARRANGER]=IPLS
[CONDUCTOR]=TPE3
[REMIXER]=TPE4
[AUTHOR]=TEXT
[WRITER]=TEXT
[LYRICIST]=TEXT
[ALBUMARTIST]=TPE2
[DATE]=TDRC
[GENRE]=TCON
[COMPILATION]=TCMP
[DISCTOTAL]=TPOS
[DISCNUMBER]=TPOS
[LABEL]=XXXX
[PUBLISHER]=TPUB
[ISRC]=TSRC
[BARCODE]=TXXX
[CATALOGNUMBER]=TXXX
[COPYRIGHT]=TCOP
[LICENSE]=USER
[COMMENT]=COMM
[DESCRIPTION]=TIT3
[ENCODER]=TSSE
[MEDIA]=TMED
[LANGUAGE]=TLAN
[LYRICS]=USLT
)
declare -Ag MP3_2_FLAC_TAB=(
[TRCK]=TRACKNUMBER:TRACKTOTAL
[TIT2]=TITLE
[TALB]=ALBUM
[TPE1]=ARTIST
[TCOM]=COMPOSER
[IPLS]=ARRANGER
[TPE3]=CONDUCTOR
[TPE4]=REMIXER
[TEXT]=AUTHOR:WRITER:LYRICIST
[TPE2]=ALBUMARTIST
[TDRC]=DATE
[TCON]=GENRE
[TCMP]=COMPILATION
[TPOS]=DISCNUMBER:DISCTOTAL
[TPUB]=PUBLISHER
[TSRC]=ISRC
[TXXX]=BARCODE:CATALOGNUMBER
[TCOP]=COPYRIGHT
[USER]=LICENSE
[COMM]=COMMENT
[TIT3]=DESCRIPTION
[TSSE]=ENCODER
[TMED]=MEDIA
[TLAN]=LANGUAGE
[USLT]=LYRICS
)
declare -g FLAC_TAG_LIST="TRACKNUMBER TRACKTOTAL TITLE ALBUM ARTIST COMPOSER ARRANGER CONDUCTOR REMIXER AUTHOR WRITER LYRICIST ALBUMARTIST DATE GENRE COMPILATION LABEL PUBLISHER ISRC BARCODE UPC COPYRIGHT LICENSE COMMENT DESCRIPTION ENCODER MEDIA LANGUAGE LYRICS"
declare -g FLAC_TAG_COND=$(echo '('${FLAC_TAG_LIST}')' | sed -e 's/ /|/g')
declare -g NODEF_TAG_LIST="TRACKNUMBER TITLE ISRC LYRICS"
declare -g NODEF_TAG_COND=$(echo '('${NODEF_TAG_LIST}')' | sed -e 's/ /|/g')
#-----------------------------------------------------------------------------------------------------------------------------------
# Fix Name
#-----------------------------------------------------------------------------------------------------------------------------------
# Standardise Name
#-----------------------------------------------------------------------------------------------------------------------------------
# $1: Input Name
# $2: SED Substitute Patern
# Out: Output Name
#-----------------------------------------------------------------------------------------------------------------------------------
function fix_name
{
input_name="$1"
ssp="$2"
if [[ "${ssp}" != "" ]]
then
sse="s/${ssp}"
else
sse="s/^//"
fi
echo ${input_name} |
sed -e 's/[ ,!/?:]/_/g' \
-e "s/['´]/_/g" \
-e 's/\[/-/g' -e 's/\]//g' \
-e 's/(/-/g' -e 's/)//g' \
-e 's/__/_/g' -e 's/_\././g' -e 's/_-/-/g' -e 's/--/-/g' -e 's/-_/-/g' \
-e 's/à/a/g' -e 's/á/a/g' -e 's/ä/a/g' -e 's/â/a/g' -e 's/ã/a/g' -e 's/é/e/g' -e 's/è/e/g' -e 's/ê/e/g' -e 's/ë/e/g' -e 's/ï/i/g' -e 's/î/i/g' -e 's/í/i/g' -e 's/ô/o/g' -e 's/ö/o/g' -e 's/ó/o/g' -e 's/ù/u/g' -e 's/ü/u/g' -e 's/û/u/g' -e 's/ú/u/g' -e 's/ç/c/g' -e 's/ñ/n/g' \
-e 's/À/a/g' -e 's/Á/a/g' -e 's/Ä/a/g' -e 's/Â/a/g' -e 's/Ã/a/g' -e 's/É/e/g' -e 's/È/e/g' -e 's/Ê/e/g' -e 's/Ë/e/g' -e 's/Ï/i/g' -e 's/Î/i/g' -e 's/Í/i/g' -e 's/Ô/o/g' -e 's/Ö/o/g' -e 's/Ó/o/g' -e 's/Ù/u/g' -e 's/Ü/u/g' -e 's/Û/u/g' -e 's/Ú/u/g' -e 's/Ç/c/g' -e 's/Ñ/n/g' \
-e 's/¿//g' \
-e 's/[+&]/and/g' -e 's/"/_inch/g' \
-e 's/#//g' \
-e 's/^[_-]*//' \
-e 's/[_-]*$//' \
-e "${sse}" |
tr '[:upper:]' '[:lower:]'
}
#-----------------------------------------------------------------------------------------------------------------------------------
# Fix File Name
#-----------------------------------------------------------------------------------------------------------------------------------
# Standardise File Name
#-----------------------------------------------------------------------------------------------------------------------------------
# $1: Input File Name
# $2: SED Substitute Patern
# Out: Output File Name
#-----------------------------------------------------------------------------------------------------------------------------------
function fix_file_name
{
input_file_name="$1"
ssp="$2"
fix_name "${input_file_name}" "${ssp}" |
sed -e 's/\(^[0-9]*\)./\1-/'
}
# TagTab Alloc
#-----------------------------------------------------------------------------------------------------------------------------------
function tagtab_alloc
{
unset tagtab
declare -Ag tagtab
declare -g taglist
taglist=":"
}
# Tag Exist
#-----------------------------------------------------------------------------------------------------------------------------------
function tag_exist
{
tag="$1"
echo ${taglist} | grep -e ":${tag}:"
}
# TagTab Read
#-----------------------------------------------------------------------------------------------------------------------------------
function tagtab_read
{
track_id="$1"
track_file="$2"
mode="$3"
tmp_file=$(mktemp)
case "${track_file}"
in
*.flac)
metaflac --export-tags-to=- "${track_file}" | sed -e 's/^[^=]*=/\U&\E/' > ${tmp_file}
while read line
do
tag="${line/=*}"
if [[ ${line/*=*/=} == "=" ]] && [[ "${tag}" != "" ]]
then
value="$(tag_read "${track_file}" "${tag}")"
if [[ "$(tag_exist ${tag})" == "" ]]
then
taglist="${taglist}${tag}:"
fi
if [[ ( "${mode}" != "FACTORING" ) || ( "${tag}" =~ ^${NODEF_TAG_COND}$ ) || ( "${tagtab["0,${tag}"]}" != "" ) ]]
then
if [[ "${tagtab["0,${tag}"]}" != "${value}" ]]
then
tagtab["${track_id},${tag}"]="$value"
fi
else
tagtab["0,${tag}"]="${value}"
fi
fi
done < ${tmp_file}
;;
*.mp3)
mid3v2 --list "${track_file}" | tail -n +2 | sed -e 's/^[^=]*=/\U&\E/' > ${tmp_file}
while read line
do
mp3tag="${line/=*}"
value="$(tag_read "${track_file}" "${mp3tag}")"
if [[ "${line/*=*/=}" == "=" ]] && [[ "${mp3tag}" != "" ]] && [[ "${MP3_2_FLAC_TAB["${mp3tag}"]}" != "" ]]
then
tag="${MP3_2_FLAC_TAB["${mp3tag}"]}"
if [[ "$(tag_exist ${tag})" == "" ]]
then
taglist="${taglist}${tag}:"
fi
if [[ ( "${mode}" != "FACTORING" ) || ( "${tag}" =~ ^${NODEF_TAG_COND}$ ) || ( "${tagtab["0,${tag}"]}" != "" ) ]]
then
if [[ "${tagtab["0,${tag}"]}" != "${value}" ]]
then
tagtab["${track_id},${tag}"]="$value"
fi
else
tagtab["0,${tag}"]="${value}"
fi
fi
done < ${tmp_file}
;;
*)
err_echo "tagtab_read: Unknown file format: ${track_file}"
;;
esac
if [[ ${taglist} == ":" ]]
then
taglist=""
fi
\rm -f ${tmp_file}
}
# TagTab Load
#-----------------------------------------------------------------------------------------------------------------------------------
function tagtab_load
{
metadata_file="$1"
mode="$2"
track_id=0
eoa="false"
while read -r line && [[ "${eoa}" != "true" ]]
do
tag="${line/=*}"
value="${line/${tag}=}"
case "${tag}"
in
@${FLAC_TAG_COND})
tagtab["${track_id},${tag}"]="$value"
;;
DEF)
;;
SOT)
track_id=$((${track_id} + 1))
;;
EOT)
;;
EOA)
eoa="true"
;;
*)
err_echo "tagtab_load: Unkwown tag: '${tag}'"
;;
esac
done < "${metadata_file}"
}
# TagTab Dump
#-----------------------------------------------------------------------------------------------------------------------------------
function tagtab_dump
{
track_id="$1"
dump_mode="$2"
case "${dump_mode}" in
"STANDARD")
dump_list="${FLAC_TAG_LIST}"
;;
"PASSTHROUGH")
dump_list="${taglist//:/ }"
;;
"CUSTOM")
dump_list="$3"
;;
esac
for tag in ${dump_list}
do
if [[ "${tagtab["${track_id},${tag}"]}" != "" ]]
then
echo "${tag}=${tagtab["${track_id},${tag}"]}"
fi
done
}
# Tag Get
#-----------------------------------------------------------------------------------------------------------------------------------
function tag_get
{
declare -n return=$1
track_id=$2
tag=$3
return="${tagtab["${track_id},${tag}"]}"
if [[ "${return}" == "" ]]
then
return="${tagtab["0,${tag}"]}"
if [[ "${return}" == "" ]] && [[ "${tag}" == "TRACKNUMBER" ]]
then
return="$(printf "%02d" ${track_id})"
fi
fi
}
# Tag Save
#-----------------------------------------------------------------------------------------------------------------------------------
function tag_save
{
target_file=$1
track_id=$2
mode=$3
if [[ "${mode}" == "CLEAN" ]]
then
tag_all_delete "${target_file}" ""
fi
for tag in ${FLAC_TAG_LIST}
do
# if [[ "${tagtab["${track_id},${tag}"]}" == "" ]]
# then
# value="${tagtab["0,${tag}"]}"
#
# if [[ "${value}" == "" ]] && [[ "${tag}" == "TRACKNUMBER" ]]
# then
# value="$(printf "%02d" ${track_id})"
# fi
# else
# value="${tagtab["${track_id},${tag}"]}"
# fi
tag_get value "${track_id}" "${tag}"
tag_delete "${target_file}" "${tag}"
if [[ "${value}" != "" ]]
then
tag_write "${target_file}" "${tag}" "${value}"
fi
done
}
# Tag Read
#-----------------------------------------------------------------------------------------------------------------------------------
function tag_read
{
track_file="$1"
tag="$2"
case "${track_file}"
in
*.flac)
metaflac --show-tag="${tag}" "${track_file}" | sed -e 's/^[^=]*=//' -e ':a' -e 'N' -e '$!ba' -e 's/\n/\\n/g'
;;
*.mp3)
# mid3v2 --list "${track_file}" | tail -n +2 | sed -e 's/^[^=]*=/\U&\E/' | grep -e "^${FLAC_2_MP3_TAB["${tag}"]}" | sed -e 's/^[^=]*=//' -e ':a' -e 'N' -e '$!ba' -e 's/\n/\\n/g'
mid3v2 --list "${track_file}" | tail -n +2 | grep -e "^${tag}" | sed -e 's/^[^=]*=//' -e ':a' -e 'N' -e '$!ba' -e 's/\n/\\n/g'
;;
*)
err_echo "tag_read: Unknown file format: ${track_file}"
;;
esac
}
# Tag Write
#-----------------------------------------------------------------------------------------------------------------------------------
function tag_write
{
track_file="$1"
tag="$2"
value="$3"
value="$(echo -e "$(escape_str "${value}")")"
case "${track_file}"
in
*.flac)
cmd="metaflac --set-tag=\"${tag}=${value}\" \"${track_file}\""
exec_cmd "${cmd}"
;;
*.mp3)
cmd="mid3v2 --\"${FLAC_2_MP3_TAB["${tag}"]}\" \"${value}\" \"${track_file}\""
exec_cmd "${cmd}"
;;
*)
err_echo "tag_write: Unknown file format: ${track_file}"
;;
esac
}
# Tag Delete
#-----------------------------------------------------------------------------------------------------------------------------------
function tag_delete
{
track_file="$1"
tag="$2"
case "${track_file}"
in
*.flac)
cmd="metaflac --remove-tag=\"${tag}\" \"${track_file}\""
exec_cmd "${cmd}"
;;
*.mp3)
cmd="mid3v2 --delete-frames=\"${FLAC_2_MP3_TAB["${tag}"]}\" \"${track_file}\""
exec_cmd "${cmd}"
;;
*)
err_echo "tag_delete: Unknown file format: ${track_file}"
;;
esac
}
# Tag All Delete
#-----------------------------------------------------------------------------------------------------------------------------------
function tag_all_delete
{
track_file="$1"
header_type="$2"
if [[ "${header_type}" == "" ]]
then
case "${track_file##*.}"
in
flac)
header_type="ogg"
;;
mp3)
header_type="id3"
;;
esac
fi
if [[ ( "${header_type}" == "ogg") && ( "${track_file##*.}" == "mp3") ]]
then
err_echo "tag_all_delete: Can't remove ogg tags from mp3 file!"
else
case "${header_type}"
in
ogg)
cmd="metaflac --remove-all-tags \"${track_file}\""
exec_cmd "${cmd}"
;;
id3)
cmd="mid3v2 --delete-all \"${track_file}\""
exec_cmd "${cmd}"
;;
*)
err_echo "tag_all_delete: Unknown header type: ${header_type}"
;;
esac
fi
}
# Album Type Get
#-----------------------------------------------------------------------------------------------------------------------------------
function album_type_get
{
track_file="$1"
for type in various_artists tribute original_soundtrack child
do
if [[ ${track_file} == */${type}/* ]]
then
echo "${type}"
fi
done
}