有馬総一郎のブログ

(彼氏の事情)

2024年04月30日 19:42:20 JST - 6 minute read - Linux

もはや音楽プレイヤーといって良いタグエディタbeetsを使ってみる 補足

前回beetsについて紹介したが、実際使ってみると細かい部分でプラグインのインストールが必要だったりカスタマイズが必要だったので、まとめておく。

フィールド追加

itemfieldsは、あくまでbeetsというタグエディターのデータベース、ライブラリーでのフィールドなので、ファイルのタグ情報と微妙に異なる。

beetsフィールドによる編集・動作が不満な場合は、 Inline Pluginをインストールして、自分でカスタマイズフィールドを用意したり、 mediafile.py1 ソースを編集するしかない。

例えば、アルバムの最大トラック番号であるトラック数のタグtracktotalとしては、9以下であれば、10の位はゼロ埋めされない。フィールドtotaltracksとしては10の位はゼロ埋めする仕様となっている。ファイル名のトラック番号としてはトラック数が9以下の場合、ゼロ埋めしないで欲しい2のだが、フィールド値として作用するためにゼロ埋めされる。

なので、以下のように Inline Pluginをインストールして、filetrackというフィールドを追加して、それをファイル名と利用している。

paths:
  default: $albumartist/$album%aunique{}/${filetrack}_${title}
item_fields:
  filetrack: u'%02i' % (track) if tracktotal > 9 else u'%01i' % (track)

タグ削除

余計なタグは削除しておきたい。 Scrub Plugin — beets 1.6.0 documentationをインストールしてる。そして、 Zero Pluginもインストールして、不要なフィールドは削除するようにしている。

ディスク番号discnumber、ディスク枚数totaldiscsは、複数枚あるアルバムしか設定したくない。しかし、数値型のフィールドとして0で編集しても、タグとして0で書き込まれてしまうので、0の時は、削除されるようにしている。

scrub:
  auto: yes

zero:
  fields: comments original_year comp bpm year month day disc disctotal encoder
  year: [^0$]
  disc: [^0$]
  disctotal: [^0$]
  update_database: true

余計なタグ

そして、特定のフィールドを設定すると、タグとして書き込まれるときに、他のタグにも同値が書き込まれる。oggなどの色んなメディアファイルへの対応によるものらしい。

beetsフィールド タグ 余計なタグ
track tracknumber track、trackc
albumartist albumartist album artist、album_artist
disc discnumber disc
disctotal totaldiscs disctotal、discc
year date year
beets

上記の件について、イシューが挙げれている。ともあれ、気持ちが悪い。zeroプラグインの設定でタグ名をそのまま記述しても、beetsのフィールドとしては存在しないので、無効となる。

$ beet zero myrath karma
zero: invalid field: album_artist
zero: invalid field: BPM
zero: invalid field: description
zero: invalid field: discc
zero: invalid field: trackc
zero: invalid field: compilation
zero: invalid field: 'album
zero: invalid field: artist'
zero: invalid field: 'year'
zero: invalid field: 'track'

ソース改修

ひょっとしたら、独自フィールドを追加したら、タグdiscnumbertotaldiscsalbumartistだけ書き込めるのか分からないけど、面倒なので、ファイル書き込み部分のソースを直接、弄ることにする。#でコメントアウトした。

~/.local/lib/python3.10/site-packages/mediafile.py

     track = MediaField(
         MP3SlashPackStorageStyle('TRCK', pack_pos=0),
         MP4TupleStorageStyle('trkn', index=0),
-        StorageStyle('TRACK'),
+        #StorageStyle('TRACK'),
         StorageStyle('TRACKNUMBER'),
         ASFStorageStyle('WM/TrackNumber'),
         out_type=int,
・・・省略・・・
     tracktotal = MediaField(
         MP3SlashPackStorageStyle('TRCK', pack_pos=1),
         MP4TupleStorageStyle('trkn', index=1),
-        StorageStyle('TRACKTOTAL'),
-        StorageStyle('TRACKC'),
+        #StorageStyle('TRACKTOTAL'),
+        #StorageStyle('TRACKC'),
         StorageStyle('TOTALTRACKS'),
         ASFStorageStyle('TotalTracks'),
         out_type=int,
・・・省略・・・
     disc = MediaField(
         MP3SlashPackStorageStyle('TPOS', pack_pos=0),
         MP4TupleStorageStyle('disk', index=0),
-        StorageStyle('DISC'),
+        #StorageStyle('DISC'),
         StorageStyle('DISCNUMBER'),
         ASFStorageStyle('WM/PartOfSet'),
         out_type=int,
・・・省略・・・
     disctotal = MediaField(
         MP3SlashPackStorageStyle('TPOS', pack_pos=1),
         MP4TupleStorageStyle('disk', index=1),
-        StorageStyle('DISCTOTAL'),
-        StorageStyle('DISCC'),
+        #StorageStyle('DISCTOTAL'),
+        #StorageStyle('DISCC'),
         StorageStyle('TOTALDISCS'),
         ASFStorageStyle('TotalDiscs'),
         out_type=int,
・・・省略・・・
     albumartist = MediaField(
         MP3StorageStyle('TPE2'),
         MP4StorageStyle('aART'),
-        StorageStyle('ALBUM ARTIST'),
-        StorageStyle('ALBUM_ARTIST'),
+        #StorageStyle('ALBUM ARTIST'),
+        #StorageStyle('ALBUM_ARTIST'),
         StorageStyle('ALBUMARTIST'),
         ASFStorageStyle('WM/AlbumArtist'),
     )
・・・省略・・・
         MP3StorageStyle('TENC'),
         MP4StorageStyle('\xa9too'),
         StorageStyle('ENCODEDBY'),
-        StorageStyle('ENCODER'),
+        #StorageStyle('ENCODER'),
         ASFStorageStyle('WM/EncodedBy'),
     )
     script = MediaField(
・・・省略・・・
         MP4StorageStyle('\xa9day'),
         StorageStyle('DATE'),
         ASFStorageStyle('WM/Year'),
-        year=(StorageStyle('YEAR'),))
+        #year=(StorageStyle('YEAR'),))
+        )

とした。これで余計なタグが書き込まれなくなった。

解凍

beet importの時、 py7zr · PyPIをインストールしていれば、圧縮ファイルをインポートすると同時に解凍までしてくれる。

$ pip install py7zr
・・・中略・・・
Successfully installed rarfile-4.1
$ beet import -c ~/Music/backflowEP.zip
/tmp/tmp6idsgjz8

この時、コピー可もしくは移動可としないと解凍できないので、設定ファイルを編集するか、-c-mのコピーオプション、移動オプションを付けて実行すれば良い。

$ beet import ~/Music/backflowEP.zip
Archive importing requires either 'copy' or 'move' to be enabled.
No files imported from /home/arimasou16/Music/backflowEP.zip

タグ値がない場合は--フォルダに移動(コピー)される。

自動タグ付け

自動タグ付けの実行内容はこんな感じ。

/music/AC-DC/Black Ice (15 items)
Tagging:
    AC/DC - Black Ice
URL:
    https://musicbrainz.org/release/37930e4a-5b7f-41a1-87f9-832024b6f0c7
(Similarity: 100.0%) (Digital Media, 2014, XW, Columbia, G010003236147T)
 * Rock N Roll Train     -> Rock ’n’ Roll Train
 * Skies On Fire         -> Skies on Fire
 * Smash N Grab          -> Smash ’n’ Grab
 * Spoilin' For A Fight  -> Spoilin’ for a Fight
 * She Likes Rock N Roll -> She Likes Rock ’n’ Roll
 * Rock N Roll Dream     -> Rock ’n’ Roll Dream
 * Rocking All The Way   -> Rocking All the Way

・・・中略・・・

/music/Behemoth/In Absentia Dei Disc 1
/music/Behemoth/In Absentia Dei Disc 2 (19 items)
Correcting tags from:
    Behemoth - In Absentia Dei Disc 2
To:
    Behemoth - In absentia dei
URL:
    https://musicbrainz.org/release/99108bfa-fa7a-4c5f-a81c-6a9596adbb8b
(Similarity: 98.2%) (album) (2xCD, 2021, XW, Nuclear Blast, 3984-15772-2)
CD 1
 * Wolves Ov Siberia                  -> Wolves ov Siberia
 * From The Pagan Vastlands           -> From the Pagan Vastlands
CD 2
 * Ora Pro Nobis Lucifer (#1)         -> Ora pro nobis Lucifer (#9)
 * Satan's Sword (I Have Become) (#2) -> Satan’s Sword (I Have Become) (#10)
 * Ov Fire And The Void (#3)          -> Ov Fire and the Void (#11)
 * Chwała Mordercom Wojciecha (#4)    -> Chwała mordercom Wojciecha (#12)
 * As Above So Below (#5)             -> As Above So Below (#13)
 * Slaves Shall Serve (#6)            -> Slaves Shall Serve (#14)
 * Chant for Ezkaton 2000 e.v. (#7)   -> Chant for Ezkaton 2000 E.V. (#15)
 * Sculpting The Throne Ov Seth (#8)  -> Sculpting the Throne ov Seth (#16)
 * Bartzabel (#9)                     -> Bartzabel (#17)
 * Decade Ov Therion (#10)            -> Decade ov Therion (#18)
 * O Father O Satan O Sun! (#11)      -> O Father O Satan O Sun! (#19)

/music/Behemoth/Live Barbarossa - Behemoth September 26, 2012, Ekaterinburg, Russia (14 items)
Skipping.

/music/Behemoth/Satanist (12 items)
Correcting tags from:
    Behemoth - Satanist
To:
    Behemoth - The Satanist

・・・中略・・・
/music/BELLFAST/Insula Sacra (11 items)
Correcting tags from:
    BELLFAST - Insula Sacra
To:
    Bellfast - Insula Sacra
URL:
    https://musicbrainz.org/release/f92bf385-b5b9-4e03-b892-7ebe19a8422d
(Similarity: 97.1%) (tracks) (CD, 2010, JP, METAL FRONTIER, KICP-1618)
 * Deadly Oath (5:03)       -> Deadly Oath (4:53) (length)
 * The Lone Horseman (7:46) -> The Lone Horseman (7:01) (length)
 * Celtic Drum (6:54)       -> Celtic Drum (7:34) (length)
 * Winds of Time (6:40)     -> Winds of Time (6:21) (length)

/music/BELLFAST/Triquedraco (11 items)
Correcting tags from:
    BELLFAST - Triquedraco
To:
    Bellfast - Triquedraco
URL:
    https://musicbrainz.org/release/a24884f7-3a1b-496d-9948-fb7ed8291903
(Similarity: 99.8%) (tracks) (CD, 2017, JP, METAL FRONTIER, KICS 3534)
 * Dragon's Lament (Prologue)    -> Dragon's Lament (title)
 * Ou est la Rose?               -> Où est la Rose?
 * 1014 (The Battle Of Clontarf) -> 1014 (The Battle of Clontarf)
 * Inis Mor                      -> Inis Mór

類似性Similarity3がいくつ以上なら、自動タグ付け反映するかは、設定ファイルで調整可能。以下の場合、類似性90%以上であれば反映される。

match:
    strong_rec_thresh: 0.10

許容値未満の場合、尋ねずにスキップする場合は-q、逆に毎回確認を求める場合は、-tのオプションを付ければ良い。その他、細かい設定、オプションなどは Using the Auto-Tagger — beets 1.6.0 documentationに記載されている。

import:
    timid: no
    quiet: yes

興味深いのは'シングルコーテーション(アポストロフィ、U+0027)としているものが、右のシングルコーテーションマーク(U+2019)で登録されいるものが多いということだ。

    μ's - Music S.T.A.R.T!!
To:
    μ’s - Music S.T.A.R.T!!

アポストロフィって何だっけ? 文字コードをめぐる謎|『人文×社会』の中の人

これ、どうやって入力するんだろうか?英語キーボード、直接入力にしても'しか打てないのけど、ロケールなど変えると右のシングルコーテーションマークになるのか?それともわざわざ、特別なことをして入力しているのか?

どちらもシングルクーテーションだが、後者は右のシングルコーテーションマーク(right single quotation mark)となっているんだね…

このように多様多彩な機能をもつbeets是非、使ってみてほしい。


  1. 自分の環境では~/.local/lib/python3.10/site-packages/mediafile.pyだった。github上のソースでは、 mediafile/mediafile.py at master · beetbox/mediafile · GitHubとなる。 ↩︎

  2. foobar2000がそういう仕様だった。 ↩︎

  3. Autotagger Matching Options ↩︎