fysh - Fill your shuffle


fysh [options]

Options are:

-c, --cache-dir

Specify cache dir. (Default: $HOME/.fysh-cache)

-d, --debug

Turn on debug printing. (Default: Off)

--faac=<path to faac>

Specify faac binary. (Default: 'faac')

--faac-opts=<options string>

Pass additional options to faac. You may enclose the string between ' or ``.

--flac=<path to flac>

Specify flac binary. (Default: 'flac')

-h, --help

Print a brief help message and exits.


Specify where to put music on the iPod shuffle. This path is relative to the iPod's root. (Default: 'music')


Specify where the iPod shuffle is mounted. (Default: '/media/ipod')


Chose suffix for resulting AAC files. Note that this changes behaviour: .m4a are selected for shuffle play, whereas .m4b are selected for playback (fixed order). (Default: 'm4a')


Prints the manual page and exits.


Limit the maximum number of encoding jobs to launch. (Default: Number of cpu)


Let fysh handle mount/umount. (Default: Do not handle mounts)


Specify music dir to search for flac files.


Do not normalize sound amplitude prior to encoding if the scale factor is below the given threshold (in other words: if normalizing is not worth the effort). (Default: 1.05)


Do not normalize sound amplitude prior to encoding. Just leave it as it is. (Default: Normalize)


Do not pick tracks at random. This is for debug, mostly. (Default: Pick at random)


Do not rebuild shuffle's database with (Default: Rebuild)


Do not remove played or skipped tracks. (Default: Remove)

-r, --rebuild-db-opts=<options string>

Pass additional options to You may enclose the string between ' or ``.

-s, --sox=<path to sox>

Specify sox binary. (Default: 'sox')

-v, --version

Prints version information and exits.


fysh is meant to fill an iPod shuffle with music. It chooses, encodes, transfers and registers the music into the iPod automatically.

fysh is pronounced like ``fish''.


The first step done by fysh after its invocation is to make some room on the shuffle. To do so, the play and skip statistics are examined. All files that have been played at least once or skipped at least once are removed.

The music directory tree you pass to fysh is searched for .flac files.

One file is picked at random and encoded to .m4a (AAC LP). It is then copied to your iPod shuffle under the /music/ directory. The process is repeated until there are no more song available or the iPod is full.

iPod shuffle directories

Here is a sample iPod shuffle directory tree:

    +- iPod_Control/
    |  `- iTunes/
    +- music/
    `- rebuild_db.log.txt

Under iPod_Control/iTunes are all iTunes files, including playlist and statistics.

Under music are the encoded songs. is the python script used to generate the playlist and rebuild_db.log.txt is its execution log.


fysh configuration is determined in the following order. First, fysh has default values for several of its settings.

Then environment variables are taken into account (see the section ``ENVIRONMENT VARIABLES'' below).

Then fysh tries to read a .fyshrc in the user's home directory (see the section ``CONFIGURATION FILE'' below).

And finally fysh will obey its command line arguments.


Invoke fysh, passing additional options to faac:

    $ fysh --faac-opts='-q 90 -c 19000'

Invoke fysh, with a low nice value to limit cpu usage:

    $ nice -n 19 fysh

Invoke fysh, with three encoding jobs in parallel at most:

    $ fysh --max-jobs=3


fysh configuration file is $HOME/.fyshrc.

The .fyshrc config file can contain all options that can be passed on the command line. Blank lines are ignored. Comments are introduced by a '#' character and last until the end of the line (shell style comments).

A sample .fyshrc may read like:

    # .fyshrc - fysh configuration file
    # We want fysh to automount the iPod:
    # Adjust faac settings (iPod's passed band is 20kHz):
    --faac-opts='-q 90 -c 19000'

This configuration file has precedence over the environment variables, but is overriden by command lines arguments.


fysh takes the following environment variables into account. Note that the .fyshrc config file as well as the command line options have precedence over those variables:


Specify faac binary. See option '--faac'.


Specify flac binary. See option '--flac'.


Specify sox binary. See option '--sox'.


There is a webpage for fysh:

File formats were taken from:

This script relies on the python database builder of


Vincent Stehlé <>.


Copyright (C) 2007 Vincent Stehlé.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA


Some enhancements remain to be done to this program:

Blacklist undesired input files.

Find latest version when downloading.

Use GNU queue. Even better: allow arbitrary wrapper for commands.

Able to fill cache speculatively. Able to limit cache size. Allow ``hit-under-miss''. Cache statistics.

Better error handling.

Able to limit fill size.

Depend on fewer executables.

Be able to specify removal criteria (played and/or skipped threshold).

Be able to accumulate iTunes statistics on the host. Use them to decide which file to pick next time.

Handle optional executables and mandatory executables in different ways during start check.

Find a way to estimate when it is worth encoding according to the remaining size on the iPod. Today we encode, then we check if it fits. This is one encode too many.

One way could be: estimate intermediate uncompressed wav size, then estimate final compressed size. then decide if it is worth trying to encode.

This would necessitate a dont-estimate option too.

Destination names computation may not suit everyone. Change this to something more flexible.

Handle first time shuffle too. Install this dump:

Read bookmark from iTunes stats and use it to decide if we need to remove a file. Use a threshold?

Handle more in and out formats. Be able to deal with other inputs than .flac: .mp3, .m4b, .aa... Some should be just copied, not encoded.

Leave less files in the tmp when exiting abnormally. Group tmp files under the same temporary dir?

Normalize sound power rather than range as it is done yet?

Be silent when more than one job?

More portable cpu number detection.

Cleanup ~/ hierarchy. Go from:

  +- .fysh-cache/
  ` - .fyshrc

  ` - .fysh/
      +- cache/
      +- music/
      |  +- random/
      |  `- playlist/
      `- fyshrc (or config, or something)

How do we cope with duplicates in both random & playlist?

BUG! Handle gracefully ``no space left'' on ipod (as before). Check remaining size in that case, and make sure can complete. Fixed room to leave? Delete last entry?

Subdivide cache directories. Use md5 hash?

Be able to specify a playlist (for ebooks, podcasts) but how? Have a playlist/ dir inside .fysh/ config dir? As well as on the iPod, separate from music/?

Progress indicator idea:

  |=====   | 56% full | 42 tracks done | ETA: 13:02:47
  [12:45:52] Message xxx.
  [12:46:00] Another message yyy.

Rework a bit the architecture: cache should maintain its statistics. Also, it should be transparent to the caller wheather we have a cache hit or not. For this to work, we should supply the cache with a callback to use in case of cache miss to actually do the computation.

Be able to limit cpu consumption? Use cpulimit for that.

Be smarter when not deleting songs on iPod, and re-selecting the same? Do not overwrite? Skip?