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/playlist-shuffle.py -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 <ct@piglets.com> # 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[loop]): item.append(all_lines[loop]) loop = loop + 1 # A proper regexp for filenames would be good if loop < len(all_lines): item.append(all_lines[loop]) loop = loop + 1 if options.verbose: print item middle.append(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: file.write(line) for item in middle: for line in item: file.write(line) for line in footer: file.write(line) 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..." random.shuffle(middle) # 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: print_banner() shuffle(options) if not options.quiet: print "Playlist shuffle complete..." if __name__ == '__main__': main()
This script looks like it does exactly what I'd like. I'm getting some errors when trying to run it, though.
osmc@osmc:~$ ~/shuffler.py -q -i /home/osmc/.kodi/userdata/playlists/video/test.m3u -o /home/osmc/.kodi/userdata/playlists/video/test_Shuffle.m3u
File "/home/osmc/shuffler.py", 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!
Justin
Justin,
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.
CT.
Thanks! Seems to be working great now.
Excellent :-).
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. =)
https://discourse.osmc.tv/t/howto-run-nightly-script-to-randomize-playlists/8715
My python version:
osmc@osmc:~$ python
Python 2.7.9 (default, Mar 1 2015, 13:48:22)
[GCC 4.9.2] on linux2