Friday, April 2, 2010

Powershell: Play with Media files

Code Snippet
  1. function MediaObjects($FolderName=".")
  2. {
  3.     #http://huddledmasses.org/editing-media-tags-from-powershell/
  4.     #http://developer.novell.com/wiki/index.php/TagLib_Sharp
  5.     if (![AppDomain]::CurrentDomain.GetAssemblies() | ?{$_.fullname -like "taglib-sharp*"}){
  6.         Write-Host $("taglib-sharp is not loaded. use below command to load it");
  7.         Write-Host $("[Reflection.Assembly]::LoadFrom( (Resolve-Path <Path of \taglib-sharp.dll>) )");
  8.         return (@())
  9.     }
  10.     if (![System.IO.Directory]::Exists($FolderName)){
  11.         Write-Host $($FolderName + " : Media directory does not exist.");
  12.         return (@())
  13.     }
  14.     $mediaExtensionList = @(".asf",".avi",".flac",".m4a",".m4p",".m4v", `
  15.               ".mp+",".mp3",".mp4",".mpc",".mpe",".mpeg",".mpg", `
  16.               ".mpp",".mpv2",".ogg",".wav",".wma",".wmv",".wv")
  17.             
  18.     $FileList = dir -Recurse -Include "*.*" -Path $FolderName |  `
  19.             ?{($_ -is [IO.FileSystemInfo]) -and ($mediaExtensionList -contains $_.Extension)}
  20.     if (!$FileList){
  21.         return (@())
  22.     }else{
  23.         $ObjList=@()
  24.         foreach ($Item in $FileList)
  25.         {
  26.             #http://huddledmasses.org/trap-exception-in-powershell/
  27.             #Excellent article
  28.             trap [Exception]{
  29.                 Write-Host $($Item.FullName + " threw exception.");
  30.                 write-host $("`tTRAPPED: " + $_.Exception.GetType().FullName);
  31.                  write-host $("`tTRAPPED: " + $_.Exception.Message);
  32.                 continue
  33.             }
  34.             $ObjList += [TagLib.File]::Create($Item.FullName)
  35.         }
  36.         return ($ObjList)
  37.     }
  38. }
  39.  
  40. function modifyMediaFiles($FolderName=".", $TagName="Genres", $NewTagValue="Hindi Movie")
  41. {
  42.     Write-Host $("Only display the name of those which are getting modified");
  43.     foreach ($media in @(MediaObjects($FolderName)))
  44.     {
  45.         if (($media.tag.$TagName -contains $NewTagValue) `
  46.          -and ($media.tag.$TagName.length -eq 1 ) )
  47.         {
  48.             continue;
  49.         }
  50.         $media.tag.$TagName=@($NewTagValue)
  51.         $media.save()
  52.         $media.name
  53.     }
  54. }
  55.  
  56. function showMediaTags($FolderName=".", $TagName="Genres")
  57. {
  58.     foreach ($media in @(MediaObjects($FolderName)))
  59.     {
  60.         Write-Host $(([String]::Join(";=;",$media.tag.$TagName)+" : "+$media.Name));
  61.     }
  62. }
  63.  
  64. #showMediaTags
  65. #modifyMediaFiles "G:\Music\HindiMovies\2005"
  66. #modifyMediaFiles "G:\Music\HindiMovies\2006"
  67. #showMediaTags "G:\Music\HindiMovies\2006"
  68. #showMediaTags "G:\Music\HindiMovies\2009\Aagey Se Right"
Some attribution first

Original Explanation: http://huddledmasses.org/editing-media-tags-from-powershell/

Media Toolset: http://developer.novell.com/wiki/index.php/TagLib_Sharp Nice one to work with media files

How to handle exception: http://huddledmasses.org/trap-exception-in-powershell/

Good discussion on how to return arrays: http://blogs.msdn.com/powershell/archive/2007/01/23/array-literals-in-powershell.aspx

Power GUI: http://powergui.org/index.jspa . A nice tool.

It took some iterations, but final thing came pretty easy. MediaObjects as shown below can be saved in our profile script. At the same time, we can add loading of taglib-sharp also in profile folder. Anyway, function will warn you if not loaded. showMediaTags & modifyMediaFiles are two examples, but we can use many more such small function once we get System.Array of TagLib.Mpeg.AudioFile from MediaObjects.

Notice how I am returning empty array and how exception is handled. Above links have more explanation on each of these.

Using the functions, I could make modification in lot of files.

Code highlighter plugin in windows live writer

No comments: