Script to play MIDI files in Banshee 2.0 in Ubuntu without going into an infinite loop

| | 2 min read

I was trying to get a list of MIDI files play in banshee 2.0 in an old computer. The system had Ubuntu 11.04 and banshee was able to play MIDI files except that it was not able to detect the end of each track and continued playing the same track with silence as the only output and infinitely playing the same track. So whenever there was a long silence I had to manually change to the next track. I did that a few times but then decided to write a small script to solve the problem.

Banshee supports passing commands via the command line. It also supports querying information about the currently playing track from the command line. However it was not able to get the length of the currently playing track from the command line. For this I had to use another utility (smfsh - sudo apt-get install smf-utils)

Now smfsh is an interactive command-driven frontend to libsmf, useful for modifying MIDI files by hand and for querying information about MIDI files. Because it opens an interactive shell I had to write a small input file that passes the required command to the shell and then exit the shell.

The complete script is as follows. This is released under GNU/GPL v3 and is available from the zyxware github account under the misc-utils repository.

#!/bin/bash

debug=0

# Infinite loop
while :
do
  # Get the path to the current file
  cur_file=`banshee --query-uri | cut -c 13-10000`
  # Get the length of the current track using smfsh since banshee is not 
  # able to stop at the end of the midi files
  cur_track_length=`smfsh $cur_file  in.txt 2>&1 | grep Length | awk '{print $4}' | cut -d. -f1`
  # Get the current position in the current track
  cur_track_pos=`banshee --query-position | awk '{print $2}' | cut -d. -f1`
  if [[ $debug -eq 1 ]]; then
    echo "Playing $cur_file at $cur_track_pos / $cur_track_length seconds"
  fi
  if ! [[ "$cur_track_length" =~ ^[0-9]+$ || "$cur_track_pos" =~ ^[0-9]+$ ]]; then
    banshee --next
  else
    # If banshee has been playing for longer than the duration of the current track then 
    # play the next track
    if [[ $cur_track_pos -gt $cur_track_length ]]; then
      banshee --next
    fi
  fi
  sleep 5
done

You will need to create an in.txt file in the same folder with the following contents as well

length
quit

You can save the text file as play-midi.sh or something like that and then run it in the background and that should be all. The script will check if banshee has overrun the currently played midi file and if so switch to the next track.