#!/bin/bash
# Fonction de réinitialisation en cas de perte de la connexion
self-reset() {
echo "[--:-- --:-- --:--]"
sleep 1
exec "$0"
}
trap self-reset PIPE
# Initialisation de la connexion au serveur
coproc nc -U /home/breizh/.mpd/socket
IN=${COPROC[1]}
OUT=${COPROC[0]}
#echo "password xxx" >&"${IN}"
# Initialisation des valeurs par défaut et des fonctions
declare -i SCROLL=50 I=0
declare -- artist song
declare -A old
human_time() {
local seconds="${1}"
if [[ -z "$seconds" || "$seconds" -lt 0 ]]
then
echo "--:--"
return
fi
local minutes=$(( seconds / 60 ))
seconds=$(( seconds % 60 ))
if [[ "$minutes" -ge 60 ]]
then
local hours=$(( minutes / 60 ))
minutes=$(( minutes % 60 ))
printf "%02dh%02d\n" "$hours" "$minutes"
else
printf "%02d:%02d\n" "$minutes" "$seconds"
fi
return
}
# Initialisation de l’état
echo "status" >&"$IN"
while read -t 0.1 -u "$OUT" output
do
[[ "$output" =~ : ]] && o[${output%%:*}]="${output#*: }"
done
# Boucle principale
while [[ -n "$COPROC_PID" ]]
do
# Gestion du clic, fait office de délai si aucune action (une seconde).
# En cas de clic, l’actualisation de l’affichage sera instantanné.
read -t 0.85 BLOCK_BUTTON
case $BLOCK_BUTTON in
1|3)
if [[ "${o["state"]}" == stop ]]
then
echo "play" >&"${IN}" || self-reset
sed '/^OK$/q' <&"$OUT" &>/dev/null
fi
;;&
2)
if [[ "${o["state"]}" == stop ]]
then
echo "play" >&"${IN}" || self-reset
else
echo "pause" >&"${IN}" || self-reset
fi
;;&
1) echo "previous" >&"${IN}" || self-reset ;;&
3) echo "next" >&"${IN}" || self-reset ;;&
1|2|3) sed '/^OK$/q' <&"$OUT" &>/dev/null ;;
4) I="I-2"; [[ "$I" -lt 0 ]] && I=0 ;;
esac
# Réinitialisation de l’état
unset o output
declare -A o
# Récupération de l’état et des informations du morceau en cours
echo "status" >&"$IN" || self-reset
echo "currentsong" >&"$IN" || self-reset
while read -t 0.1 -u "$OUT" output
do
[[ "$output" =~ : ]] && o[${output%%:*}]="${output#*: }"
done
# Choix des couleurs selon l’état
case "${o["state"]}" in
play ) status="" ;;
pause ) status="" ;;
stop ) status="" ;;
esac
# En cas de changement de morceau,
# on réinitialise l’affichage défilant
if [[ "${o["file"]}" != "${old["file"]}" || "${o["Title"]}" != "${old["Title"]}" || "${o["Name"]}" != "${old["Name"]}" ]]
then
unset bloc1 bloc2 bloc3 bloc4
artist="${o["Artist"]:-${o["Name"]}}"
song="${o["Title"]}"
[[ -z "$artist$song" ]] && song="$(basename "${o["file"]}")"
if [[ "$(( ${#song} + ${#artist} + 1 ))" -gt "$SCROLL" ]]
then
scroll=true
song=" $song "
else
unset scroll
song=" $song"
fi
old["file"]="${o["file"]}"
old["Title"]="${o["Title"]}"
old["Name"]="${o["Name"]}"
I=0
fi
# Gestion du défilement
if [[ -n "$scroll" ]]
then
unset bloc1 bloc2 bloc3 bloc4
declare -- bloc1 bloc2 bloc3 bloc4
bloc1="${artist:$I:$SCROLL}"
if [[ "${#bloc1}" -eq 0 ]]
then
bloc2="${song:$(( I - ${#artist} )):$SCROLL}"
if [[ "$(( ${#bloc1} + ${#bloc2} ))" -lt "$SCROLL" ]]
then
bloc3="${artist:0:$(( SCROLL - ${#bloc2} ))}"
if [[ "$(( ${#bloc1} + ${#bloc2} + ${#bloc3} ))" -lt "$SCROLL" ]]
then
bloc4="${song:0:$(( SCROLL - ${#bloc1} - ${#bloc2} - ${#bloc3} ))}"
fi
fi
else
bloc2="${song:0:$(( SCROLL - ${#bloc1} ))}"
if [[ "$(( ${#bloc1} + ${#bloc2} ))" -lt "$SCROLL" ]]
then
bloc3="${artist:0:$(( SCROLL - ${#bloc2} - ${#bloc1} ))}"
fi
fi
I+=1
[[ "$I" -ge "$(( ${#artist} + ${#song} ))" ]] && I=0
else
unset bloc1 bloc2 bloc3 bloc4
bloc1="$artist"
bloc2="$song"
fi
# Gestion du temps
declare -i time_elapsed time_total time_left
time_total="${o["time"]#*:}"
[[ "$time_total" -eq 0 ]] && time_total="${o["Time"]}"
[[ "$time_total" -eq 0 ]] && time_total=-1
if [[ "${o["state"]}" == "stop" ]]
then
time_elapsed=-1
time_left=-1
else
time_elapsed="${o["time"]%:*}"
time_left="${time_total} - ${time_elapsed}"
fi
time="[$(human_time "${time_elapsed}") $(human_time "${time_left}") $(human_time "${time_total}")]"
# Nettoyage des chaînes de caractère pour pango
bloc1="${bloc1//&/&}"
bloc2="${bloc2//&/&}"
bloc3="${bloc3//&/&}"
bloc4="${bloc4//&/&}"
# DEBUG
printf '%s%s%s%s%s\n' "$bloc1" "$bloc2" "$bloc3" "$bloc4" " $status$time"
done