ShS's Blog

Just another sysadmin's weblog

Скрипт для массового переименования MP3-файлов с использованием информации из mp3 tag’ов.

Posted by shs на 2009/12/20

Совсем недавно потребовалось мне скачать с  одного из сайтов большое количество mp3-файлов. При скачивании с сайта файлы почему-то получали странные имена, наподобие следующего: 432568789645876926097137509375.mp3. Сначала, я качал каждый файл вручную: тыркал в ссылку ПКМ -> Сохранить как… -> и, в появившемся окне диалога сохранения файла, менял странное название файла на внятное и узнаваемое, состоящее из какой-либо комбинации названия автора/исполнителя, номера трека, названия альбома, названия композиции. Занятие это довольно утомительное, и на долго меня не хватило (сдался, когда счет скаченных файлов пошел на 2й десяток). Посему, запустил я свой любимый freedownloadmanager, да и скачал  все файлы в два щелчка «мышки». Счастье почти наступило,  теперь требовалось задать закачанным файлам «правильные» имена. «Погуглив», я обнаружил, что переименование mp3-файлов – весьма популярное занятие, для которого написано вагон и маленькая тележка всевозможных программ, программок и программулек. Скрипты так же попадались, но в основном nix’овые. Задачка же по переименованию файлов представлялась мне просто классической задачей скриптования.  И тогда я  решил присоединиться к движению по «изобретению велосипедов» переименованию mp3-файлов, а, заодно, попрактиковаться в PoSh’е (чтобы мозги не ржавели) и написать свой скрипт для этого богоугодного дела.

 Найти инструментарий для работы с тэгами в mp3-файлах у меня не получилось (возможно, плохо искал): пару раз наткнулся на упоминание какой-то dll, являющейся частью софта от Creative Labs, при помощи которой можно решить поставленную задачу, но, ведь, «это же не наши методы». У кого-то есть устройства от Creative, а у кого-то нет. Зачем искусственно ограничивать область применения будущего «творения»? ;) Хотелось стандартного решения без привлечения 3d party soft’а.   И тут я вспомнил, что «Проводник» (Explorer) в ОС Windows  вполне успешно  способен отображать  всю интересующую меня информацию о mp3-файлах, а, значит, поиск можно направить в сторону COM-объекта Shell.Application. Найдя пару примеров на technet’е и «Сером форуме» , я взялся за дело и, вот, что из этого вышло:

#############################################################################################
#
#    Ren_Mp3_Files.ps1 PowerShell shs 20091217
#
#############################################################################################
#
#.Назначение
#    Массовое переименование MP3-файлов
#
#.Параметры
#    Ren_Mp3_Files.ps1 <Path_2_Folder_containing_MP3_Files>
#
#    Path_2_Folder_containing_MP3_Files - путь к папке, содержащей MP3-файлы
#
#
#.Пример запуска: 
#     .\Ren_Mp3_Files.ps1 "C:\mp3\Пушной"
#
#.Описание
#    Массовое переименование MP3 файлов
#    Новые имена файлов будут сформированы по следующему шаблону:
#         <Название_альбома>--<Номер_трека>--<Название_композиции>
#
#    (информацию о названиях альбома, трека, авторе и т.п. берем из расширенных свойств файла, 
#     доступных при использовании COM-объекта Shell.Application)
#############################################################################################
#
param($Path2mp3Folder = $(throw "В качестве параметра запуска укажите в двойных кавычках путь к паке, содержащей mp3-файлы!"))
#$Path2mp3Folder -путь к папке, в которой лежат файлы mp3, подлежащие переименованию
#
cls
#
#Удаляем оконечный слэш, если таковой был указан,
#чтобы в дальнейшем логика работы программы не зависела о того,
#был ли указан оконечный слэш в пути к целевой папке или нет
$Path2mp3Folder = $Path2mp3Folder -replace "\\$"
#Создаем объек "оболочки" (Shell.Application)
$Shell= New-Object -COM Shell.Application
#Получаем объект с целевой папкой
$Folder=$Shell.NameSpace($Path2mp3Folder)
#В целевой папке ищем все файлы с расширением mp3, 
#результирующую коллекцию помещаем в $FolderItems
$FolderItems = dir "$Path2mp3Folder\*.mp3"
#Удаляем PlayList, если таковой уже существует
del ("$Path2mp3Folder\___"+$Folder.Title+".m3u") -ErrorAction SilentlyContinue
#Создаем пустую хэш-таблицу, в которую мы будем собирать информацию
#о расширенных свойствах файла
$mp3File=@{}
#Обрабатываем каждый файл из полученной коллекции файлов
ForEach ($Item in $FolderItems) {
    #Получаем объект, с расширенными свойствами файла
    $File                    = $Folder.ParseName($Item.Name)
    #Извлекаем расширенные свойства файла и заполняем ими хэш-таблицу
    $mp3File.Name            = $File.Name
    $mp3File.Path            = $File.Path
    #$mp3File.ArtistName    = $Folder.GetDetailsOf($File,9)
    $mp3File.AlbumName        = $Folder.GetDetailsOf($File,17)
    $mp3File.SongTitle        = $Folder.GetDetailsOf($File,10)
    $mp3File.TrackNumber    = $Folder.GetDetailsOf($File,19)
    #$mp3File|ft -AutoSize
    #Если расширенные свойства (которые мы хотим использовать) не пусты, 
    #то сформируем новое имя файла и, затем, переименуем файл
    if ((($mp3File.AlbumName -ne "") -and ($mp3File.TrackNumber -ne "")) -or ($mp3File.SongTitle -ne "")) {
        #Формируем новое имя файла
        $NewFileName=$mp3File.AlbumName + "--" + ("{0:D2}" -f [int]$mp3File.TrackNumber) + "--" + $mp3File.SongTitle  + ".mp3"
        #Удалим из нового имени файла недопустимые для имени файла символы,
        #которые, возможно, содержатся во вновь сформированном имени файла
        $NewFileName = $NewFileName -replace "[\/\\\*\?\<\>\|:`"]"
        #Заменяем пробелы на "знак подчеркивания" ("_")
        $NewFileName = $NewFileName -replace "[\s]","_"
        #Переименовываем файл
        ren $mp3File.Path $NewFileName -PassThru -ErrorAction SilentlyContinue #-WhatIf
    } 
    else {
        $NewFileName= $mp3File.Name
    }
    #В качестве бонуса ;) сформируем playlist
    $NewFileName | Out-File ("$Path2mp3Folder\___"+$Folder.Title+".m3u") -Append -Encoding default
}

Пример работы скрипта:

PS > .\Ren_Mp3_Files.ps1 "C:\mp3\Несчастный случай"


    Каталог: C:\mp3\Несчастный случай


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        03.05.2008     10:32    5151620 Чернослив_И_Курага--04--Со_Страху.mp3
-a---        03.05.2008     10:42    4102053 Чернослив_И_Курага--07--Про_Катю.mp3
-a---        03.05.2009     15:40    5611145 Чернослив_И_Курага--08--Про_Ваню.mp3
-a---        02.05.2008     19:16    3772574 Чернослив_И_Курага--12--Сел_И_Поехал.mp3


PS >

Отмазка: Скрипт снабжен подробными комментариями. Думаю, их вполне достаточно для понимания его работы. Если вам что-то не понятно – спрашивайте ;).

PS Да, раз уж речь зашла о моей любимой команде «Несчастный случай» ;) А знаете ли вы какую песню они исполнят в новогоднюю ночь на «Голубом огоньке»? Не знаете? Ну, так сходите на офсайт «НС» и послушайте. ;)

комментария 2 to “Скрипт для массового переименования MP3-файлов с использованием информации из mp3 tag’ов.”

  1. fzg said

    понятно, что «Хотелось стандартного решения без привлечения 3d party soft’а», но тотал_коммандер, по-моему есть у всех. и групповое переименование обеспечивает всем необходимым. включая и инфу из mp3 и прочую фигню. а промежуточный результат сразу наглядно отображается.

    • shs said

      > но тотал_коммандер, по-моему есть у всех…
      Total Comander совсем не бесплатный продукт: http://www.prodmag.ru/catalog/info/3896
      а утверждение, о том что он есть у всех — ошибочно. Так, например, ни у меня, ни у моих друзей его нет и покупать его я не собираюсь. ;)

Оставьте комментарий