Python script to randomise an m3u playlist

While I’m blogging scripts for playlist manipulation here is one I use in a nightly cron job to shuffle our playlists so that various devices playing from them have some daily variety. All disclaimers apply, it’s rough and ready but WorksForMe (TM).

I have an entry in my crontab like this

0 4 * * * /home/colin/bin/ -q -i /var/media/mp3/A_Colin.m3u -o /var/media/mp3/A_Colin_Shuffle.m3u

which takes a static playlist and produces a nightly shuffled version.

#!/usr/bin/env python
# Simple script to randomise an m3u playlist
# Colin Turner <>
# 2013
# GPL v2

import random
import re

# We want to be able to process some command line options.
from optparse import OptionParser

def process_lines(options, all_lines):
  'process the list of all playlist lines into three chunks'
  # Eventually we want to support several formats
  m3u = True
  extm3u = False
  if options.verbose:
    print "Read %u lines..." % len(all_lines)
  header = list()
  middle = list()
  footer = list()
  # Check first line for #EXTM3U
  if re.match("^#EXTM3U", all_lines[0]):     if options.verbose:       print "EXTM3U format file..."     extm3u = True     header.append(all_lines[0])     del all_lines[0]      loop = 0   while loop < len(all_lines):     # Each 'item' may be multiline     item = list()     if re.match("^#EXTINF.*", all_lines[loop]):
      loop = loop + 1
    # A proper regexp for filenames would be good
    if loop < len(all_lines):
      loop = loop + 1
    if options.verbose: print item
  return (header, middle, footer)

def load_playlist(options):
  'loads the playlist into an array of arrays'
  if options.verbose:
    print "Reading playlist %s ..." % options.in_filename
  with open(options.in_filename, 'r') as file:
    all_lines = file.readlines()
  (header, middle, footer) = process_lines(options, all_lines)
  return (header, middle, footer)

def write_playlist(options, header, middle, footer):
  'writes the shuffled playlist'
  if options.verbose:
    print "Writing playlist %s ..." % options.out_filename
  with open(options.out_filename, 'w') as file:
    for line in header:
    for item in middle:
      for line in item:
    for line in footer:

def shuffle(options):
  'perform the shuffle on the playlist'
  # read the existing data into three arrays in a tuple
  (header, middle, footer) = load_playlist(options)
  # and shuffle the lines array
  if options.verbose:
    print "Shuffling..."
  # now spit them back out
  write_playlist(options, header, middle, footer)

def print_banner():
  print "playlist-shuffle"

def main():
  'the main function that kicks everything else off'
  usage = "usage: %prog [options] arg"
  parser = OptionParser(usage)
  parser.add_option("-i", "--input-file", dest="in_filename",
                    help="read playlist from FILENAME")
  parser.add_option("-o", "--output-file", dest="out_filename",
                    help="write new playlist to FILENAME")
  parser.add_option("-v", "--verbose",
                    action="store_true", dest="verbose")
  parser.add_option("-q", "--quiet", default=False,
                    action="store_true", dest="quiet")
  (options, args) = parser.parse_args()
#  if len(args) == 0:
#      parser.error("use -h for more help")
  if not options.quiet:
  if not options.quiet:
      print "Playlist shuffle complete..."
if  __name__ == '__main__':






7 responses to “Python script to randomise an m3u playlist”

  1. Justin avatar

    This script looks like it does exactly what I’d like. I’m getting some errors when trying to run it, though.

    osmc@osmc:~$ ~/ -q -i /home/osmc/.kodi/userdata/playlists/video/test.m3u -o /home/osmc/.kodi/userdata/playlists/video/test_Shuffle.m3u
    File “/home/osmc/”, line 17
    ‘process the list of all playlist lines into three chunks’
    IndentationError: expected an indented block

    I don’t know how to write scripts, so if you could give me a hand that’d be great!


    1. Colin avatar


      I tried to reply a moment ago and it seemed to get lost, so apologies if you get two replies!

      The fault is entirely mine, the way I had pasted the code into the blog and the syntax highlighter I was using didn’t show the indentation in the code, which is critical in Python. In fact I just noticed this last Friday when showing some students.

      I have swapped over to a different highlighter and you should see the indentation, it even provides a button (hover over the area) to copy all the code to your clipboard.

      Let me know if you get success now or have any other problems.

      Thanks for the comment and the heads up.


      1. Justin avatar

        Thanks! Seems to be working great now.

        1. Colin avatar

          Excellent :-).

          1. Justin avatar

            I’ve added a guide to installing your script on the forums of the linux mediacenter distro that I use (OSMC). Thanks again for the code. =)

            [HowTo] Run nightly script to randomize playlists

            I’ve found a python script that reads a .m3u playlist and randomizes it so that it doesn’t always play the media in the same order. I was getting quite tired of the same video always playing first every time I opened a playlist. All credit for the script goes to Colin Turner @

  2. Justin avatar

    My python version:

    osmc@osmc:~$ python
    Python 2.7.9 (default, Mar 1 2015, 13:48:22)
    [GCC 4.9.2] on linux2

  3. Python Script To Copy a Playlist and Linked Files | Proving the Obviously Untrue

    […] previous Python scripts (that allow for files to be appended to a playlist on the command line, and shuffle a playlist from the command line) to make a – well – bit of a Frankenstein’s monster that will take a playlist as […]

Leave a Reply

Your email address will not be published. Required fields are marked *