0
\$\begingroup\$

I've put together this script to check through various location and pick the next media file to play on an internet radio station:

#!/bin/sh

dir=/ezstream

# processing function
play_next()
{
  location=$1
  used=$2
  last=$3

  # check for media
  available=$(ls -1 $location)
  if [ -z "$available" ]; then

    # this is an empty folder; report unsuccessful
    return 0

  else

    # remove already-used media
    if [ -f $used ]; then
      while read remove; do
        available=$(echo "$available" | grep -v "${remove##*/}")
      done < $used
    elif [ -f $last ]; then
      remove=$(cat $last)
      available=$(echo "$available" | grep -v "$remove")
    fi

    # calculate and play next
    remaining=$(echo "$available" | wc -l)
    if [ $remaining -eq 1 ]; then
      rm -f $used
      next=$location/$available
      echo $next | tee $last
    else
      next=$location/$(echo "$available" | shuf -n 1)
      echo $next | tee -a $used | tee $last
    fi
    echo $(date +"%Y-%m-%d %T"): $next >> $dir/history.log

    # report success
    return 1

  fi
}

# Check all the options provided in the cfg.
options=$(cat $dir/config/play-next.cfg | jq -c '. |= sort_by(-(.spacing//0)) | .[]')
for option in $options; do
  name=$dir/$(echo $option | jq -j '.name')
  location=$(echo $option | jq -j '.location')
  spacing=$(echo $option | jq -j '.spacing//0')

  # If the tracking file doesn't exist, or it was last touched at
  # least $spacing minutes ago, then this is the next thing to play.
  if [ ! -f $name.play ] || [ $(find $name.play -mmin +$spacing | wc -l) -eq 1 ] || [ $(find $name.play -mmin $spacing | wc -l) -eq 1 ]; then
    play_next $location $name.txt $name.play
    if [ $? == 1 ]; then
      break
    fi
  fi
done

If I use a config that intersperses stingers among the episodes, the script takes ~0.8s to run:

[
  {
    "name": "episodes",
    "location": "/run/radio/media/episodes"
  },
  {
    "name": "stingers",
    "location": "/run/radio/media/stingers",
    "spacing": 120
  }
]

However, if I add an empty folder, the time to run this goes up ~50% to ~1.2s:

[
  {
    "name": "episodes",
    "location": "/run/radio/media/episodes"
  },
  {
    "name": "stingers",
    "location": "/run/radio/media/stingers",
    "spacing": 120
  },
  {
    "name": "empty",
    "location": "/run/radio/media/empty",
    "spacing": 5
  }
]

Once it takes that long, my streaming client loses the connection, and I have to reconnect, so I'd like to speed this script up. In the future, there will be more directories / types of media to intersperse. I will obviously avoid having empty directories in the config, but I want to get ahead of the script time-to-run expanding as more locations are added. Any suggestions on how to tune this would be greatly appreciated; I'm fairly new to shell scripting (and linux in general).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.