functions/Export-TrackArtwork.ps1
|
function Export-TrackArtwork { <# .SYNOPSIS Exports embedded artwork (pictures) from an audio track to the filesystem. .DESCRIPTION Extracts pictures from a media file and saves them to disk. The filename is constructed from an optional prefix, the picture type, and the appropriate file extension based on the MIME type. If no output directory is specified, images are saved to the same directory as the source file. .PARAMETER FilePath The path to the media file containing the artwork. .PARAMETER TagLibFile A TagLib.File object to extract artwork from. Can be passed via pipeline. .PARAMETER Picture A TagLib.IPicture object to export. Can be passed via pipeline. .PARAMETER SourceFilePath (Optional) The path to the source media file. Used to determine the output directory when a Picture is piped in. .PARAMETER OutputDirectory (Optional) The directory to save the exported image(s). Defaults to the same directory as the media file. .PARAMETER Prefix (Optional) A string to prepend to the filename (e.g., "AlbumName_"). .PARAMETER PictureType (Optional) One or more TagLib.PictureType values (e.g., 'FrontCover', 'BackCover') to filter which pictures to export. Defaults to 'FrontCover'. .PARAMETER All (Optional) If specified, exports all pictures regardless of type. Overrides -PictureType. .EXAMPLE Export-TrackArtwork -FilePath "C:\Music\song.mp3" .EXAMPLE Export-TrackArtwork -FilePath "C:\Music\song.mp3" -Prefix "MyAlbum_" -OutputDirectory "C:\Covers" .EXAMPLE Export-TrackArtwork -FilePath "C:\Music\song.mp3" -PictureType FrontCover,BackCover .EXAMPLE Export-TrackArtwork -FilePath "C:\Music\song.mp3" -All .EXAMPLE $tf = [TagLib.File]::Create("C:\Music\song.mp3") $tf | Export-TrackArtwork -Prefix "Export_" .EXAMPLE Get-TrackArtwork -FilePath "C:\Music\song.mp3" -All | Export-TrackArtwork -OutputDirectory "C:\Covers" -Prefix "Cover_" .EXAMPLE Get-TrackArtwork -FilePath "C:\Music\song.mp3" -All | Export-TrackArtwork -SourceFilePath "C:\Music\song.mp3" -Prefix "Cover_" .OUTPUTS System.IO.FileInfo[] - Information about the exported file(s). .NOTES Requires TagLib# to be loaded. #> [CmdletBinding(DefaultParameterSetName = 'ByFilePath')] param( [Parameter(Mandatory, ParameterSetName = 'ByFilePath', Position = 0)] [string]$FilePath, [Parameter(Mandatory, ParameterSetName = 'ByTagLibFile', ValueFromPipeline)] [TagLib.File]$TagLibFile, [Parameter(Mandatory, ParameterSetName = 'ByPicture', ValueFromPipeline)] [TagLib.IPicture]$Picture, [Parameter(ParameterSetName = 'ByPicture')] [string]$SourceFilePath, [string]$OutputDirectory, [string]$Prefix, [ValidateSet( 'Other','FileIcon','OtherFileIcon','FrontCover','BackCover','LeafletPage','Media','LeadArtist', 'Artist','Conductor','Band','Composer','Lyricist','RecordingLocation','DuringRecording', 'DuringPerformance','MovieScreenCapture','ColouredFish','Illustration','BandLogo','PublisherLogo' )] [TagLib.PictureType[]]$PictureType = @([TagLib.PictureType]::FrontCover), [switch]$All ) begin { # Map MIME types to file extensions $mimeToExtension = @{ 'image/jpeg' = '.jpg' 'image/png' = '.png' 'image/gif' = '.gif' 'image/bmp' = '.bmp' 'image/tiff' = '.tiff' 'image/webp' = '.webp' } } process { $tf = $null $disposeFile = $false $pictures = @() $sourceDirectory = $null Write-Verbose "[PROCESS] Export-TrackArtwork called with ParameterSet: $($PSCmdlet.ParameterSetName)" try { # Get pictures based on parameter set switch ($PSCmdlet.ParameterSetName) { 'ByFilePath' { $tf = [TagLib.File]::Create($FilePath) $disposeFile = $true $sourceDirectory = Split-Path -Path $FilePath -Parent $pictures = $tf.Tag.Pictures } 'ByTagLibFile' { $tf = $TagLibFile Write-Verbose "Using TagLib.File from pipeline $($tf | Get-Member )" $sourceDirectory = Split-Path -Path $tf.Name -Parent $pictures = $tf.Tag.Pictures } 'ByPicture' { $pictures = @($Picture) if ($SourceFilePath) { $sourceDirectory = Split-Path -Path $SourceFilePath -Parent } } } if (-not $pictures -or $pictures.Count -eq 0) { Write-Verbose "No artwork found" return } # Filter pictures by type unless -All is specified if (-not $All -and $PSCmdlet.ParameterSetName -ne 'ByPicture') { $pictures = $pictures | Where-Object { $PictureType -contains $_.Type } } if (-not $pictures -or $pictures.Count -eq 0) { Write-Verbose "No pictures matching the specified type(s) found" return } # Determine output directory if (-not $OutputDirectory) { if ($sourceDirectory) { $OutputDirectory = $sourceDirectory } else { $OutputDirectory = Get-Location Write-Verbose "No source file path available, using current directory: $OutputDirectory" } } # Ensure output directory exists if (-not (Test-Path -Path $OutputDirectory)) { New-Item -ItemType Directory -Path $OutputDirectory -Force | Out-Null } # Export each picture foreach ($pic in $pictures) { # Get file extension from MIME type $extension = $mimeToExtension[$pic.MimeType] if (-not $extension) { # Default to .jpg if MIME type is unknown $extension = '.jpg' Write-Verbose "Unknown MIME type '$($pic.MimeType)', defaulting to .jpg" } # Construct filename $typeName = $pic.Type.ToString() if ($Prefix) { $filename = "$Prefix$typeName$extension" } else { $filename = "$typeName$extension" } $outputPath = Join-Path -Path $OutputDirectory -ChildPath $filename Write-Verbose "Exporting $typeName to $outputPath" # Write picture data to file [System.IO.File]::WriteAllBytes($outputPath, $pic.Data.Data) # Output file info Get-Item -Path $outputPath } } finally { if ($disposeFile -and $tf) { $tf.Dispose() } } } } |