Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Subscribe
Archives
March 7, 2025

More Tooling with PowerShell

In the last article, I started sharing my experiences in build a set of PowerShell tools to help my manage my MuseScore scores. I was able to extract score properties from a compressed XML file. The next step is to extract information from the associated MP3 file. I also know I will want to update the MP3 file with extracted score information. But let's not get ahead of ourselves.

TagLibSharp

A few years ago, I wrote published a newsletter issue on setting extended properties of MP3 and image files with an open source package, TagLib. I have saved the DLL to my scripts directory so that I can easily import it into PowerShell.

Add-Type -Path C:\scripts\TagLibSharp.dll

I'll continue with the MuseScore project from last time and specify the path to the MP3 file.

$mp3Path = "$Home\Documents\MuseScore4\Scores\nocturne-chamber-orchestra\Hypnos Suite.mp3"

I can now create a TagLib.File object and extract the properties I need.

$file = [TagLib.file]::Create($(Convert-Path $mp3Path))

Notice that I converted the path to a true FileSystem path. I often find when working with third-party libraries to convert paths. I can't assume the library will understand PSDrive references. Converting the path eliminates any ambiguity.

PS C:\> $file

Tag                    : TagLib.NonContainer.Tag
Properties             : TagLib.Properties
TagTypesOnDisk         : None
TagTypes               : Id3v1, Id3v2
Name                   : C:\Users\Jeff\Documents\MuseScore4\Scores\nocturne-chamber-orchestra\Hypnos
                         Suite.mp3
MimeType               : taglib/mp3
Tell                   : 0
Length                 : 0
InvariantStartPosition : 0
InvariantEndPosition   : 12139205
Mode                   : Closed
FileAbstraction        : TagLib.File+LocalFileAbstraction
Writeable              : True
PossiblyCorrupt        : False
CorruptionReasons      :

It looks like there are nested properties.

PS C:\> $file.Properties

Codecs          : {TagLib.Mpeg.AudioHeader}
Duration        : 00:12:38.7054375
MediaTypes      : Audio
Description     : MPEG Version 1 Audio, Layer 3
AudioBitrate    : 128
AudioSampleRate : 44100
BitsPerSample   : 0
AudioChannels   : 2
VideoWidth      : 0
VideoHeight     : 0
PhotoWidth      : 0
PhotoHeight     : 0
PhotoQuality    : 0

Here's the information I need to extract.

PS C:\> $file.Properties.Duration

Days              : 0
Hours             : 0
Minutes           : 12
Seconds           : 38
Milliseconds      : 705
Ticks             : 7587054375
TotalDays         : 0.00878131293402778
TotalHours        : 0.210751510416667
TotalMinutes      : 12.645090625
TotalSeconds      : 758.7054375
TotalMilliseconds : 758705.4375

And it is already formatted as a TimeSpan object! In the last article, I was creating a custom object for the score. Now, I can add the length.

[PSCustomObject]@{
    Title      = $title
    SubTitle   = $subTitle
    Composer   = $composer
    Duration   = $file.Properties.Duration
    CoverArt   = $CoverArt
    Copyright  = $copyright
    Online     = $online
    Path       = $Path
}

> We'll come back to the Tag property later.

Get-ScoreProperty

This should be the last piece I need to build a PowerShell function. The function will extract information from the compressed XML file, find the cover image, and use the TagLib library to extract the MP3 properties.

Want to read the full issue?
GitHub Bluesky LinkedIn About Jeff
Powered by Buttondown, the easiest way to start and grow your newsletter.