Skip to content

Instantly share code, notes, and snippets.

@jdhitsolutions
Last active July 19, 2021 19:15
Show Gist options
  • Save jdhitsolutions/ca3be345e677337ea2e4d585bc1bd609 to your computer and use it in GitHub Desktop.
Save jdhitsolutions/ca3be345e677337ea2e4d585bc1bd609 to your computer and use it in GitHub Desktop.
A PowerShell function to use the MuseScore3 command-line tools to export a score file and its parts. You will need to dot-source this ps1 file and then run the function.
#requires -version 5.1
Function Export-MuseScore {
<#
.Synopsis
Export a Musescore3 score
.Description
The command line options for Musescore 3.6 appear to not work properly or as expected
on a Windows platform. This PowerShell function will take a mscz score file and export
it to MXL, PDF and an MP3. Optionally, you can also export parts to individual PDF files.
This will also create .mscx files for each part as well as the score.
C:\Program Files (x86)\MuseScore 3\bin should be in your %PATH% or you can try setting an
alias:
Set-Alias -name musescore3 -Value 'C:\Program Files (x86)\MuseScore 3\bin\MuseScore3.exe'
You should run this command in the folder with the Musescore file. Any existing files
will be overwritten.
.Parameter Score
Specify the .mscz file.
.Parameter Parts
Export parts to PDF and .mscx files.
.Example
PS C:\Scores\StringTrio> Export-Musescore StringTrio.mscz -parts
PS C:\Scores\StringTrio> Get-ChildItem
Directory: C:\Scores\StringTrio
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 7/8/2021 10:20 AM 374993 stringtrio-Viola.mscx
-a---- 7/8/2021 10:20 AM 109402 stringtrio-Viola.pdf
-a---- 7/8/2021 10:20 AM 389236 stringtrio-Violin.mscx
-a---- 7/8/2021 10:20 AM 116168 stringtrio-Violin.pdf
-a---- 7/8/2021 10:20 AM 323591 stringtrio-Violoncello.mscx
-a---- 7/8/2021 10:20 AM 102907 stringtrio-Violoncello.pdf
-a---- 7/8/2021 10:20 AM 4581667 stringtrio.mp3
-a---- 7/8/2021 10:19 AM 2094812 stringtrio.mscx
-a---- 7/3/2021 12:57 PM 71373 stringtrio.mscz
-a---- 7/8/2021 10:19 AM 191923 stringtrio.pdf
-a---- 7/8/2021 10:19 AM 1041938 stringtrio.mxl
Export the score and parts. If you want additional formats for parts, like an MP3 you can
manually run a command like: musescore3 -o viola.mp3 .\stringtrio-Viola.mscx
.Notes
Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/
.Link
https://musescore.org/en/handbook/3/command-line-options
#>
[cmdletbinding(SupportsShouldProcess)]
[OutputType("System.IO.File")]
[alias("ems")]
Param(
[Parameter(Position = 0,Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName, HelpMessage = "The mscz Musescore file to process.")]
[Alias("pspath", "fullname")]
[ValidatePattern('.*\.mscz$')]
[ValidateScript({ Test-Path $_ })]
[string]$Score,
[parameter(HelpMessage = "Export parts to PDF and mscx files")]
[switch]$Parts
)
begin {
Write-Verbose "Starting $($MyInvocation.MyCommand)"
#Write-progress parameters
$prog = @{
Activity = $MyInvocation.MyCommand
Status = "Processing"
CurrentOperation = "Initializing"
PercentComplete = 0
}
} #begin
Process {
$file = Get-Item $score
Write-Verbose "Processing $($file.name)"
$prog.Status = "Processing $($file.name)"
Write-Progress @prog
$dir = Split-Path -Path $file.FullName -Parent
$pdf = Join-Path $dir -ChildPath "$($file.basename).pdf"
$mp3 = Join-Path $dir -ChildPath "$($file.basename).mp3"
$xml = Join-Path $dir -ChildPath "$($file.basename).mxl"
$mscx = Join-Path $dir -ChildPath "$($file.basename).mscx"
$prog.PercentComplete = 25
$prog.CurrentOperation = "Exporting to $($file.basename).pdf"
Write-Progress @prog
if ($pscmdlet.ShouldProcess($pdf, "Export PDF")) {
#Write-Verbose "Saving $pdf" -ForegroundColor yellow
musescore3.exe -o $pdf $file.fullname
Start-Sleep -Seconds 10
}
$prog.PercentComplete = 50
$prog.CurrentOperation = "Exporting to $($file.basename).xml"
Write-Progress @prog
if ($pscmdlet.ShouldProcess($xml, "Export XML")) {
#Write-Verbose "Saving $xml" -ForegroundColor Yellow
MuseScore3.exe -o $xml $file.fullname
Start-Sleep -Seconds 5
}
$prog.PercentComplete = 75
$prog.CurrentOperation = "Exporting to $($file.basename).mp3"
Write-Progress @prog
if ($pscmdlet.ShouldProcess($mp3, "Export MP3")) {
MuseScore3.exe -o $mp3 $file.fullname
Start-Sleep -Seconds 10
}
if ($Parts -AND $Pscmdlet.ShouldProcess($mscx, "Create MSCX file")) {
Write-Verbose "Creating $($file.basename).mscx"
$prog.PercentComplete = 80
$prog.CurrentOperation = "Exporting to $($file.basename).mscx"
Write-Progress @prog
MuseScore3.exe -o $mscx $file.fullname
#give the command time to complete
Start-Sleep -Seconds 20
}
if ($Parts -AND (Test-Path $mscx)) {
$prog.CurrentOperation = "Exporting parts from $($file.basename).mscx"
$prog.PercentComplete = 85
Write-Progress @prog
#define parameters for a child progress bardir
$childProg = @{
ParentID = 0
ID = 1
Activity = "Generating parts"
Status = "Getting content"
CurrentOperation = $mscx
PercentComplete = 0
}
Write-Progress @childProg
[xml]$score = Get-Content -Path $mscx
$scoreparts = $score.museScore.Score.score
Write-Verbose "Found $($scoreparts.count) parts"
$childProg.CurrentOperation = "Found $($scoreparts.count) parts"
$childProg.PercentComplete = 1
Write-Progress @childProg
$i = 0
foreach ($part in $scoreparts) {
Write-Verbose "Processing part for $($part.name)"
$i++
$childProg.PercentComplete = ($i/$scoreparts.count)*100
$partbase = "{0}-{1}" -f $file.basename, $part.name.replace("/","_")
$partname = "$partbase.mscx"
$partFile = Join-Path $dir -ChildPath $partname
$partPDF = Join-Path $dir -ChildPath "$partbase.pdf"
$childProg.status = $part.name
$childProg.CurrentOperation = "Exporting to $partbase.pdf"
Write-Progress @childProg
$r = $score.museScore.SelectSingleNode("//Score")
[void]$score.museScore.ReplaceChild($part, $r)
if ($pscmdlet.shouldProcess($partFile, "Save part")) {
$score.Save($partFile)
if ($pscmdlet.ShouldProcess($partFile, "ExportPDF")) {
MuseScore3.exe -o $partPDF $partFile
start-Sleep -Seconds 5
} #should export part pdf
} #should save part
} #foreach part
}
elseif ( $Parts -AND (-not $WhatIfPreference)) {
Write-Warning "Failed to create $mscx"
}
} #process
end {
$prog.completed
Write-Progress @prog
Write-Verbose "Ending $($MyInvocation.MyCommand)"
} #end
} #close function
#you can include this code in the file above or run it separaately to define an autocompleter for the Score parameter.
Register-ArgumentCompleter -CommandName Export-MuseScore -ParameterName Score -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
#PowerShell code to populate $wordtoComplete
(Get-Childitem *.mscz).Name |
ForEach-Object {
# completion text,listitem text,result type,Tooltip
[System.Management.Automation.CompletionResult]::new("'$_'", "'$_'", 'ParameterValue', "'$_'")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment