play random sequence for gpio input

I have butchered together a couple of things, this should take a list of sequences or everything with a name matching the pattern put it in a random list and then play through them if a button is pressed. Should only play if nothing is playing or if the Background playlist is playing.

If needed I can go through and neaten it all up but hey it seems to work.

edit: i just realised you wanted this script to play the background playlist again after. I start work in 5mins but that should be simple. I use another script to check if nothing is playing and then play the background playlist automatically which I find more useful.

Code:
#!/bin/bash
################################################################
Play random from list only if idle or playing background
################################################################

# Get our current status
STATUS=$(fpp -s | cut -d',' -f2)
PLAYLIST=$(fpp -s | cut -d',' -f4)

# Check that we got something meaningful
if [ -z "${STATUS}" ]; then
    echo "Error with status value" >&2
    exit 1
fi

shopt -s nullglob
cd ${MEDIADIR}/sequences

# The only configuration expected by the user is to set the
# SEQUENCES variable here at the top of the script.  Here are
# examples on ways to set that variable:

# File glob to include all sequences
#SEQUENCES=(*)

# File glob to include Donation Box effects sequences
#SEQUENCES=(DonationEffect_*)

# Specific sequences to include, including one with a space in the name
# NOTE: You must include the .fseq file extension since this is a list
#       of file names.
SEQUENCES=("Its Beginning to Look a Lot like Christmas.fseq" "Christmas Every Day-ShowStopper.fseq")

database=$(dirname $(mktemp -u))/button1sequence_db.txt

check_sequence_and_create_database()
{
    # Check if the database file doesn't exist (reboot, or first-run) or if
    # the database only has 1 (or somehow 0) entries.  If so, we will then
    # (re)create it ensuring that if we have a song queued, we don't use the
    # next queued entry as the first in the new set of data, thus avoiding
    # duplicate plays in a row.
    if [ ! -e ${database} ] || [ $(cat ${database} | wc -l) -lt 2 ]; then
        TEMP=$(mktemp)
        TNEXT=""

        # Handle the case where we don't have a variable passed in.  For this we
        # will blindly create the list.  We also handle the case of less sequences
        # than 2 because if we have 0 or 1 we will get stuck in the while loop
        # below forever.
        if [ -z "$1" ] || [ $(ls -1 "${SEQUENCES[@]}" | wc -l) -lt 2 ]; then
            (ls -1 "${SEQUENCES[@]}") | shuf > ${TEMP}
        # Handle the case where we have more than 1 sequence and need to re-queued
        # random data ensuring the first of the new entries is not the next sequence
        # so we don't play the same sequence twice.
        else
            # Loop through until the first song of the new random set is not the
            # same as the next song queued.
            while [ -z "${TNEXT}" ] || [ "x${TNEXT}" == "x$1" ]; do
                (ls -1 "${SEQUENCES[@]}") | shuf > ${TEMP}
                TNEXT="$(head -n 1 ${TEMP})"
            done
        fi

        # Now that we've populated our temp file with the new random set, add it to
        # our existing database and remove the temporary file.
        cat ${TEMP} >> ${database}
        rm -f ${TEMP}
    fi
}

# Run this once at the beginning of the world in case this is the first time we
# are running this script.  In that case we will populate the database the first
# time.
check_sequence_and_create_database

# Get our next sequence as the first in our database
next_sequence="$(head -n 1 ${database})"

# Remove the first line ("Take one down, pass it around...")
printf '%s\n' "$(sed '1d' ${database})" > ${database}

# Run the randomization again.  We run it now so that when there is only one
# entry left in the file we queue up the new set with a different SEQUENCES
# than the last in our current set to avoid repeats.
check_sequence_and_create_database "$(head -n 1 ${database})"

# Check that we got something meaningful
if [ -z "${STATUS}" ]; then
    echo "Error with status value" >&2
    exit 1
fi

# Act on the current status
case ${STATUS} in
    # IDLE
    0)
        fpp -P "${next_sequence}"
        ;;
    # PLAYING
    1)
        if [[ "${PLAYLIST}" == "Background" ]]; then
            echo "BackgroundPlaying" >&2
            fpp -P "${next_sequence}"
        fi
        ;;
    # STOPPING GRACEFULLY
    2|*)
        # Do nothing for stopping gracefully for now, or unknown
        ;;
esac
 
FPP 8.0 deprecated the FPP -P and FPP -S so its time to move things across to the API.

This is my current revision of the code specifically my "Kids Button" used from last year.
This takes all the sequences in the sequence folder that start with kids_ ie kids_blueythemesong.fseq and randomly plays one of them there is a bit of logic in there to try avoid playing the same song repeatedly.

It only plays if there is nothing playing or my background playlist is playing ( a 2 min loop with no audio that I use as a background to lessen the annoyance to my neighbours ) upon playing a sequence it writes the button pressed and the date/time to a log file.

Hopefully it helps someone.


Code:
#!/bin/bash
################################################################
# Play only if idle or playing background
################################################################

# Get our current status
STATUS=$(curl -s http:/127.0.0.1/api/fppd/status | jq -r '.status_name')
PLAYLIST=$(curl -s http://127.0.0.1/api/fppd/status | jq -r '.current_playlist.playlist')

# Check that we got something meaningful
if [ -z "${STATUS}" ]; then
    echo "Error with status value" >&2
    exit 1
fi

shopt -s nullglob
cd /home/fpp/media/sequences || { echo "Error: /home/fpp/media/sequences not found"; exit 1; }

# SEQUENCES variable definition
SEQUENCES=(kids_*)  # Customize as necessary

# Set a custom path for the database
# Ensure this path is writable, such as /home/fpp/media/scripts
database="/home/fpp/media/scripts/button_kids_sequence_db.txt"

# Create the temp file in the same directory as database file
TEMP="/home/fpp/media/scripts/tempfile_$$"

# Check and create database if needed
check_sequence_and_create_database() {
    # Check if the database file doesn't exist or is empty
    if [ ! -e ${database} ] || [ $(wc -l < ${database}) -lt 2 ]; then
        TNEXT=""
       
        # Handle the case of no sequences or less than 2 sequences
        if [ -z "$1" ] || [ $(ls -1 "${SEQUENCES[@]}" | wc -l) -lt 2 ]; then
            ls -1 "${SEQUENCES[@]}" | shuf > ${TEMP}
        else
            while [ -z "${TNEXT}" ] || [ "${TNEXT}" == "$1" ]; do
                ls -1 "${SEQUENCES[@]}" | shuf > ${TEMP}
                TNEXT=$(head -n 1 ${TEMP})
            done
        fi
       
        cat ${TEMP} >> ${database}
        rm -f ${TEMP}
    fi
}

check_sequence_and_create_database

# Get the next sequence
next_sequence=$(head -n 1 ${database})
tail -n +2 ${database} > ${database}

# Re-run randomization to avoid repeats
check_sequence_and_create_database "$next_sequence"

# Act on the current status
echo "STATUS: ${STATUS}" >&2  # Debugging line to check STATUS value
case ${STATUS} in
    idle)  # IDLE
        curl http://127.0.0.1/api/playlist/"${next_sequence}"/start >&2
        echo "kids,$(date +"%Y,%m,%d,%H,%M,%S")" >> log.csv
        ;;
    playing)  # PLAYING
        if [[ "${PLAYLIST}" == "Background" ]]; then
            echo "BackgroundPlaying" >&2
            curl http://127.0.0.1/api/playlist/"${next_sequence}"/start >&2
            echo "kids,$(date +"%Y,%m,%d,%H,%M,%S")" >> log.csv
        fi
        ;;
    *)
        echo "Unknown status: ${STATUS}" >&2
        exit 1
        ;;
esac
 
If you haven't already come up with a solution, I have exactly this working right now. I have a large red button for visitors to press which will select a random sequence... well, playlist. I created a playlist for each sequence and I am using the CycleRandomPlaylists.sh script. The script is tied to a GPIO input controlled by the button. I also have a background sequence which plays and is kicked off by the Command Preset FPP_STARTED. Works great! When the button is pushed one of the playlists/sequences plays and the entire thing resets and re-randomizes once all playlists have been played. After each playlist the background sequence kicks back in. I think I could have skipped the one sequence per playlist and used the CycleRandomSequences.sh script but I was sure how to avoid the background sequence in the randomized list of sequences -- probably easy but too lazy to figure it out and since this worked for me just fine.
Hi, I have the same problem now. fpp8. CycleRandomPlaylists.sh script is installed, the playlist is specified, but the lead in and lead out don't work. And there is no random selection played.
What do I have to enter in the command presets and where?
I would really be very grateful for help
 
Back
Top