If you are a software engineer from India, you must have downloaded Bollywood songs from Songspk.info or one of its clone sites at least once. Its a nice service for sure but they definitely have their own quirks. Checking the music file in Windows explorer or Media player will show songspk.info in multiple place including in file names and all the tags. They definitely deserve to do it given the service they provide but I intend to remove that information from downloaded files to keep them short and clean in my media players and hence decided to use Powershell for some automation. Result of that effort is as follows
Before using this, make sure to download taglib-sharp on some folder as it needs to be loaded. Before running any command, make sure to run it with -Whatif parameter to understand what it will do. Code is divided into 3 sections. I intend to add function for modifying tags with multiple values later on. I am greatly indebted to all bloggers on powershell and especially stackoverflow for helping me along the way. They are too many to list out here.
Function Check-TagLibLoad()
{
#validate if taglib-sharp is loaded or not
$taglibload = [System.AppDomain]::CurrentDomain.GetAssemblies() | `
Select-Object -Property FullName | `
Select-String -Pattern "taglib-sharp"
if (!$taglibload){
Throw "Load Taglib using [Reflection.assembly]::LoadFrom(<Full path of downloaded taglib-sharp dll like D:\temp\taglib-sharp-2.1.0.0-windows\Libraries\taglib-sharp.dll>)"
}
}
Function Rearrange-Patterns()
{
# Rearranges array so that if string A is part of B, A comes after B
Param(
[ValidateNotNullOrEmpty()]
[Parameter(Mandatory=$true)]
[String[]]$Patterns
)
[System.Collections.Generic.List[System.String]]$PatternsTemp = $Patterns | Sort-Object -Unique
for ($cnt1 = 1; $cnt1 -lt $PatternsTemp.Count; $cnt1++){
do{
$found = $false
for ($cnt2 = 0; $cnt2 -lt $cnt1; $cnt2++){
if ($PatternsTemp[$cnt1].Length -le $PatternsTemp[$cnt2].Length){
continue
}
if ($PatternsTemp[$cnt1] -match $PatternsTemp[$cnt2]){
$PatternsTemp.Insert($cnt2,$PatternsTemp[$cnt1])
$PatternsTemp.RemoveAt($cnt1+1)
$found = $true
break
}
}
}while($found -eq $true)
}
$PatternsTemp
}
# Rearrange-Patterns -Patterns "Songspk.info","songs","- Songspk.info","so","pk","info","Songspk","[Songs]"
This function uses above two functions. Save all three in one file and then dot source that file and use this function through pipe lining. Make sure to run with -WhatIf first and carefully examine output.
Function Update-Simple-tags()
{
# Update tags with simple non-array values
[CmdletBinding()]
Param(
[ValidateNotNullOrEmpty()]
[Parameter( Position=0, Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[Alias('FullName')]
[String[]]$FilePath,
[ValidateNotNullOrEmpty()]
[Parameter(Mandatory=$true)]
[string[]]$RemovePatterns,
[switch]$WhatIf
)
begin{
Check-TagLibLoad
$RemovePatterns = Rearrange-Patterns -Patterns:$RemovePatterns
}
Process
{
Unblock-File -LiteralPath:$FilePath
$Music = [taglib.file]::create($FilePath)
$TagList = @("Title", "Comment", "Lyrics", "Conductor", "Copyright")
$Update = $False
$Message = @("$FilePath")
foreach ($tag in $taglist)
{
$OldTagVal = $Music.tag.$tag
$RemovePatterns | ?{$Music.tag.$tag -Match $_} |
%{
$Music.tag.$tag = ($Music.tag.$tag -replace $_, "").Trim()
$Update = $true
}
if ($update -eq $true) {
$Message += (" '$Tag': '$OldTagVal' to '"+$Music.tag.$tag+"'")}
else{
$Message += (" '$Tag': No Update")
}
$Update = !($Whatif)
}
if ($Update -eq $true) {
$Music.save()
}
$Message
}
End{
}
}
# dir -filter 2015* -Directory | %{dir -Path $_ -Filter *.mp3 -File} | Update-Simple-tags -RemovePatterns "Songspk.info","- Songspk.info","www.SongsPk.Info" -WhatIf | Out-File Update.log
# dir -filter 2015* -Directory | %{dir -Path $_ -Filter *.mp3 -File} | Update-Simple-tags -RemovePatterns "Songspk.info","- Songspk.info","www.SongsPk.Info" | Out-File Update.log
Below are some commands that can be used to edit downloaded files before running above functions to ensure files are in good naming convention to be modified. Names with ‘[‘ in them are tough to handle otherwise. Unblocking is needed since files are downloaded from internet. Rename-Item cannot work with file with special characters hence Move-Item. Make sure to use -WhatIf beforehand with each command. There is a blog post that talks about unzipping zipped file from Powershell but you can discover that if needed.
#Dir -Filter 2015-*.zip | Unblock-File
#Dir -Filter 2016* -Directory | Move-Item -Destination {$_.FullName -replace "320kbps",""}
#Dir -Filter 2016* -Directory | Move-Item -Destination {$_.FullName -replace "\[Songspk.info\]",""}
#Dir -Filter *-2015.zip | Move-Item -Destination {"2015-"+($_.Name -replace "-2015","")}
#Dir -Filter 2016* -Directory | %{dir -Path $_ -recurse -File} | Move-Item -Destination {$_.FullName -replace "\[Songspk.info\] ",""}
#Dir -Filter *2016* -Directory | | Move-Item -Destination {$_.Name -replace "\[Songspk.info\] ",""}
#[Reflection.Assembly]::LoadFrom("D:\temp\taglib-sharp-2.1.0.0-windows\Libraries\taglib-sharp.dll")
Recent Comments