I never thought I would autofill my iphone with music, but I recently tried it and I actually like it. You start to appreciate more types of music. In this post a python script to do the same thing for USB devices to listen to new music in my car.

It is funny how you limit yourself to a few albums/playlists over time, autofill breaks this habit. Now my daily music digest is much more variated. The autofill script is on github. It has become a bit longer than expected because I added more features.

With the required options (music lib path, destination dir path, max size of autofill), it just takes random songs. With the optional switches you can filter on genre and limit the song length. I use eyed3 to read the mp3 metadata. As it is expensive to run it against a lot of mp3 files, I dump its output to a file in json format. When using the -c option you can retrieve the metadata of your songs from this file. This makes it much faster and has the benefit (over a simple copy/paste script) that you can specify genres, etc.

Some useful things in Python:

  • recursively find files,
  • loading and storing json (note you can also use pickle),
  • optparse is a great module to deal with command line parsing (see switches below),
  • random dict key selection with random.choice,
  • become trained in catching every exception (here for example the AttributeError when eyed3 couldn't find genre.name etc.), otherwise the program will end unexpectedly!
  • rfe: it generally suits my purpose, but there are many options that could be added like filtering artist, album, and other criteria, delete previously selected songs, etc. Any ideas, feel free to post them in the comments.
  • code: split functionality over more / smaller methods and classes (length of 'path_exists_check' and 'select_genres' is convenient), build automated testing against each method.

By the way here are some other uses for your old USB drives

Script use:

$ python music_autofill.py
Mandatory option is missing: [path]

Usage: music_autofill.py [options]

  -h, --help            show this help message and exit
  -p PATH, --path=PATH  path to music lib
  -u USB, --usb=USB     path to usb stick
  -s SIZE, --size=SIZE  max size autofill in MB
  -g, --genres          filter on genres
  -l LENGTH, --length=LENGTH
                        max length of song in minutes
  -v, --verbose         verbose switch
  -c, --caching         dump music lib to json for fast retrieval

Example output

Without genres, using cache file:

$ python music_autofill.py -p "music_dir" -u ~/Desktop/tmp  -s 1000 -c 
1048576000 bytes reached, we're done!
Successfully copied: 103 / failures upon copying: 0
Cache file music_dir/my_music_library.json was used
- to run without caching, don't use the -c option
- to refresh the cache, delete the mentioned file


With -g to specify genres:

$ python music_autofill.py -p "music_dir" -u /Volumes/USB\ DISK/ -g  -s 200  -c 
provide genres to filter on, seperated by commas: brazilian beats, breaks, da bass, blues
209715200 bytes reached, we're done!
Successfully copied: 36 / failures upon copying: 0
Cache file music_dir/my_music_library.json was used

Bob Belderbos

Software Developer, Pythonista, Data Geek, Student of Life. About me