我如何使用 Groovy 分析我的音樂目錄
為了簡化 Java 的繁瑣,我製作了一個 Groovy 工具來分析我的音樂目錄。
最近,我一直在研究 Groovy 是如何簡化略微繁瑣的 Java 的。在這篇文章中,我開始了一個簡短的系列,通過創建一個分析我的音樂目錄的工具來演示 Groovy 腳本。
在本文中,我將演示 groovy.File
類如何擴展和精簡 java.File
並簡化其使用。這為查看音樂文件夾的內容提供了一個框架,以確保預期的內容(例如,cover.jpg
文件)就位。我使用 JAudiotagger 庫 來分析音樂文件的標籤。
安裝 Java 和 Groovy
Groovy 基於 Java,需要安裝 Java。 Java 和 Groovy 的最新和穩定的版本可能都在你的 Linux 發行版的倉庫中。 Groovy 也可以直接從 Apache Foundation 網站 安裝。對於 Linux 用戶來說,一個不錯的選擇是 SDKMan,它可用於獲取 Java、Groovy 和許多其他相關工具的多個版本。對於本文,我使用以下 SDK 版本:
- Java:版本 11.0.12-open 的 OpenJDK 11
- Groovy:版本 3.0.8
音樂元數據
最近,我重整了我的音樂消費方式。我決定使用優秀的開源 Cantata 音樂播放器,它是開源 MPD 音樂播放器 的一個前端。我所有的電腦的音樂都存儲在 /var/lib/mpd/music
目錄下。在該音樂目錄下有藝術家子目錄,在每個藝術家子目錄下有專輯子目錄,包含音樂文件、cover.jpg
,偶爾還有 PDF 格式的內頁說明。
我絕大部分的音樂文件都是 FLAC 格式的,有一些是 MP3 格式,可能還有一小部分是 OGG 格式。我選擇 JAudiotagger 庫的一個原因是它可以透明地處理不同的標籤格式。當然,JAudiotagger 是開源的!
那麼查看音頻標籤有什麼意義呢?以我的經驗,音頻標籤的管理極差。(提到音頻標籤,)我的腦海中浮現出「粗心」這個詞。這是標籤本身真正存在的問題,也可能是出於我自己的學究傾向。無論如何,這是一個可以通過使用 Groovy 和 JAudiotagger 解決的重要問題。不過,它不僅適用於音樂收藏。許多其他現實世界的問題也適用,如需要下沉到文件系統中的目錄樹來處理在那裡找到的內容。
使用 Groovy 腳本
這是此任務所需的基本代碼。我在腳本中加入了注釋,這些注釋反映了我通常留給自己的(相對簡寫的)「注釋提醒」:
// 定義音樂庫目錄
def musicLibraryDirName = '/var/lib/mpd/music'
// 輸出 CSV 文件標題行
println "artistDir|albumDir|contentFile"
// 迭代音樂庫目錄中的每個目錄
// 這一層應該是藝術家目錄
new File(musicLibraryDirName).eachDir { artistDir ->
// 迭代藝術家目錄中的每個目錄
// 這一層應該是專輯目錄
artistDir.eachDir { albumDir ->
// 迭代專輯目錄中的每個目錄
// 這裡應該是內容
// 或相關內容(如 `cover.jpg`,PDF 格式的內頁說明)
albumDir.eachFile { contentFile ->
println "$artistDir.name|$albumDir.name|$contentFile.name"
}
}
}
如上所述,我使用 groovy.File
在目錄樹中移動。具體來說:
第 7 行創建一個新的 groovy.File
對象並在其上調用 groovy.File.eachDir()
,第 7 行的 {
和第 18 行的結尾的 }
之間的代碼是傳給 eachDir()
的 groovy.Colsue
參數。
這意味著 eachDir()
為目錄中找到的每個子目錄執行該代碼。這類似於 Java lambda(也稱為「匿名函數」)。 Groovy 閉包不會像 lambda 那樣限制對調用環境的訪問(在最新版本的 Groovy 中,如果你願意,也可以使用 Java lambda)。如上所述,音樂庫目錄中的子目錄應該是藝術家目錄(例如,「Iron Butterfly」 或 「Giacomo Puccini」),因此 artistDir
是 eachDir()
傳遞給閉包的參數。
第 10 行對每個 artistDir
調用 eachDir()
,第 10 行的 {
和第 17 行的 }
之間的代碼形成另一個處理 albumDir
的閉包。
第 14 行,在每個 albumDir
上調用 eachFile()
,第 14 行的 {
和第 16 行的 }
之間的代碼形成了處理專輯內容的第三級閉包。
在本文的範圍內,我對每個文件唯一需要做的就是開始構建信息表,我將其創建為一個以豎線分隔的 CSV 文件,它可以導入 LibreOffice 或 OfficeOnly 或任何其他電子表格。現在,代碼輸出前三列:藝術家目錄名、專輯目錄名和內容文件名(同樣,第 2 行輸出 CSV 標題行)。
在我的 Linux 筆記本電腦上運行它會產生以下輸出:
$ groovy TagAnalyzer.groovy | head
artistDir|albumDir|contentFile
Habib Koite & Bamada|Afriki|02 - Ntesse.flac
Habib Koite & Bamada|Afriki|08 - NTeri.flac
Habib Koite & Bamada|Afriki|01 - Namania.flac
Habib Koite & Bamada|Afriki|07 - Barra.flac
Habib Koite & Bamada|Afriki|playlist.m3u
Habib Koite & Bamada|Afriki|04 - Fimani.flac
Habib Koite & Bamada|Afriki|10 - Massake.flac
Habib Koite & Bamada|Afriki|11 - Titati.flac
Habib Koite & Bamada|Afriki|03 – Africa.flac
[...]
Richard Crandell|Spring Steel|04-Japanese Lullaby [Richard Crandell].flac
Richard Crandell|Spring Steel|Spring Steel.pdf
Richard Crandell|Spring Steel|03-Zen Dagger [Richard Crandell].flac
Richard Crandell|Spring Steel|cover.jpg
$
在性能方面:
$ time groovy TagAnalyzer.groovy | wc -l
9870
real 0m1.482s
user 0m4.392s
sys 0m0.230s
$
又好又快。它在一秒半內處理近 10,000 個文件!對我來說足夠快。可觀的性能、緊湊且可讀的代碼,還有什麼不喜歡的?
在我的下一篇文章中,我會打開 JAudiotagger 並查看每個文件中的標籤。
via: https://opensource.com/article/22/8/groovy-script-java-music
作者:Chris Hermansen 選題:lkxed 譯者:geekpi 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive