import os import sys import getopt import mad import ID3 __doc__ = "Generate m3u playlists (default: local dir)" __author__ = "Lawrence Oluyede <l.oluyede@gmail.com>" __date__ = "Jul 12 2004" __version__ = "0.2" """ A simple m3u file is like this: #EXTM3U #EXTINF:111,Coldplay - In Myplace /path/to/the/song/Coldplay - In My Place.mp3 - #EXTM3U is the format descriptor (unchanging) - #EXTINF is the record marker (with extended info, unchanging) - : is the separator - 111 is the length of the track in whole seconds - , is the other separator - the name of the track (a good generator parses the ID3, if there isn't an ID3 use the file name without the extension) - /path/etc. etc. is the absolute (or relative) path to the file name of the track Requirements: - Python 2.2 - pymad for track length - http://spacepants.org/src/pymad/ - id3-py for reading ID3 infos - http://id3-py.sourceforge.net/ """ FORMAT_DESCRIPTOR = "#EXTM3U" RECORD_MARKER = "#EXTINF" def _usage(): """ print the usage message """ msg = "Usage: pyM3U.py [options] playlist_name [path]\n" msg += __doc__ + "\n" msg += "Options:\n" msg += "%5s,\t%s\t\t%s\n" % ("-n", "--no-sort", "do not sort entries by filename") msg += "%5s,\t%s\t\t\t%s\n" % ("-w", "--walk", "walk into subdirs (default: no walk)") msg += "\n%5s,\t%s\t\t\t%s\n\n" % ("-h", "--help", "display this help and exit") print msg def generate_list(name="songs_list.m3u", path=".", sort=True, walk=False): """ generates the M3U playlist with the given file name and in the given path """ fp = None try: try: if walk: # recursive version mp3_list = [os.path.join(root, i) for root, dirs, files in os.walk(path) for i in files \ if i[-3:] == "mp3"] else: # non recursive version mp3_list = [i for i in os.listdir(path) if i[-3:] == "mp3"] #print mp3_list if sort: mp3_list.sort() fp = file(name, "w") fp.write(FORMAT_DESCRIPTOR + "\n") for track in mp3_list: if not walk: track = os.path.join(path, track) else: track = os.path.abspath(track) # open the track with mad and ID3 mf = mad.MadFile(track) id3info = ID3.ID3(track) # M3U format needs seconds but # total_time returns milliseconds # hence i convert them in seconds track_length = mf.total_time() / 1000 # get the artist name and the title artist, title = id3info.artist, id3info.title # if artist and title are there if artist and title: fp.write(RECORD_MARKER + ":" + str(track_length) + "," +\ artist + " - " + title + "\n") else: fp.write(RECORD_MARKER + ":" + str(track_length) + "," +\ os.path.basename(track)[:-4] + "\n") # write the fullpath fp.write(track + "\n") except (OSError, IOError), e: print e finally: if fp: fp.close() if __name__ == "__main__": if len(sys.argv) == 1: sys.stderr.write("No playlist name given\n") sys.exit(1) options = "nhw" long_options = ["no-sort", "help", "walk"] try: opts, args = getopt.getopt(sys.argv[1:], options, long_options) except getopt.GetoptError: print "error" _usage() sys.exit(2) name, path, sort = "songs_list.m3u", ".", True walk = False #print opts, args # check cmd line args for o, a in opts: if o in ("-n", "--no-sort"): sort = False if o in ("-w", "--walk"): walk = True if o in ("-h", "--help"): _usage() sys.exit(1) try: name = args[0] except: pass try: path = args[1] except: pass #print name, path, sort if os.path.exists(path): generate_list(name, path, sort, walk) else: sys.stderr.write("Given path does not exist\n") sys.exit(2)