#!/bin/bash
PrOgRaM="${0##*/}"
function Help(){ echo -e "\nUs: ${PrOgRaM} [-o output_name] folder\n" >&2 ; exit 1 ; }
function Error_Avortant(){ echo -e "\nERROR in ${PrOgRaM}: ${1}.\nAborting...\n" >&2 ;  exit 1 ; }
function TestAvailavilityOfPrograms(){ local prog; for prog in $@ ; do
    which "$prog" >/dev/null 2>&1 || Error_Avortant "el programa '${prog}' no esta disponible" 1
done ; }
function MiraTipusDeFitxer() { TipusDetectat="NRF"
     [ -f "$1" ] && TipusDetectat="`exiftool -s3 -FileType "$1" | tr '[A-Z]' '[a-z]'`"
     echo "$TipusDetectat"
}
function FindIfAudiofilesInFolderExist(){ local NF ; NF="$1" ; shift
   NF="$( find "$NF" $@ -type f -a \( -name '*.[Mm][Pp]3' -o -name '*.[Ww][Aa][Vv]' -o -name '*.[Mm]4[Aa]' -o -name '*.[Oo][Gg][Gg]' -o -name '*.[Ff][Ll][Aa][Cc]' \) -printf "F" )"
   test -n "$NF"
}
#
# Funcions de manipular la informació dels fitxers d'audio
function info2EXTINF(){ awk -F '=' -v FiLeNaMe="$1" '{ E[$1]=$2; } END{
    if(!length(E["T"])) { sub(/.*\//, "", FiLeNaMe); sub(/\..*/,"", FiLeNaMe); E["T"]=FiLeNaMe; }
    if(length(E["A"])) printf("#EXTINF:%s, %s - %s\n", E["D"], E["A"], E["T"]);
    else printf("#EXTINF:%s, %s\n", E["D"], E["T"]);
}' ; }
#
function mp3info-info(){ mp3info -p "D=%S\nA=%a\nT=%t\n" "$1" 2>/dev/null | info2EXTINF "$1" ; }
function ogginfo-info(){ ogginfo "$1" 2>/dev/null | awk '
  /Playback length:/{ gsub(/[ ms\t]/,""); split($0, TT, /:/); printf("D=%d\n", int(TT[2]*60 + TT[3] + 0.5)); }
  /TITLE=/ { gsub(/[[:space:]]+/, " "); printf("T=%s\n", substr($0,index($0,"=")+1)); }
  /ARTIST=/{ gsub(/[[:space:]]+/, " "); printf("A=%s\n", substr($0,index($0,"=")+1)); }
' | info2EXTINF "$1" ; }
function soxi-info(){ soxi "$1" 2>/dev/null | awk '
  /Duration *:/{ gsub(/[ \t]/,""); split($0, TT, /:/); printf("D=%d\n", int(TT[2]*3600 + TT[3]*60 + TT[4] + 0.5)); }
  /TITLE=/ { gsub(/[[:space:]]+/, " "); printf("T=%s\n", substr($0,index($0,"=")+1)); }
  /ARTIST=/{ gsub(/[[:space:]]+/, " "); printf("A=%s\n", substr($0,index($0,"=")+1)); }
' | info2EXTINF "$1" ; }
function mpeg-info(){ ffprobe -i "$1" 2>&1 | sed '1,/^Input/d' | awk '
  /Duration:/{ gsub(/[ \t]/,""); split($0, TT, /:/); printf("D=%d\n", int(TT[2]*3600 + TT[3]*60 + TT[4] + 0.5)); }
  /title *:/ { gsub(/[[:space:]]+/, " "); printf("T=%s\n", substr($0,index($0,":")+2)); }
  /artist *:/{ gsub(/[[:space:]]+/, " "); printf("A=%s\n", substr($0,index($0,":")+2)); }
' | info2EXTINF "$1" ; }
#
[ $# -eq 0 ] && Help
NoMsOrTiDa=""
for Opt ; do
  case "$Opt" in
        -o|--output) shift; NoMsOrTiDa="$Opt";;
       -o=*|--output=*) NoMsOrTiDa="${Opt#*=}" ;;
        -*) Help ;;
         *) DiReCtOrI="${Opt%%/}" ;;
  esac
done
[ -d "$DiReCtOrI" ] || Error_Avortant "folder '${DiReCtOrI}' not found"
[ -n "$NoMsOrTiDa" ] || NoMsOrTiDa="$DiReCtOrI"
[ -e "${NoMsOrTiDa}.m3u" ] && Error_Avortant "the file\n     '${NoMsOrTiDa}.m3u'\nalready exists"
FindIfAudiofilesInFolderExist "${DiReCtOrI}/" || Error_Avortant "No valid audio file found in '$DiReCtOrI'"
#
AuDiOdIrEcToRi="`basename "${DiReCtOrI}"`"
#
( # Inici de subshell que fabrica el fitxer m3u
### Capçalera de fitxer m3u
echo -e "#EXTM3U\n# List automatically created by ${PrOgRaM} (Lluis Alseda). Encoding: UTF-8."
echo "# Playlist Folder: $AuDiOdIrEcToRi"
find "${DiReCtOrI}/" -mindepth 1 -type d -printf "%P\n" | sort | while read dd ; do
    FindIfAudiofilesInFolderExist "${DiReCtOrI}/$dd" -maxdepth 1 && echo "# Including music folder: ${AuDiOdIrEcToRi}/$dd"
done
#
# Processat dels fitxers d'audio per a calcular la informació EXTINF
find "${DiReCtOrI}/" -type f -a \( -name '*.[Mm][Pp]3' -o -name '*.[Ww][Aa][Vv]' -o -name '*.[Mm]4[Aa]' -o -name '*.[Oo][Gg][Gg]' -o -name '*.[Ff][Ll][Aa][Cc]' \) -printf "%P\n" | sort |
  while read FiTxEr ; do
    TiPuS="`MiraTipusDeFitxer "${DiReCtOrI}/$FiTxEr"`" ; ext="${FiTxEr##*.}" ; ext="${ext,,*}"
    [ "${#ext}" -ne "${#1}" -a "$ext" != "$TiPuS" ] && echo -e "\nWarning in ${PrOgRaM}: al fitxer '$FiTxEr'\nl'extensió especificada (${ext}) no coincideix amb el tipus detectat ($TiPuS).\nAssumint tipus ${TiPuS^^*}.\n" >&2
    case "$TiPuS" in
         mp3)      mp3info-info "${DiReCtOrI}/$FiTxEr" ;;
         ogg)      ogginfo-info "${DiReCtOrI}/$FiTxEr" ;;
         wav|flac) soxi-info    "${DiReCtOrI}/$FiTxEr" ;;
         m4a)      mpeg-info    "${DiReCtOrI}/$FiTxEr" ;;
    esac
    echo "${AuDiOdIrEcToRi}/${FiTxEr}"
  done
# Fi de subshell que fabrica el fitxer m3u
echo "#" ) > "${NoMsOrTiDa}.m3u" # | iconv -f UTF-8 -t WINDOWS-1252 >
chmod 660 "${NoMsOrTiDa}.m3u"
#
exit 0
#
