World of Cheese

v 31 jĂșlius 2016

Automatically generating genre-based m3u playlists

Posted by Andy in Tech   

Following the computer woes here <{filename}/ITmeltdown.rst> and subsequent IT rebuilds, the house finally has all the pis working. Mopidy is proving a tidy music system but it is very album/artist based but there is the possibility of using m3u play lists. My idea was to use genre playlists as a way of having a wide selection of music and not being forced to change/choose tracks after every album.

I was hoping to find a pre-writed program which would spit out the relevant data and could be incorporated into a bashscript. However, there seemed to be no decent linux programs which would do all that I wanted automagically. My solution is to write a python3 program which finds and reads every genre of mp3/m4a/mp4 in the Music folder and then to sort them into genre specfic playlists. I've used mutagen for the process of the metadata as it had the best online examples which worked at the time of writing

I know it isn't fast of pretty but it is much quicker than doing this all by hand

Here it is

#!/usr/bin/env python3
from glob import glob
import fnmatch,  os
from mutagen.easyid3 import EasyID3
from mutagen.mp4 import MP4

def findall(music):
    music_list = []
    for root, dirnames, filenames in os.walk(music):
        for filename in fnmatch.filter(filenames, '*.m*'):
            if filename.endswith("m3u"):
                    continue
            music_list.append(os.path.join(root, filename))
    return sorted(music_list)

def generate_m3u(music_files):
    m3u_master = {}
    for filename in music_files:
        if filename.endswith("mp3"):
            mp3info = EasyID3(filename)
            genre = mp3info['genre'][0]
        elif filename.endswith("m4a"):
            mp3info = MP4(filename)
            genre = mp3info['\xa9gen'][0]
        else:
            print(filename)
            genre = "wrong files"
        if not genre in m3u_master:
            m3u_master[genre]=[]
        m3u_master[genre].append(filename)
    return m3u_master

def m3u_save(m3u_list, Playlist):
    for genre in m3u_list:
        genre_file = os.path.join(Playlist, genre.replace(" ","_") + ".m3u")
        with open(genre_file, mode='wt', encoding='utf-8') as myfile:
            myfile.write('\n'.join(m3u_list[genre]))


if __name__ == "__main__":
    Music = "/external/Music"
    Playlist = "/external/Playlists"
    music_files = findall(Music)
    m3u_list = generate_m3u(music_files)
    m3u_save(m3u_list, Playlist)

    
 
 

Comments