Control Scripting
I've spent a few issues reviewing how I built a PowerShell tool to insert text into a graphic image. The function I wrote and demonstrated last time, will work with any graphic file, even though I created the function with a specific use case in mind. I want to take an image file associated with one of my musical compositions, insert the name, and use the image in the MP3 file. I also want to make this an easy to invoke repeatable process. When I update a score, I'll end up with a new MP3 file which will need to be updated again.
I have taken the functions I wrote for manage my score files into a module. The module is not in a PSModulePath
location, so I import it specifying the path.
Import-Module c:\scripts\MuseScoreTools -force
I have created a test folder to use during development so that I don't pollute my original score files.
The MP3 file has already been updated with tags.
PS C:\temp\violin-nocturne> Get-MuseScoreMp3 '.\Nocturne for Violin.mp3' | Tee -Variable a
Title : Nocturne for Violin
Subtitle : in G Minor
Length : 00:05:40
Composer : {Jeffery Hicks}
Album :
Track : 0
Year : 2023
Genre : {Classical}
Description : https://musescore.com/user/26698536/scores/7210278
Comment : This is a computer generated performance. Created with MuseScore 3.6.2
Copyright : c. 2021-2023 Jeffery D. Hicks
Size : 5488208
Path : C:\temp\violin-nocturne\Nocturne for Violin.mp3
The original cover image is stored in the MP3.

What I need is a PowerShell solution that merges my stand-alone Add-TextToImage
function with tools in the MuseScoreTools
module. I could add the function to the module and update the module commands. But if I wanted to use the function for something else, I'd have to remember it is in the MuseScoreTools
module. What I don't want is to have the same function in two locations because that means twice as much maintenance.
Instead, I think I will create a stand-alone script file. I can load the function and import the module in the script file. Given that every image will be different, each cover image will have a different font style and color. My initial design consideration is that I will manually invoke the script on a single folder.
This gives me a starting point for the control script.
#requires -version 7.5
#requires -module pwshSpectreConsole
#C:\Scripts\UpdateScoreMPCover.ps1
Param(
[Parameter(HelpMessage = 'The path to the MuseScore files')]
[string]$Path = "."
)
. C:\scripts\Add-ImageText.ps1
Import-Module C:\scripts\MuseScoreTools -Force
Organize
When approaching a control script, I think you'll find it helpful if you can verbalize each step in the process. Unlike a function which is designed to do one task, a control script is an orchestration of tasks. Take the time up front to organize your thoughts. Even better, write them in your script file as comments.
#convert the path to a full file system path
#Get the MP3 file in the location. There should only be one.
#Validate that the MP3 file tags have been updated.
#Update the MP3 file if missing information.
#Test for cover image settings
#import cover image settings if found
#otherwise use parameter values
#Create a preview image file of the cover image with imported or parameter settings
#update the MP3 file with preview cover image
#show the new image
#export the cover image settings
Since I want to be able to quickly refresh a cover image with text, I intend to save settings like font and color in a JSON file. My comments layout a workflow. Looking at the comments and visualizing the process also ensure I have steps in the proper order. All I need to do now is write code to implement the steps. When I'm finished, they will already be documented!
Getting paths is simple enough.
#convert the path to a full file system path
$Path = Convert-Path $Path
#Get the MP3 file in the location. There should only be one.
$mp3Path = (Get-ChildItem -Path $Path -Filter *.mp3).FullName
As is validating that the MP3 file has been updated.
#Validate that the MP3 file tags have been updated.
$mp3Tags = Get-MuseScoreMp3 -Path $mp3Path
if (-Not $mp3Tags.Title) {
#Update the MP3 file if missing information.
Write-Host "Updating MP3 tags" -ForegroundColor Yellow
Update-MuseScoreMp3 -Path $mp3path
Write-Host "MP3 tags updated" -ForegroundColor Green
$mp3Tags = Get-MuseScoreMp3 -Path $mp3Path
}
After writing the code, I realized I need to move one of the workflow comments up. I should also explain that I am manually executing each block of code interactively in my test folder. If the code works, I copy and paste it into the control script. If I mess things up, I can re-copy the source files into the test folder.