AppleScript zwraca warunek w zależności od długości pliku audio

5

Chciałbym użyć Hazel (automatyzatora systemu plików opartego na regułach) dla systemu macOS, aby automatycznie przenosić pliki audio mixtape z jednego folderu do drugiego, jeśli ich czas trwania jest dłuższy niż 30 minut.

Hazel nie zapewnia wbudowanej metody sprawdzania długości pliku audio (o której wiem), ale zapewnia możliwość uruchamiania reguł, jeśli warunek AppleScript zostanie spełniony, tj return true.

Sądząc z poniższego zrzutu ekranu, myślę, że to działa, jeśli length of theFile > 30*60 seconds: return true (pseudo kod) .

wprowadź opis zdjęcia tutaj

Nie jestem jednak pewien, jak to osiągnąć za pomocą AppleScript. Wszelkie pomysły, jak to zrobić lub od czego zacząć? Wyszukiwanie online nie dostarczyło wielu podstawowych pomysłów, ale wydaje się możliwe.


Uwaga : Udzielanie porad na temat AppleScripts jest poza zakresem AFAIK obsługi Hazel, więc nie mogę uzyskać od nich żadnej pomocy.

Winterflags
źródło
2
Nie mam Hazel, więc nie mogę przetestować go i dlaczego komentarz vs. odpowiedź, jednak tutaj jest AppleScript do shell script komenda , która będzie ustawiona theResultna truelub falseczy można dowiedzieć się, jak ją przekazać theFileName: set theResult to (do shell script "[[ $(afinfo -r '" & theFileName & "' | awk '/estimated duration:/{print int($3/60)}') -gt 30 ]] && echo 'true' || echo 'false'") as boolean. Możesz następnie dodać ten wiersz po nim, return theResulta będzie on równoważny return truelub return falseodpowiednio.
user3439894
1
@ user3439894 Rozumiem, dlaczego nie opublikowałeś tego jako odpowiedzi, ale nadal uważam, że powinieneś, ponieważ dzięki temu OP nie usuwa pytania (z jakiegokolwiek powodu). W tym przypadku Twoja odpowiedź prawdopodobnie doprowadzi do rozwiązania, które pomoże innym. :)
Monomeeth
@Monomeeth, poszedłem naprzód i pobrałem Hazel, a po niewielkiej modyfikacji zweryfikowałem kod w moim komentarzu. Nawiasem mówiąc, nie wierzę, że dodanie odpowiedzi może powstrzymać autora PO przed usunięciem jego pytania.
user3439894
1
@Winterflags, mam zaktualizować odpowiedź dodawania informacji o tym, jak to zrobić szybciej, przeczytać rozdział na końcu odpowie po: „Jeśli chcesz, aby zawartość z do shell script poleceniem , aby działać szybciej, a następnie kliknąć na poniższy:”
user3439894

Odpowiedzi:

6

OK, pobrałem Hazel i przetestowałem następujący kod AppleScript na nowej regule, aby sprawdzić, czy działa. Poniższy kod stosowany w osadzonym skryptem ustawi theResultsię truena theFile, plik audio, który jest dłuższy niż 30 minut. Dowolny plik o długości 30 minut lub mniej lub plik inny niż dźwięk zostanie ustawiony theResultna false:

set theResult to (do shell script "[[ $(afinfo -r '" & POSIX path of theFile & "' | awk '/estimated duration:/{print int($3/60)}') -gt 30 ]] && echo 'true' || echo 'false'") as boolean
return theResult
  • Zauważ, że od mojego pierwszego komentarza przed opublikowaniem tej odpowiedzi zmieniłem theFileNamena POSIX path of theFilei, jak widać na poniższym obrazku, potwierdziła ona regułę. Następnie pomyślnie przetworzył regułę, tak jak ją zdefiniowałem.
  • Aby zmienić liczbę minut, zmień wartość po prawej stronie operatora , np.
    -gt 30Na żądany czas, np -gt 20. Operatora można również zmienić któregokolwiek z następujących powodów: -eq, -ne, -lt, -le, -gtlub-ge

Okienka preferencji

Zrozumienie trochę treści do shell script polecenia :

  • afinfonie ma wiele na temat strony podręcznika , więc po prostu wpisz afinfoTerminal i naciśnij Enter, aby wyświetlić opcje .
  • afinfo -r - {-r --real} get the estimated duration after obtaining the real packet count
  • Przykładowe dane wyjściowe afinfo -r:

     $ afinfo -r '09 Karn Evil 9.mp3'
     File:           09 Karn Evil 9.mp3
     File type ID:   MPG3
     Num Tracks:     1
    ----
     Data format:     2 ch,  44100 Hz, '.mp3' (0x00000000) 0 bits/channel, 0 bytes/packet, 1152 frames/packet, 0 bytes/frame
                        no channel layout.
     audio bytes: 85117515
     audio packets: 81460
     estimated duration: 2127.935 sec
     bit rate: 320000 bits per second
     packet size upper bound: 1052
     maximum packet size: 1045
     audio data file offset: 275530
     optimized
    ----
     $
    
    • Powyższe dane wyjściowe są przesyłane potokowo ( |) do awk.
  • awk '/estimated duration:/{print int($3/60)}'
    • awkwyszukuje rekord (linii), zawierający estimated duration:w wyjściu z afinfoodprowadzone do niej i drukuje trzeciego pola , $3, 2127.935jako liczba całkowita, został podzielony przez 60uzyskać liczbę minut, a wartości czasu w sekundach. Na przykład wyjścia , awkzwrócone:35
  • $(...)Część substytucji poleceń przeszła 35do testu [[ $(...) -gt 30 ]], więc zrównała się [[ 35 -gt 30 ]]iw rezultacie, używając operatorów logicznych, powtórzyła echo true. Gdyby wartość była równa lub mniejsza niż 30, lub plik nie-dźwiękowy, odbijałby się echem false.

Jeśli chcesz, aby zawartość z do shell script poleceniem , aby działać szybciej, a następnie użyć następujących:

set theResult to (do shell script "[[ $(afinfo -b '" & POSIX path of theFile & "' | awk 'FNR == 3 {print int($1/60)}') -gt 30 ]] && echo 'true' || echo 'false'") as boolean
return theResult
  • afinfo -b - {-b --brief} print a brief (one line) description of the audio file
    • Działa to szybciej niż przy użyciu, -rponieważ nie zlicza pakietów, ale pobiera informacje z osadzonych danych. Zauważ, że chociaż pomoc mówi „(jedna linia)”, dane wyjściowe są w rzeczywistości trzema liniami, ale nadal są szybsze niż długa forma, szczególnie jeśli nie są używane -r.
  • Przykład wyjście z afinfo -b:

    $ afinfo -b '09 Karn Evil 9.mp3'
    09 Karn Evil 9.mp3, MPG3, Num Tracks:     1
    ----
    2127.938 sec, format:   2 ch,  44100 Hz, '.mp3' (0x00000000) 0 bits/channel, 0 bytes/packet, 1152 frames/packet, 0 bytes/frame
    $
    
    • Powyższe dane wyjściowe są przesyłane potokowo ( |) do awk.
  • awk 'FNR == 3 {print int($1/60)}'
    • awkwypisuje pierwsze pole ( $1) trzeciego rekordu (linii) danych wyjściowych przesyłanych potokowo afinfo -b, 2127.935jako liczbę całkowitą, podzielone przez, 60aby uzyskać liczbę minut, ponieważ wartość czasu jest w sekundach. W przykładowym wyniku awkzwrócono:35
użytkownik3439894
źródło
4
+1 Dobra robota! Jestem pewien, że inni uznają to za przydatne. :)
Monomeeth
1
@Monomeeth, aby sprostać łaskawemu komentarzowi, zaktualizowałem odpowiedź, aby zawierała trochę zrozumienia tego, co robi do shell script polecenie . BTW +1 dla Ciebie w wyborach moderatora społeczności! :)
user3439894,
2
Dzięki za rozwiązanie, a zwłaszcza za dodanie kontekstu i wyjaśnień, które moim zdaniem będą najbardziej korzystne dla szerszej publiczności!
Winterflags