Music

Porting Playlists With Python

I had a brief sting last year where I was using Spotify, but I dumped it, mostly for financial reasons, but also because as much as I like the ability to just, listen to whatever, I kind of dislike the whole “Music as a service” aspect. I can still find new stuff via Youtube and then add it to my list of “Albums to maybe buy eventually”.

One thing I lost though was my Playlists. I was worried they were just gone, soon after logging in, I swear they hd just vanished, but checking now, they seem to all be there again. Whatever the case, I wanted a backup copy.

This is of course, an arduous thing to do, particularly my large “play random tracks” list, which has 1200+ songs. I don’t have time to type all that out, or to search and find all these tracks on Youtube. There are services, but they tend to be limited unless you want to pay, which is more annoying than anything.

Exporting from Spotify

Thankfully, i can use Python. I needed a script that would pull down my playlists and dump them to simplet text files. I actually had originally asked Perplexity to build this script, which it did, but the API method it used didn’t match the one I had previously used during my Python class, to make a Plylist generator for Spotify.

Instead of doing what would probably be the easier thing, and figuring out whate OAUTH method the Perplexity script uses, I just, rebuilt things using the Spotipy library, which is what I had used previously. So this script is one I made, for the most part.

It connects and gets a list of all the playlists you have, then loops through that list, and on ech playlist, pulls down all the track names, and writes them to a text file, in the format Artist – Album – Track Name.

The credentials go into a file int he same directory called auth,py with the following format of your Spotify Developer credentials.  Keep the quotation marks.

SPOTIPY_CLIENT_ID = "YOUR CLIENT ID"  
SPOTIPY_CLIENT_SECRET = "YOUR CLIENT SECRET"  
SPOTIPY_REDIRECT_URI = "http://localhost"  
SPOTIFY_USERNAME = "YOUR USER ID NUMBER"
import requests
import os
import spotipy
from auth import *
from spotipy.oauth2 import SpotifyOAuth

sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=SPOTIPY_CLIENT_ID,
                                               client_secret=SPOTIPY_CLIENT_SECRET,
                                               redirect_uri=SPOTIPY_REDIRECT_URI,
                                               scope="user-library-read",
                                               cache_path="token.txt"))

def get_all_playlists():
    playlists = []
    limit = 50
    offset = 0
    playlists = sp.current_user_playlists(limit, offset)
    return playlists

## https://stackoverflow.com/questions/39086287/spotipy-how-to-read-more-than-100-tracks-from-a-playlist
def get_playlist_tracks(username,playlist_id):
    results = sp.user_playlist_tracks(username,playlist_id)
    tracks = results['items']
    while results['next']:
        results = sp.next(results)
        tracks.extend(results['items'])
    return tracks

def save_playlists_to_files(this_list, listname):
    if not os.path.exists('lists'):
        os.makedirs('lists')
    # Sanitize filename for filesystem
    safe_name = listname.replace('/', '_').replace('\\', '_')
    filename = f"lists/{safe_name}.txt"

    with open(filename, 'w', encoding='utf-8') as f:
         f.write(f"Playlist: {listname}\n")
         f.write("Tracks:\n")
            # Optionally, you can fetch and list track names here
         for eachtrack in this_list:
             f.write(f"{eachtrack}\n")

playlists = get_all_playlists()
#print(playlists)
for each in playlists['items']:
   this_list=[]
   #print(each['name'])
   listid = each['id']
   ownerid = each['owner']['id']
   #print("\n")
   mytracks = get_playlist_tracks(ownerid,listid)
   for eachtrack in mytracks:
      trackentry = f"{eachtrack['track']['artists'][0]['name']} - {eachtrack['track']['album']['name']} - {eachtrack['track']['name']}"
      this_list.append(trackentry)
      #print(trackentry)
   save_playlists_to_files(this_list, each['name'])

Everything gets output to a folder called “lists”.

Importing to Youtube

But what to do with these lists?  It’s going to be a bit more complicated to try to get Python to build them from my private music collection.  I have a LOT of the tracks, I don’t have all of the tracks, I also would need it to scan through well, it’s a fuckton, of music files, some tens of thousands, maybe more, decide on a file, and add it to a winamp or VLC playlist.

What I can do though, for now, is make a big ass YouTube Playlist.  

I have no experience with the Youtube API, so I just asked Perplexity for this script, specifically:

“create a python script that will take a text file list of sings, as an input, one song on each line, formatted “artist – Album – Song title” and search Youtube for the artist and song, and add the first result to a new playlist named after the name of the file”

It did some thinking, then gave me a script and instructions on how to set up OAUTH credentials on Youtube.  I then did a test run of the script on one of the shorter list files and, sure enough, it worked perfectly.  I have included the script below.

You need to create an app here, and create OATH Credentials, and download the file, place it int he folder with the script below, renammed to “client_secret.json”.

The script requires the following dependencies.

pip install google-auth-oauthlib google-auth-httplib2 google-api-python-client

Something not mentioned by Perplexity, that I found a solution for on Stack Overflow, after getting an error, you need to add users. On the App page (you should be sitting there after creating the app), Select the “Audience” tab on the side bar, then a bit down, add a “Test User” by email address, which is the email address associated with your Youtube Channel that you want ot attach the playlists.

import os
import argparse
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow

SCOPES = ["https://www.googleapis.com/auth/youtube.force-ssl"]

def create_playlist_and_add_songs(file_path):
    # Authenticate and build service
    flow = InstalledAppFlow.from_client_secrets_file("client_secret.json", SCOPES)
    credentials = flow.run_local_server(port=0)
    youtube = build("youtube", "v3", credentials=credentials)

    # Get playlist name from filename
    playlist_name = os.path.splitext(os.path.basename(file_path))[0]

    # Create new playlist
    playlist = youtube.playlists().insert(
        part="snippet,status",
        body={
            "snippet": {
                "title": playlist_name,
                "description": f"Auto-generated from {playlist_name}"
            },
            "status": {"privacyStatus": "private"}
        }
    ).execute()
    playlist_id = playlist["id"]

    # Process songs
    with open(file_path, "r") as f:
        for line in f:
            parts = line.strip().split(" - ", 2)
            if len(parts) != 3:
                print(f"Skipping malformed line: {line}")
                continue

            artist, album, song = parts
            query = f"{artist} {song}"
            
            # Search for video
            search_response = youtube.search().list(
                q=query,
                part="id",
                maxResults=1,
                type="video"
            ).execute()
            
            if not search_response.get("items"):
                print(f"No results for: {query}")
                continue
            
            video_id = search_response["items"][0]["id"]["videoId"]

            # Add to playlist
            youtube.playlistItems().insert(
                part="snippet",
                body={
                    "snippet": {
                        "playlistId": playlist_id,
                        "resourceId": {
                            "kind": "youtube#video",
                            "videoId": video_id
                        }
                    }
                }
            ).execute()
            print(f"Added {artist} - {song}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("input_file", help="Text file containing songs")
    args = parser.parse_args()
    create_playlist_and_add_songs(args.input_file)

And here is the final imported version of my Raffaella playlist from Spotify.

Duolingo’s Music and Math Courses

Man, talk about both exciting and frustrating all at once. Duolingo launched both a Math and Music course recently, but it was iOS only, initially, and I use Android. It would come eventually though, and it apparently has, and I missed it, or at least, missed the announcement, if there was one. I have been periodically checking and they were not there until fairly recently.

I don’t really have a lot of need or interest in the Math course, but I wasn’t in a good place to try out the music course, so I started off on the Math one for a bit. I am already great at math, I mean, seriously, I have probably done more math than most people have, between school and hobbies and work. But hey, why not.

From what I have done, it’s, kind of weird? It’s all pretty basic Adding, subtracting, multiplying, and fractions so far. But there are often these blocks instead of actual numbers. Which I kind of get is intended to encourage counting, but some of the presentation on the groupings isn’t as consistent as it could be. Plus it just, feels like adding an extra counting step to slow you down. And no, I am not individually counting blocks, I used to count as a job, I can count groups very quickly. Which is also why I noticed the occasional inconsistency that almost felt like it was done purposely as a trip.

Maybe it was.

The real fun part though is that, it’s smart enough to recognize “goofy answers”. Like it has a block of squares to shade, 3/5ths or something. You can shade a random assortment of the 100 squares, just so long as it’s 60 total shaded. Or if it gives you an open ended question like “2/6+1/6”. Sure, you could put 3/6, or 1/2, but it will also take 3987/7974.

But enough math nonsense, my real interest is in the Music course. I really want to learn music, it was one of my “Decade resolutions” in 2020. To be done by 2030. I have really been looking forward to the music course.

And I like it. Even if so far it’s just banging out C, D, and E on the scales. It’s that repetition I want so I can better read sheet music.

But oh my God it’s frustrating as hell to actually do.

And not because it’s hard, but because there is a lot of weird lag and stutter. Every few courses you do a song snipped using notes you know, and so many times I miss a few because it… Just… rand… om… ly… stop…s and… stu… tt…ers…. As it slides along.

At the bare minimum, it’s distracting.

I don’t honestly understand WHY either. I would blame processing power, but I have a decent enough phone that can do other rhythm based games, just fine, often at a much much faster BPM.

I feel like part of the problem is the weird “holding” it sometimes asks for on notes. Like if I could just tap the notes to the beat, everything would run fine, but it often requires these half beat holds, which only exacerbates the stuttering issue since it causes more stutter, and means you can’t just move on and get the next note and try to compensate for the stutter.

It’s just really frustrating. I doubt I go very far in the course as is, as much as I really want to.

Calibrating My Audio-Technica AT-LP60

I don’t have a ton of vinyl records, but I do like to actually listen to them. It’s a topic for its own entire post, but I don’t collect anything for its “value”. I collect because I want to enjoy it. I point this out a bit because I also have a shitload of toys. I noticed something recently, that I am surprised I didn’t notice before, or maybe it just, didn’t actually click that it was an issue. Last week I got 1989 (Taylor’s Version). While listening to that, everything seemed, slightly too fast. I think I may have noticed this a bit with my Bone’s 10th vinyl as well. In the case of the Taylor Swift album, I decided it was just something to do with it being a re-recorded album, and not a straight remaster/release.

More recently, I got my copy of Aurora’s All My Demons… (Commentary here)…

Because I started hardcore tracking my listening with Last.fm years ago, I can say, with confidence, that I have listened to this album a lot. I can’t say it’s my most listened to album of all time for sure, but I can say, it’s the top since I started tracking. When listening to it, things were definitely off. The whole thing was running slightly too fast, and Aurora’s wonderful vocals sounded weird.

My first thought was, that maybe the belt was wearing out. It also occurred to me, that it’s a belt, it probably has a tension adjustment somewhere. I looked up a copy of the manual, which didn’t mention it anywhere. But, various audio forums did mention it. On the bottom of the players, are two small holes, where a screwdriver can be inserted and the tension adjusted, altering the rotation speed.

The problem then was, how to know if the speed was right. I probably could have done it by ear with All My Demons, but the adjustment is on the bottom, I can’t adjust it while it’s playing (well, not easily). It turns out, there are technical ways to do this as well. One of the search results mentioned a printable strobe guide. I’m not positive what this is, but I can infer based on other things I know of. I suspect it works like a Zeotrope, where you get a sort of animation going when the record spins at the proper speed.

Another result suggested an app called RPM Speed and Wow. As the name suggests, it uses a phone’s accelerometer to measure the RPM and Wow of a turn table. I’m not entirely sure what Wow is, it seems to be related to audio distortion, I may look into that later a bit more. For now, the concern was the speed. I loaded up the app, placed the phone on the turn table, pressed the “pause” button on the player, which prevents the arm from dropping, but not the table from spinning, and pressed play. After about a minute, I had a measurement of 34.99 RPM, almost 5% off.

Suddenly it makes sense why all the music seemed too fast, because it was!

I dug out a small screw driver and carefully lifted the player up to turn the knob. One issue was that I wasn’t sure which direction to go. I went with clockwise (Spoilers, the correct direction is counter clockwise). I tested again, but it didn’t change. I tried counter clockwise, no real change. So I went and got an even smaller screwdriver.

Left Screwdriver was too large to fit, the right was needed.

It takes a very small screwdriver to get in the hole properly to adjust the knob. Also, it takes a very very very small amount of turn to adjust the speed. The best way I can describe it, I needed a 5% change, which pretty much meant a 5% turn out of a whole circle. I doubt it’s actually that exact, but it’s very very slight.

Anyway, after going Clockwise, things got faster, so I lifted things up and went counter-clockwise until I landed on 33.12 RPM. This is around half a percent too slow, which frankly, is close enough. Probably as close as I am going to get without seriously altering my methods. For one thing, during at least one tip to adjust, the turntable itself fell off, so I had to put it and the belt back on, which probably screws up these small adjustments I’m making as more than half a percent.

I put my All My Demons record back on the turn table and fired it up, and it was better, much much better, enough that it wasn’t noticeably off.

Just as a quick wrap up, I want to give a shout out to this Matco screwdriver set. A friend of mine in High School gave this set to me for my birthday, I think my 16th. His dad worked for Matco and there were a ton of Matco tools in his house. Anyway, it’s served me well, repeatedly, for over 25 years now. It’s a super useful set of screwdrivers (the pen not so much, I’ve never used the pen).

Weekly Wrap-Up (09.03.2023 to 09.09.2023)

This week will be a bit music-heavy, not so much about anything specific, but about what I have been doing in general. It honestly could almost be its own, separate post and topic, instead of a weekly wrap post.
Anyway.

Roughly, 4 months or so ago, Target Circle had a 3 months free offer for Apple Music and Apple TV. I have no interest in Apple TV’s content, sorry Ted Lasso. I did take the offer, so I could watch Tetris, then immediately set it to cancel. The Apple Music I did want to try out.

I don’t make it any sort of secret that I prefer buying music, but I am increasingly kind of wishing I had a paid streaming option, somewhat primarily so I can sample artists a bit easier. Also, sometimes I just want to listen to some particular song or artist and it is otherwise inconvenient to do. Amazon really fucking screwed me up with they broke Amazon Music. I will never forgive them. I owned a lot of my music through Amazon, and could just “pick up and listen” easily in their app. But the app started CONSTANTLY begging you to subscribe to the premium option, and then the last straw was that it no longer does anything but shuffle, even if you own it unless you subscribe.

Bull.

Shit.

So anyway, in the past, I have had a 6-month trial of Spotify, and I had a 3-month trial on Tidal, and I have some YouTube playlists but Vanced Player finally broke broke. The easy and obvious choice is Spotify. Everyone uses Spotify, it’s the defacto choice. I wasn’t super keen on Spotify because one, they don’t include HiFi Audio. Tidal charges extra (by a lot) so Tidal was out for this reason as well. Tidal in general is very expensive compared to everyone else. Secondly, Spotify pays artists pretty low compared to others. I like supporting artists.

I had decided Apple Music may be a good choice, this trial was a chance to try it out. And I subscribed for a month at the paid tier. What I wanted though, was to do the Family Plan. For like, $6 more, I could eliminate the headache of conflicting with my wife listening at home on the Echo while I was at work. For $6 more, I could let my kids have music as well, so they don’t have to rely on random services or YouTube.

Except it turns out, that Apple, does not have a web-based account management system for Apple Music. To manage family sharing, you MUST use an iPhone or a Mac. I don’t have either one of these. I am actually vaguely considering getting a Mac for my next laptop, but currently, I don’t have either. So that’s completely not happening.

So for now, I have canceled that Apple Music subscription, and I have decided to just go with Spotify. I probably don’t need the HiFi audio anyway, since most of this listening is done with Bluetooth to my earbuds or my car anyway, and I still pay artists directly buying music anyway.

The pain now is, Spotify gave me a 3-month discount deal, for a single plan. So my family may be slightly screwed out of that for a bit. I honestly don’t think they even care about the overall prospect of a music service anyway.

One thing though, which brings this a bit into “What I did this week”, is to consolidate all of my music across these services into Spotify. It didn’t take too long, because I have never used any of them for a super long term. I used a tool called Soundiiz, which came up as recommended for most of it. The free plan is a bit limited though, so some had to be done manually. I was going to just cough up the $3 for a month of their paid tier so it would be instant, but it’s only $3 if you “pay annually”, and it’s $4.50 otherwise. That extra $1.50 wasn’t the killer for me, it was the bull shit annoying “marketing deception”. I HATE that crap. If it had been upfront with “4.50/month” or “$36/year”, I would probably have just paid for a month.

The core transfer was mostly playlists, and only two were larger than the 200 song limit. So I just transferred them in multiple chunks and then merged them back into the Spotify App. For liked Artists, I just set up side-by-side windows and manually searched on Spotify.  This also played nicely into another music project I had started on Apple Music to build a “Huge playlist of music I like that I can just play on shuffle”.  You can find it here or below, and my profile is here.

Activity Log

I mentioned last week getting a bit of a bonus at work.  That came through so I was a bit less restricted on a few things, in one case, with Humble Bundle, where I went for the following.

  • Masterful 3D Platfomrs – Primarily because I wanted A Hat in Time, but also because I enjoy these sorts of games, especially after playing through Yooka Laylee recently.
  • Tales from Wales Interactive – It’s cheap and I’ve been kind of wanting to try some of these FMV-style games, especially as I do like playing through CYOA Interactive Fiction text-style games.
  • DinoFever – Bought almost exclusively for the Turok games, because at the moment I have been playing Quake II Remastered and I’m on a bit of an “old school FPS Kick”. Everything else looked pretty interesting as well, and it’s cheap.
  • Dungeon Crawl Classics MEGA Bundle – I have this crazy fantasy that one day I will be able to play tabletop games. Please don’t judge me.

Books

  • Max and the Multiverse: A Sci-Fi Comedy Novel by Zachry Wheeler – It was free, sounded interesting
  • An Enemy Reborn (Realms of Chaos) by Michael A. Stackpole, William F. Wu – I swear I have heard of this author before, and it sounded interesting. It looks like he has done some Star Wars books.
  • The Hedge Knight (A Game of Thrones) by George RR Martin – Game of Thrones is still cool right? WHERE IS WINDS OF WINTER GEORGE???
  • 15-Minute Spanish: Learn in Just 12 Weeks (DK 15-Minute Langauge Learning) – I am not quitting Duolingo, but I really feel like my Spanish learning is stalling a bit so I want to supplement it a bit again. I’m actually explicitly blaming Duo for this because they have changed the learning tree like 4 or 5 times now and every time it feels like they push my progress way back. I mean, the goal is to learn the language, not finish some arbitrary tree, but it’s really really discouraging.
  • Woke Up Like This: A Novel by Amy Lea, Mindy Kaling – Every month Amazon Prime includes a selection of free books. I almost never read them and half the time I don’t redeem them, but I have been trying to pick out one just because it’s there.

Weekly Wrap Up (07.30.2023 to 08.05.2023)

Who knows how long this one will last, but I’ve decided to try something different for Saturdays. Basically, just a sort of, rambly, weekly wrap up of… life. No structured requirements, maybe nothing happened and it ends up being short. Basically just sort of, straight regular journaling. What I’ve been doing, what I’ve gotten new, any major events, that sort of thing. I won’t discuss work really, except in vague terms, for a variety of reasons.

Something little I’ve been wanting to do, I added some outside speakers to my music set up, so I can listen to music outside while on the deck. I actually mounted them below the deck, so they would work above and below, but if it doesn’t really work out I can always get a second set for above.

The big thing this week was working on doing Blaugust. I’m taking the mad man route of trying to post at least one post a day. So far, I have…. some… pre written and scheduled, and some TBD. I doubt I keep up this pace after August. I usually keep gaming posts on Lameazoid, but it helps a lot that I’m bored of Fortnite so I’m not super playing it these days. I managed to get Optimus Prime out of the Battle Pass, which that and Summer Meowscles were basically all I cared about. I will probably skip next BP and not play for a while unless it has some super amazing stuff in it. I saw a rumor they may do an Overwatch Collab, which…. I would be really likely to go in for. Because I really like Overwatch as a concept, but I absolutely HATE Overwatch as a game.

Anyway, grinding a game like Fortnite normally eats up too much of my spare time. It’s Unhealthy gaming honestly. In slightly more healthy gaming, I picked up the Avengers game, because it’s being de-listed and it’s on sale for $6, and a bundle of Train Simulator add-ons from Fanatical, because maybe one day I will get on a TrainSim kick like I do with Truck Simulator.

It’s probably worth mentioning new toy stuff for the week too, though that really is also a Lameazoid topic, so I’ll keep it to a minimum. My Pile of Loot from BBTS reached it’s 90 days and needed shipped, so I’ve added that to the collection. I also picked up a lone Transformer from Ross. Let’s just make this one a list.

  • Transformers Kingdom Deluxe Pipes (why did I never get Huffer, the superior one???)
  • Star Wars Black Series Cassian Andor and B2EMO – I need a better Cassian than the awful original Rogue One release and this two pack was cheaper than a single BS figure.
  • Star Wars Black Series Mara Jade – It’s fucking Mara Jade. No more reason needed. Why the Sequels cut all the existing post OT lore is beyond me.
  • Power Rangers Lightning Collection Rita Repulsa – My PRLC is pretty much limited to mighty Morphin’, and it was basically there except for Rita, which was previously only available in a 2 pack with Lord Zedd, whom I already had. Now I have Rita, and she’s a pretty good figure, but I’m a sucker for cloth goods.
  • Power Rangers Lighting Collection Minotaur – OK, Might Morphin’, and any cool monsters they put out. And I need to stop buying the monsters at full retail. They ALWAYS go on markdown/clearance. So far I’ve gotten them all except Pumpkin Rapper, which I should have done, and the Snake Man, which hits all the right buttons, but I can’t bring myself to get it because it looks kind of lame. Anyway, a Minotaur figure is useful to have in general for fantasy stuff.
  • Jada Toys Street Fighter Ryu – Everyone in the toy community is stoked for this line, and Jada in general. Now that I have the first two releases, I’m more excited, for Street Fighter and for their Mega Man stuff. Because these are good figures.
  • Jada Toys Street Fighter Fei Long – I like him even more than I do Ryu.

Something else that might be useful here, with no context, and mostly for my own reference, I’m going to throw out a list of new (to me) music I may have listened to this week. It’s easy at the moment because I’m trying out Apple Music. i tend to keep this huge list of random notes of “Artists to listen to,” but never actually get to them. I want to try to get better about just, throwing them onto the endless playlist and listening to them.

Ok, I said no context, but maybe, a LITTLE bit of context might be useful.

  • Apple had one of their suggested playlists that was just called something like “African Music”, which was a collection of music, by artists from Africa. Lots of sort of hip hip/reggae sort of music. It was good stuff, but I skipped over it after a bit because I wanted to get to well, something else. It’s not that I wasn’t enjoying it, I just wanted to try other new music.
  • Let’s Eat Grandma – I think this one was a Facebook or Instagram Ad. I want to say it was decent.
  • Bluhm – I think this was another FB/IG “Suggested post” This is actually a fairly common place for me to find suggestions.
  • Laufey – Ben Folds is hosting or performing with, I’m not sure what, but basically, Ben Folds and Dodie are doing a thing with Laufey, so I thought I would give her music a try. It’s pretty good. Dodie-ish.
  • Skyr0 – Another Instagram suggestion, but this time it was a Reels suggestion. Some pretty interesting Synth music.
  • Blondshell – A bit more rock/alternative, a photographer I follow who seems to share some of the same tastes in music posted photos from a Blondshell show, so I decided to give it a listen.
  • Jade Bird – Suggested I think in the Lauren Mayberry Discord. I need to give it another go to jog my memory of if I liked it.
  • Half Gringa – One of the acts that’s going to be at Pygmalion, which I am going to in a month or so. So I wanted to listen. I decided I liked it enough to try to catch the live act, then realized it’s not actually at the event I am going to, it was just, posted by the event’s IG.
  • Claud – This one IS going to be at Pygmalion, and right before Lauren’s show, so I’ll definitely be catching their show. It’s good stuff. Some strong “King Princess but maybe not quite as raunchy” vibes.
  • David Byrne/Talking Heads – Occasionally I am reminded of some older artists and I decided that I can’t actually remember which songs they did, so I’ll throw on the “Essentials” list from Apple Music. This was the case for David Byrne. I’ve decided I don’t really care that much for David Byrne, though Talking Heads are decent..
  • David Bowie – It was also the case for David Bowie, except I know what songs David Bowie did, I just…. wanted to listen to a bunch of Bowie.