Using Beets to Migrate from Google Play Music to Plex - Part 1

This blog post is now really old, but I've posted it anyway since I've started my blog over and some parts of this can be used again. Simply replace Google Play Music with the music service of your choice that happens to be closing down.

If you haven't already heard Google Play Music is sunsetting meaning Google is closing down the service completely and you'll no longer be able to stream music from the free app. It's a shame because it was an excellent service. I made the switch to it a number of years ago when I was moving away from iPhone to Android. At the time I needed an alternative to iTunes.

The advertising giant has made efforts to migrate all users over to YouTube Music, their paid streaming option and replacement for Google Play Music. A free version of YouTube Music is available but it's still missing some basic features that really should be included in any music player app. The ability to play music while the app is in the background is too basic to not have as standard.

One of the best things about GPM was that it was free and ad-free at that. You could upload a massive load of tracks—I think 50,000—and listen to them on any device via the browser or apps on both iPhone and Android.

While there are a lot of other streaming services such as Spotify, nearly all have a subscription fee and those that are free, have their other significant limitations. If you've purchased and ripped a lot of music over the years to build up a big collection, you'll want to preserve that and maybe even keep your playlists as well. I decided to go for Plex Media Server as the host for my music because it would bring my entire media collection of movies and TV shows together and still allow me to stream it remotely anywhere in the world.

Google has made it pretty easy for you to download all your music from Google Play Music if you don't want to transfer everything over to YouTube Music. You can either use the recently added feature in the settings menu to download every song or you can use Takeout which will package up all your music, including the playlist files and give you a number of zip files to download, depending on the size of your library. Even though my library is fairly small - under 10,000 songs - it was still over 70GB to download, so I had to leave my machine running while everything downloaded.

I opted to download all my songs via Google Play Music itself. The trouble is, as I said before, it downloads each song individually and not in any logical folder structure like artist/album/song. Since I wanted to import everything into Plex I needed to have that structure otherwise everything would import under one album of "Various Artists". Not what I wanted. I figured now was as good a time as any to properly organise my music collection, fix the issues with the tagging, and have a consistent naming convention for all the files too.

Beets

Beets is a free command-line application used to, in the words of the developers on their site, "get your music collection right once and for all". It uses MusicBrainz.org to gather the correct metadata tags for each song. Perfect! I thought. I can use this to tidy up the song tags and put them into the folders for Plex to import without much effort. Not so fast. It turns out that Beets also wants to have a nice folder structure to work with. It can import individual songs but it's not a great experience on that many songs and manually importing one song at a time would be way too time consuming. Still, I liked what Beets had toIt was that folder structure problem again. What I then tried was to use a bash loop to import each individual file and update the tags one by one thinking this surely wouldn't take that long to do. The problem there was that it really did take ages to do. And it wasn't helped by MusicBrainz restricting my IP because of over-requesting data as a result of the first command. Here's the command I ran anyway. offer and I found a Docker image by the awesome folk at LinuxServer.io. This allowed me to get set up and running in a matter of minutes.

Once logged into the newly running container, and after reading the docs, I was ready to get started sorting out my library and importing it into Plex.

$ docker exec -it beets /bin/sh

As the docs point out, using the autotagger function can take a long time especially on a large library and it's an interactive process, so be prepared to spend a significant amount of time at the computer checking the tags that Beets finds for your music.

Without really knowing how long it would take to import my music, I decided to just get cracking with it and see how it goes. What I said earlier about reading the docs first. That was a lie; at least in part. I did read the docs but not extensively and I thought I could just run a single command on the folder that contained every mp3 file and beets would do the rest. Not quite.

$ beet import /path/to/music .

It was that folder structure problem again. What I then tried was to use a bash loop to import each individual file and update the tags one by one thinking this surely wouldn't take that long to do. Wrong again. It really did take ages and it wasn't helped by MusicBrainz restricting my IP because of over-requesting data as a result of the first command. Here's the command I ran anyway.

$ for track in *; beet import -t -m "$track"; done

By this time I'd learned a couple of additional flags to add.

-t is for timid mode which asks you what you want to do at every decision point. Without this Beets will assume a match it found is what you want when the match percentage is high enough. It's good, but not perfect.

-m is for moving tracks instead of copying them which is the default action Beets will take. I had already defined the location to move the processed tracks to in the config file.

This command works fine and does the job of allowing me to import my songs without having to put them into folders. It's just slow. Really slow. What's more, I was making mistakes and tagging songs with the incorrect album info. Did you know different releases by the same artist can have different names in different countries and even different track listings? A couple of tracks from one an album eneded up showing as separate albums but with the same album art. It started me thinking about how it would be faster to just manually folderise (probably not a word) the songs manually and then just import them into Plex. That way I would just need to put them in the right folders and Plex would find the album info from the metadata tags.

I looked at the folder of songs and began to weep a little. I didn't want to spend my time putting songs into folders and I didn't want to import one song at a time. I know some programming and, with quick search, I found a couple of python modules that I could use to read each mp3 file. I could get the artist, album and any other metadata, and then put the tracks into their appropriate folders automatically. The module I ended up using was called Mutagen and this is the script I wrote.

from mutagen.id3 import ID3, ID3NoHeaderError
import os
import shutil

def getAlbumName(folder):
	for file in os.listdir(folder):
	  if file.endswith(".mp3"):
			musicPath = os.path.join(folder, file)
      print("checking:", musicPath)
      try:
	      audio = ID3(musicPath)
        if 'TALB' in audio:
	        print(audio['TALB'].text[0])
          newPath = os.path.join(folder,audio['TALB'].text[0])
          if os.path.exists(newPath):
	          shutil.move(musicPath,newPath)
          else:
	          try:
	            os.mkdir(newPath)
            except OSError:
	            print ("Creation of the directory %s failed" % newPath)
            else:
	            print ("Successfully created the directory %s " % newPath)
              shutil.move(musicPath, newPath)
              print("Moved file")
            except ID3NoHeaderError:
	            print("No tags available. Can't sort this one")

getAlbumName('/media/Volume5/Music from Google Play Music/')

I don't really recommend using this script to sort songs into their folders. The mistake I made, and only realised after the script was running, was that I was only looking for the album name and not the artist as well. A stupid error that meant any albums with the same name, but by different artists, would be placed into a single folder. Not a big problem for my library as it only affected a couple of "greatest hits" albums: “Stevie Wonder - Number Ones” and “Michael Jackson - Number Ones” as one example.

Having said that, I have posted the mp3Folderiser on my GitHub so please feel free to use it and/or modify to suit your own needs.

Running the script got me most of the way to being able to import my music into Plex and made it possible to run the Beets command properly.

$ beet import -t -m /path/to/googlePlayMusic/

This is where Beets really starts to shine. Beets runs a multi-threaded importer meaning it can ask you to make decisions while looking up the metadata for the next album and moving your tracks in the background. This made it much much faster to use. While no application is perfect, Beets does a great job at getting the right metadata and even correctly suggested renaming tracks that had the wrong tags in the first place using some kind of wizardry I haven't yet understood.

Continue reading the next part on importing into Plex.