Musings of a dad with too much time on his hands and not enough to do. Wait. Reverse that.

Month: May 2018 (Page 2 of 2)

Music to drive by, Part 2

A while back, I posted about my challenges putting together a flash drive containing the music I’d like to listen to in the car when not listening to podcasts and so forth. Well, I’d like to offer an update on that effort.

In my original post, I discussed a script that first inventoried all my music then copied select mp3s to my flash drive based on whatever criteria I chose–in my example, my primary criteria was the song’s genre. In retrospect, I think it might be smarter to break those operations out into two scripts: one script to inventory my music and write the inventory to a JSON file and a second script to read that file, apply whatever filtering criteria I wish to apply, and copy the resulting mp3 files to a destination like a flash drive.

Create my inventory file

This script allows me to inventory my music and write it to a file. I’ll only need to re-run this script whenever there’s a change to my inventory. Having this file will, of course, allow me to proceed with the next step of this process–writing select files to my flash drive–but it will also help me figure out if I have music incorrectly labeled and it can also serve as a data file on which I can do some analysis later on. Here’s a snippet of the important piece of this script, but the full version is available on my Github page:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$music_folder = "$Env:USERPROFILE\Music"  # path to my music files
$dirs_to_exclude = "$Env:USERPROFILE\Music\soundclips"  # sub-dirs to exclude from the music collection
$mp3_collection = @()

# get a list of all the sub-directories containing MP3 files
$mp3_folders = dir "$music_folder\*.mp3" -Recurse | select Directory -Unique | where {$dirs_to_exclude -notcontains $_.Directory.FullName}

# now, loop through all my music folders to collect all the MP3s I want to process; store them in the $mp3_collection collection object
foreach($mp3_folder in $mp3_folders){
    $shell = (New-Object -ComObject Shell.Application).NameSpace($mp3_folder.Directory.FullName)
    foreach($mp3_object in $shell.Items()){
        if($shell.GetDetailsOf($mp3_object, 2) -like "MP3 File"){
            $mp3_file = [pscustomobject]@{'file' = $mp3_folder.Directory.FullName + '\' + $shell.GetDetailsOf($mp3_object, 0);
                                          'artist' = $shell.GetDetailsOf($mp3_object, 13);
                                          'album' = $shell.GetDetailsOf($mp3_object, 14);
                                          'album_year' = $shell.GetDetailsOf($mp3_object, 15);
                                          'genre' = $shell.GetDetailsOf($mp3_object, 16);
                                          'song' = $shell.GetDetailsOf($mp3_object, 21);
                                          'file_size' = $shell.GetDetailsOf($mp3_object, 1);
                                          'length' = $shell.GetDetailsOf($mp3_object, 27)}
            $mp3_collection += $mp3_file
        }
    }
    $shell = $null
}

# save collection to json object
$mp3_collection | ConvertTo-Json -Depth 5 | Out-File ($music_folder + "\mp3_collection.json")

Here’s an example of the JSON file the script will create:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[
    {
        "file":  "C:\\Users\\jdoe\\Music\\AC-DC\\Back in Black\\01_AC-DC_Hells Bells.mp3",
        "artist":  "AC/DC",
        "album":  "Back in Black",
        "album_year":  "1980",
        "genre":  "Hard Rock \u0026 Metal",
        "song":  "Hells Bells",
        "file_size":  "7.25 MB",
        "length":  "00:05:11"
    },
    {
        "file":  "C:\\Users\\jdoe\\Music\\38 Special\\The Very Best Of The A\u0026M Years (1977-1988)\\01 - Rockin\u0027 Into The Night.mp3",
        "artist":  "38 Special",
        "album":  "The Very Best Of The A\u0026M Years (1977-1988)",
        "album_year":  "2003",
        "genre":  "Rock",
        "song":  "Rockin\u0027 Into The Night",
        "file_size":  "7.56 MB",
        "length":  "00:03:59"
    },
    {
        "file":  "C:\\Users\\jdoe\\Music\\Billy Idol\\Greatest Hits\\03 - Hot In The City (2001 Digital Remaster).mp3",
        "artist":  "Billy Idol",
        "album":  "Greatest Hits",
        "album_year":  "2001",
        "genre":  "Rock",
        "song":  "Hot In The City (2001 Digital Remaster)",
        "file_size":  "7.16 MB",
        "length":  "00:03:32"
    }
]

Copying select files to my flash drive

My second script in this process will pull in my inventory file, apply whatever filters I’ve coded, and write the results to whatever destination I chose. Furthermore, I’ve added a check to limit the overall size of selected files by the size of the flash drive you’re using. Here’s a snippet of my code, but the full version is available on my Github page:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function Convert-FileSizeToMB($size){
    $return_val = 0

    switch ( $size.split(" ")[1] ){
        "GB" { $return_val = [double]$size.split(" ")[0] * 1GB }
        "MB" { $return_val = [double]$size.split(" ")[0] * 1MB }
        "KB" { $return_val = [double]$size.split(" ")[0] * 1KB }
    }

    return $return_val
}

$music_folder = "$Env:USERPROFILE\Music"  # path to my music files
$mp3_col = Get-Content ($music_folder + "\mp3_collection.json") | Out-String | ConvertFrom-Json
$flashdrive_location = "C:\temp_music_folder"  # set the location of your flashdrive here
$flashdrive_size = 14250MB  # my song selections will likely exceed the size of the flash drive, so set that size limit here

# song selection criteria
$genres_i_want = "Metal", "Hard Rock & Metal", "Rock", "Rock; Hard Rock & Metal"
$bands_to_skip = "Mel Tormé", "Starland Vocal Band", "Burt Bacharach"

# apply my selection criteria and get a list of the songs to copy over to the flashdrive
$mp3s_to_write_to_drive = $mp3_col | where {$genres_i_want -contains $_.genre} | where {$bands_to_skip -notcontains $_.artist}

$size_of_files = 0
foreach ($mp3 in $mp3s_to_write_to_drive){
    if ($size_of_files -le $flashdrive_size){
        $size_of_files += Convert-FileSizeToMB $mp3.file_size
        Copy-Item -LiteralPath $mp3.file $flashdrive_location
    }else{
        break
    }
}

Unfortunately, this script runs quite long–at least, when I’m trying to load a 16 GB flash drive. In my experience, PowerShell just doesn’t do well with big I/O operations. If this gets too annoying, I may try to throw Python at the problem and see if I can get a better runtime.

Why am I going through all this effort when I should just be able to write my whole catalog to a large flash drive?

So, you might be asking, why are you doing all this hard work when surely your music collection can fit on today’s large capacity flash drives? First of all, don’t call me Shirley (sorry, couldn’t resist). To start with, my car seems to require FAT32 formatted flash drives. Once you get above 32 GB flash drives, though, it becomes difficult, but not impossible, to format such large drives as FAT32. I did this, in fact, some time ago. I took a 64 GB flash drive, formatted it to FAT32, and copied my entire catalog to it. It worked…kind of. Strangely, my car radio only recognized a fraction of all the songs I had on the drive. Then, after a few months, my drive more or less burned up and became unusable. So, I decided to go a less radical route and try to build a more selective process–the one described above.

Did I forget something?

Not to name names, but a certain family member occasionally forgets important items as he/she rushes out of the house at the start of the day. I, too, am not immune to such forgetfulness: from time-to-time, I find myself turning around a block or two from the house just to reassure myself that the garage door is closed or coffee maker is off or whatever. In an effort to reduce or eliminate these frustrations, here are some techniques I try to employ most mornings:

1. Keep your important possessions in the same locations

“That’s your home. Are you too good for your home?!”

Happy Gilmore

All your important possessions, work-related and otherwise, should have a home. Wallet, car keys, office badge, cell phone, etc. Designate a home for these items and keep your items in their homes at all times until you need them; otherwise, you’ll burn important minutes searching for your wayward items.

2. Make a checklist

After a third time of driving to my kid’s school to drop off a forgotten lunch–cutting into my work commute–I created a morning (and evening) checklist for each child, taped it to the refrigerator, and made each one go through it every morning. It worked for the most part. Such things should work for you, too.

3. Establish a sequence of events and make it a habit

I’ve established a set sequence every morning: make the kid breakfast, get changed for the day, unload/load the dishwasher, hit the bus stop, etc. Sticking to that order helps ensure I don’t forget anything important.

4. Establish a magic number

My magic number if four: 1) wallet, 2) keys, 3) cell phone, 4) coffee mug. Every morning, I count off these four items before I leave the house and every evening I count off these four items before I leave the office.

5. Verbalize when you’ve accomplished a task

If I’m not careful, as I start to pull out of my suburb or, even worse, onto the highway, I’ll start asking myself, “did I close the garage door?” Or, “did I turn off the coffee maker?” Arrghh! To conquer that second-guessing, as I close the garage door or turn off the coffee maker, I find it effective to say out loud: “I’ve closed the garage door!” Or, “I’ve turned off the coffee maker!” I will say these statements out loud to ingrain the fact in my brain. I try to make sure no one else is around to hear lest I scare the neighbors.

6. Set up alarms for yourself on your phone

I have a recurring alarm set up on my phone that goes on when it’s time to walk with the kid out to the bus stop. I have another set up weekly to remind me to take out the garbage (a snippet of The Coasters, Yakety Yak). Alarms are a great tool for remembering your responsibilities. Have some fun with your alarms, too. I highly recommend Zedge for downloading awesome ringtones and notifications.

7. Set up events and notifications in your calendar

The wife and I make heavy use of Google calendar for tracking all our events and activities. One helpful feature of Google calendar is event reminders: for any event you create, you can attach a “reminder” in the form of either an email or notification. For my more important events, I’ll select “notification” and then decide on when I need to be notified. If the event’s simply a reminder to do something–like call the cable company and threaten to cut the cord if they don’t lower my rates–I may want my reminder to be “on time”. If the event’s a dentist appointment for the kids, I might set it for 24 hours in advance so that I have time to clear my work schedule for that hour. When you’re on your laptop, notifications can be annoying; however, if you set up your calendar on your phone, notifications will usually appear in your system tray with a little chime and can be a helpful reminder tool.

8. Prepare the night before

Nighttime preparation is critical for a successful morning rush. Consider these techniques: A) pack up whatever items you can including lunches, school and work materials, gym clothes, etc. and places these items in their respective homes (see #1), B) perform whatever tasks you can the night before to lessen the morning rush including shaving and showering, choosing your clothes for the next day, etc. and C) rehearse your morning process the night before. Rehearsing your morning can be particularly helpful for unusual mornings, such as getting ready for a morning airplane flight, leaving early for a conference or college visit, and so forth.

9. Wear a watch

Am I showing my age by advocating wearing a watch? For a while, I tried the whole rely-solely-on-my-phone-for-the-time thing, but I don’t always have my phone with me or it’s inconveniently shoved in my pocket. A watch is a great way to keep you abreast of the time and help you stay on schedule, reducing the risk of forgetting tasks and items in the morning rush.

10. Get your kids (and/or spouse) to help

Your kids should be performing morning tasks, anyway: feeding and letting out the dog, unloading the dishwasher, packing their lunches, etc. Enlist their help!

Newer posts »

© 2024 DadOverflow.com

Theme by Anders NorenUp ↑