Shuffle Function For The Brennan Helix CD Player In PHP

Use the following script to run a shuffle playlist on a Brennan Helix CD player. Normally the CD player doesn't support playlists or shuffle, but this can be worked around using this script.

<?php
declare(strict_types=1);
// The IP address of the Helix, used on every request.
$helixIp = 'http://192.168.xxx.xxx';
/**
 * Call the Helix API with a given route.
 *
 * @param string $helixIp
 *   The Helix IP address (no ending slash).
 * @param string $route
 *   The route of the API to use.
 *
 * @return string
 *   The unparsed result from the API call.
 */
function makeCall(string $helixIp, string $route):string {
  $url = $helixIp . '/' . str_replace(' ','%20', $route);
  $ch = curl_init();
  $user_agent = "Mozilla/4.0";
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
  curl_setopt($ch, CURLOPT_HEADER, 0);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  curl_setopt($ch, CURLOPT_TIMEOUT, 120);
  $contents = curl_exec($ch);
  curl_close($ch);
  return $contents;
}
/**
 * Recursively find all files on the Helix SD card.
 *
 * @param string $helixIp
 *   The Helix IP address (no ending slash).
 * @param string $path
 *   The directory path to find files from. Defaults to the root of "\sdcard".
 *
 * @return array
 *   The list of files found under the path.
 */
function findFiles(string $helixIp, string $path = '/sdcard'):array {
  $files = [];
  $contents = makeCall($helixIp, 'getFiles?path=' . $path);
  $contents = json_decode($contents);
  if ($contents !== null) {
    foreach ($contents as $item) {
      if ($item->type === 2) {
        // This is a directory type. Recursively call the findFiles() function
        // using the name of the item as an extra path argument.  
        $files = array_merge($files, findFiles($helixIp, $path . '/' . $item->name));
      }
      if ($item->type === 1) {
        // This is a file type. Make sure it is a .wav file and add it to the
        // list of files.
        if (str_ends_with($item->name, '.wav') === true) {
          $files[] = $path . '/' . $item->name;
        }
      }
    }
  }
  return $files;
}
// Generate the list of files.
if (file_exists('shuffle.txt')  === true) {
  // If the cache file exists then load this into memory.
  $files = file('shuffle.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
}
else {
  // If the cache file doesn't exist then find all the files on the SD card.
  $files = findFiles($helixIp);
  file_put_contents('shuffle.txt', implode(PHP_EOL, $files));
}
// Shuffle the wav files we found.
shuffle($files);
// As long as the $files array contains files to play then run the following
// loop.
do {
  // Get the current status of the Helix.
  $status = makeCall($helixIp, 'getStatus');
  $status = json_decode($status);
  // Print out the current state of the "Playing" property.
  echo $status->Playing === true ? 'playing' . PHP_EOL : 'not playing' . PHP_EOL;
  if ($status->Playing === false) {
    // If the Helix reports that it is not playing then pop an item off of the
    // files array and make a call to play this file.
    $file = array_pop($files);
    echo 'Playing file: ' . $file . PHP_EOL;
    makeCall($helixIp, 'playFile?path=' . $file);
  }
  // Sleep for 5 seconds.
  sleep(5);
} while(count($files) > 0);

To use this script, make sure you have PHP installed and create a script file with this code, changing the IP address as appropriate. Then call the script like this:

php shuffle.php

Every 5 seconds the script asks the Helix if anything is playing, and if not the next track from the list is sent over to the player. This will print out "playing" until the Helix reports that it is not playing anything, at which point it will print out "not playing" and then the name of the track it has asked the Helix to play, like this.

playing
not playing
Playing file: /sdcard/music/The Black Dahlia Murder/Deflorate/08 Eyes of Thousand.wav
playing

The first time this runs it will run through your SD card and generate a list of the files. These are then written to a file called shuffle.txt; which is used as a cache for the list. My Helix has over 5,300 files on it so this process took a couple of minutes.

Feel free to use and adapt this code to your needs. I have added comments to show what is going on.

Add new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
1 + 8 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.