[Powershell] Tagowanie plików muzycznych
#1
Zrobione na szybkości, podzielę się.
Postanowiłem spędzić weekend po geekowsku - ignorując ludzi nie wgapionych w monitor, nie zwracając uwagi na ładną (tfu!) pogodę i wypalające słonce oczy, przed kompem. Cel - uporządkowanie własnej biblioteki plików audio, porobienie tagów, wyszukanie jakichś błędnych wpisów, zaktualizowanie okładek, przekonwertowanie z płyt tego, czego jeszcze niezgrałem itp. Jest do tego cała masa programów, zaczynając od narzędzi wbudowanych w popularne odtwarzacze (Windows Media Player, iTunes, Foobar 2000, Winamp 5.666) i zewnętrznych programów, często freeware (Spesoft free cd ripper czy mp3tags). Te dwa ostatnie interesują mnie najbardziej. Pierwszy, konwertując CD, bardzo brzydko pozapisywał tagi FLAC w jakimś brzydkim kodowaniu, przez co znaki diakrytyczne (nie tylko polskie, także Hungarumlaut czy zwykły, szwabski umlaut) pozamieniały się w potwory... i tak zamiast Händel miałem H+Ąndel. Ten drugi, daje bardzo fajne opcje, jak np. zmiana nazwy pliku czy dowolnego taga według schematu, ale brakuje mu głupiego "znajdź i zamień", żeby każde wystąpienie takiej pomyłki z automatu ubić*.

Pewnie szukając po kolejnych programach okienkowych znalazłbym w końcu jakiś, co spełni moje wymagania, ale juz zbyt dużo śmiecia nadwyrężyło dziś mój dysk. Z tego powodu postanowiłem wyszukać, czy Powershell posiada jakieś możliwości rozwiązania mojego problemu. Wbudowanych rozwiązań brak, ale dzięki obsłudze .Netowych rozszerzeń, można szybko to nadrobić, dociągając Taglib-sharp
https://github.com/mono/taglib-sharp/
I zaczynamy zabawę:
Kod:
# Wczytujemy bibliotekę
[Reflection.Assembly]::LoadFrom("D:\powershell\taglib-sharp.dll")

# wczytujemy plik
$media = [TagLib.File]::Create("D:\Muzyczka\FLAC\Händel\Fireworks, Hallelujah, Concerto Grosso\01-Fireworks - Overture.flac")

#zmiana taga authors
$media.tags.artists = $media.tag.artists[0].replace('+Ą','ä')

#zapisujemy do pliku
$media.save()
Do dobra, ale jak na razie w postaci kilku linijek mam to, co dowolny program załatwia kilkoma kliknięciami. To gdzie tu zysk? Otóż możemy tworząc proste pętle, rurociągi (ech, pipeline brzmi jednak mniej obciachowo...) i wykorzystując obiekty mocno zautomatyzować proces. o, na przykład tak:
Kod:
# Wczytujemy bibliotekę
[Reflection.Assembly]::LoadFrom( ("D:\powershell\taglib-sharp.dll"))

#Listujemy pliki do zmiennej:
$dirresult = dir 'D:\Muzyczka' -recurse -File -force -include "*.mp3", "*.flac"

#i zaczynamy zabawę
$dirresult | %{[TagLib.File]::Create("$($_.fullname)")} | %{$_.tag.artists = $_.tag.artists[0].replace.('+Ą','ä'); $_.save()}

I o ile początek osoba znająca jedynie j.angielski mogłaby ogarnąć, to tu już się należy trochę wyjaśnienia osobom nieznającym Powershella.
Generalnie Powershell, jak i Windows, w większości zastosować nie zwraca uwagi na wielkość znaków, stąd duże litery tu czy tam sięw nazwach metod czy zmiennych pojawią i są bez znaczenia Suspicious
Listując pliki wziąłem dwa rozszerzenia, mp3 i flac, gwiazdka * oznacza dowolny ciąg znaków, czyli kazałem mu zebrać wszystko, czego nazwa kończy się na .flac lub .mp3. Parametr do poprawnego działania wymaga wcześniej użycia parametru -recurse. W przypadku listowania folderów oznacza on przeszukiwanie wszystkich podfolderów. Czym jest rekursja, tudzież rekurencja ogólnie, polecam Wikipedię, od moich tłumaczeń tylko byście zgłupieli. Wink Chociaż osoby kodujące chyba wiedzą co to znaczy.

Dalej, wyniki wistowania przesyłam przez pipeline, znak |, czyli każdy obiekt po kolei będzie brał udział w dalszych przetworzeniach.
% to skrót od foreach-object, czyli wykonujemy polecenia umieszczone w nawiasie klamrowym {} dla każdej przesłanej przez | zmiennej. Domyślnie taka zmienna otrzymuje tymczasową nazwę $_, i do niej się odwołuję. Foreach-object muszę zastosować, pipeline domyślnie pozwala wywoływać wartości obiektu czy metody tylko na początku, przed pierwszym znakiem |.
Czemu po Create tyle $, nawiasów i w ogóle? $ oznacza zmienną. Cudzysłów oznacza string, zmienną tekstową, w odróżnieniu od apostrofu zamienia nazwy zmiennych na ich wartości. Nawias i drugie $ musiałem wykorzystać, bo inaczej rozwinęłoby nazwę zmiennej $_, a fullname pozostawiłoby nietknięte - a tak wywołuje konkretną zmienną, czyli pełną ścieżkę do pliku.
Wewnątrz klamry mogę wykonywać kolejne operacje na przesłanej zmiennej, oddzielając je średnikiem. Dlatego po zamianie znaków od razu save.

Pytanie w zasadzie, po co? Pewnie bym znalazł zaraz program, który pozwala robić to co chcę w okienkach? Tak, ale to by było mniej geekowe ^^ a poza tym, tak mamy podstawę do zmieniania kolejnych wartości, np. po średniku mogę umieścić kolejne znaki, które mi się źle zapisały, mogę tworzyć kolejne, pętle, mogę napisać skrypt, który automatycznie wyszuka duplikaty, np. inny format, ale ten sam wykonawca, płyta i utwory... przykładów wiele można by sobie nawyobrażać.
Pewnie w ramach czasu poświęconego na pisanie posta już bym to ręcznie w jakichś programach uporządkował, ale gdzie w tym wartość edukacyjna? po okienkach każdy klikać umie Suspicious I nie, nie boje się, że przypadkiem trafię na piosenkę, która ma w nazwie +Ą.

Pisane na szybkości, bez dłuższej weryfikacji - nie polecam kopiować i bezmyślnie stosować. Tym bardziej, jak patrze, ile czasu spędziłem na walce z zabłąkana spacją... Nie biorę odpowiedzialności za literówki! Wink

Źródło: http://www.toddklindt.com/blog/Lists/Pos...spx?ID=468

*No dobra, jest "zastąp wyrażeniem regularnym", więc "może" i się da, ale pozdrowienia dla tego, komu się tai regex zechce napisać. Tym bardziej, że rzadko jest to jeden błąd literki na plik.
Człowiek, któremu zazdroszczą najlepszych pomysłów na sygnatury...
Odpowiedz




Użytkownicy przeglądający ten wątek: 1 gości