有馬総一郎のブログ

(彼氏の事情)

2024年04月30日 06:46:51 JST - 14 minute read - Linux

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

FAQ | Navidromeを見ると音楽メタデータの編集アプリとして、 beetsがおすすめされている。当初、 beetsのインストールが上手くいかなかったのと、設定が余りに煩雑なので MusicBrainz Picardを使っていた。しかし、最近、ようやく使いかたが分かってきたのでまとめておく。

beets

ただのタグエディタじゃない

beetsは、ただのタグエディタじゃない。プラグインを追加して、再生アプリと連携してことで音楽プレイヤーとして使うも出来る。また、タグエディタとしてもCLIだけあって、55,000曲もの音楽であっても高速に読み書き管理することが出来る。

snapwineを使ってまで foobar2000を使う人がそれなりにいるのも、リッピング、タグエディタ、プレイヤーとして三拍子揃った音楽プレイヤーだからだ。

曲再生アプリとしては、 Top 11 Best Music Players for Linux [2024]にもあるとおり、 Strawberry Music Playerなど素晴しいものがいっぱいある。

リッピングも FrontPage - AbcdeWikiAsunderなどある。

ただ、タグエディタには寡聞にして満足するものが殆どない。一時的に書き込むタグエディタにとどまっているか、もしくは、ライブラリとして保存・管理できるが、自動タグ付けの方向に向かっている。そして、多くが5万曲を読み込むと固まる。しかし、beetsはメモリも逼迫することなく、5万曲の管理出来る。

インストール

私のような雑魚Linux使いであるならば、pip install beetsでインストールするのは待ってほしい。 Getting Started — beets 1.6.0 documentationにあるとおり、パッケージマネージャでインストールするのが良い。pythonの依存関係で上手くインストール出来ないことがあるからだ。

実際、自分はインストールでは成功と出るのだけど、エラーで実行できなかった。

$ beet config -p
** error loading plugin bandcamp:

何故かインストールされるべきモジュールが無かったので、手動で以下のコマンドを実行した。

pip install beets-bandcamp
pip install beets-describe
pip install pylast
pip install mpd-queue
pip install flask
pip install beets-yearfixer

しかし、結果として、プラグイン重複のエラーが出るようになってしまった。解決方法が分かなかったので、暫く使うことはなかった。

Traceback (most recent call last):
  File "/home/arimasou16/.local/bin/beet", line 8, in <module>
    sys.exit(main())
  File "/home/arimasou16/.local/lib/python3.10/site-packages/beets/ui/__init__.py", line 1285, in main
    _raw_main(args)
  File "/home/arimasou16/.local/lib/python3.10/site-packages/beets/ui/__init__.py", line 1268, in _raw_main
    subcommands, plugins, lib = _setup(options, lib)
  File "/home/arimasou16/.local/lib/python3.10/site-packages/beets/ui/__init__.py", line 1152, in _setup
    item_types.update(plugins.types(library.Item))
  File "/home/arimasou16/.local/lib/python3.10/site-packages/beets/plugins.py", line 341, in types
    raise PluginConflictException(
beets.plugins.PluginConflictException: Plugin acousticbrainz defines flexible field average_loudness which has already been defined with another type.

最近は 俺流!PEP668とうまくやっていく方法 | スクエニ ITエンジニア ブログにあるように、安易にpip install出来なくなっている。システムを構築するツールとなっているpythonを使って出鱈目にインストールされては困る?ということだろう。

パッケージマネージャが提供できるものをインストールするか、以下のように仮想環境にインストールするとトラブルにならない。

もしくは、 beets - LinuxServer.ioからbeetsのcompose.yamlを使ってdocker環境で試すのも悪くない。

services:
  beets:
    image: lscr.io/linuxserver/beets:latest
    container_name: beets
    environment:
      - TZ=Asia/Tokyo
    volumes:
      - /home/arimasou16/.config/beets:/config
      - /home/arimasou16/Music:/music
      - /home/arimasou16/Downloads:/downloads
    ports:
      - 8337:8337
    restart: always

ただし、提供されるイメージのbeetsが、デフォルトからの多少変更があり、プラグインもインストール1されている。音楽ディレクトリ:roを付与して読み込み専用にした上でタグの取り込みだけ試した方が良いと思う。

基本操作

基本操作としては、以下のようになる。

  1. 設定

    beet config -e

  2. ライブラリー(音楽フォルダ・ファイル)のインポート

    beet import 音楽フォルダ・ファイルのパス

  3. データベース更新

    beet modify クエリ もしくは Edit Pluginをインストールしてbeet edit クエリ

    ファイルタグ反映beet update クエリ

  4. タグ書き込み

    beet write クエリ

  5. ファイル・フォルダ移動

    beet move クエリ

  6. 画像ファイル埋め込み

    ファイル指定は EmbedArt Pluginをインストールしてbeet embedart -f 画像ファイルパス クエリ

    自動取得なら FetchArt Pluginをインストールしてbeet fetchart クエリ

  7. 曲再生

    Play Pluginをインストールしてbeet play クエリ

通常のアプリなら、ファイルにいきなりタグを書き込むが、たまに忘れたりして、beet updateでタグからデータベースに反映されて先祖返りしたりする。慣れが必要。

設定ファイル

beet config --default > ~/.config/beets/config.yamlとすれば、現在2のデフォルト設定ファイルが出力される

一応、私の設定ファイルを書き残しておく。

# Beets configuration --------------------------------------------------------
library: ~/.config/beets/musiclibrary.blb
directory: /Music/

replace:
    '[\\/]': '-'
    '^\.': _
    '[\x00-\x1f]': _
    '[<>:"\?\*\|]': _
    '\.$': ''
    '\s+$': ''
    '^\s+': ''
    '^-': '-'

art_filename: folder
threaded: yes
format_item: $artist   $album   $title
sort_item: albumartist+ year+ album+ disc+ track+
sort_album: albumartist+ year+ album+
per_disc_numbering: no
clutter:
  - "Thumbs.DB"
  - "Thumbs.db"
  - "thumbs.db"
  - ".DS_Store"
  - "folder.*"
  - "*.m3u"
asciify_paths: no
id3v23: yes
va_name : 'Various Artists'

import:
  write: no
  move: no
  copy: no
  resume: ask
  timid: no
  log: beetslog.log
  incremental: no
  from_scratch: no
  quiet: yes
  quiet_fallback: asis
  default_action: asis
  languages: jp en kr
  autotag: no
  ignore:
    - ".*"
    - "System Volume Information"
    - "lost+found"
  duplicate_action: remove

# Paths ----------------------------------------------------------------------
paths:
  default: $albumartist/$album%aunique{}/${filetrack}_${title}
  singleton: Singletons/$artist - $title
  comp: Various Artists/$album%aunique{}/${filetrack}_${title}
  albumtype:soundtrack: Original Soundtrack/$album/${filetrack}_${title}

# Plugins --------------------------------------------------------------------

plugins: info inline duplicates rewrite edit embedart fetchart scrub zero play

edit:
  itemfields: album albumartist artist year disc disctotal genre genres title track tracktotal

embedart:
  auto: yes
  ifempty: no
  maxwidth: 0
  quality: 0
  remove_art_file: no

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

play:
  command: /usr/bin/mpv --no-video

fetchart:
  sources: filesystem coverart itunes amazon albumart
  cover_format: JPEG

item_fields:
  filetrack: u'%02i' % (track) if tracktotal > 9 else u'%01i' % (track)

自分もよく理解していない、誤解している部分もあると思う。

クエリ

全てのbeetコマンドの基本となるキーワードで検索する機能。

スペース区切りはand扱い。,or扱い。コーテーションで括れば、一単語扱い。またはスペースも\ エスケープすれば一単語扱いとなる。

-^はnot演算子となる。'で括ってもnotとして動作する。コマンドラインとしてのオプションとクエリを分割するにはbeet list -a -- artist:dylan -year:1980..1990 "-album::the(y)?"と間に--を入れることで、--以降がクエリとして見做される。

フィールドはfield:で指定する。

キーワードの前に:を付ければ正規表現が使える。フィールド指定と一緒の場合はtitle::^regex$

..で数値検索。日付だけでなく、ビットレートbitrateや、曲の長さlenghtも指定できる。

beet ls 'length:..1:00'と値の前に付ければ、未満。beet ls 'bitrate:3000000..'と値の後ろに付ければ、超過。beet ls 'added:2008..2010'と値の間に..付ければ範囲内となる。

beet ls -a 'added:-1w..'とマイナスを使って現在から何週間以内3なども検索できる。しかし、addedでしか使えないのか、yearでは駄目だった。

インポート

初回のフルスキャン、自動タグ付けは行わず、ただ取り込みだけなら数時間で完了する。さすがに自動タグ付けした場合はメモリも時間も相当使う。

$ beet stats
Tracks: 54878
Total time: 23.7 weeks
Approximate total size: 757.9 GiB
Artists: 3462
Albums: 4286
Album artists: 1412

beetsは、デフォルトでタグ書き込みwrite: yes、ファイルコピーcopy: yes、自動タグ付けautotag: yesとなっている。(元ファイルをコピーするとはいえ)一気にあなたの音楽ライブラリを書き換えるので、いきなりbeet import ~/Musicすることはおすすめしない。

docker経由でも自動スキャンとインポートだけで、タグ書き込み無し、ファイル移動無しなら、cpuが10%超えることはないし、メモリも24時間経っても2GBあたりで推移している。結局、半数ぐらいがスキップされたが、自動スキャン有での取り込みは29時間26分で終了した。

-sのオプションを付けるとアルバムでなくsingletonとしてインポートされてalbumfieldsがない曲となる。逆にフォルダ違いの曲を同アルバムとして扱いたい場合は--flatオプションを付ける必要がある。

情報表示

beet ls クエリformat_item: $artist - $album - $titleで設定したフィールドが確認できる。表示した結果をそのまま、クエリとして貼り付けたいので、私は- にした。

$ beet ls re-arise
RE-ARISE - RE-ARISE - Never
RE-ARISE - RE-ARISE - A Light In The Dark
RE-ARISE - RE-ARISE - The Red Sky
RE-ARISE - RE-ARISE - Iwo-Jima
RE-ARISE - RE-ARISE - Galaxy
RE-ARISE - RE-ARISE - Realize
RE-ARISE - RE-ARISE II - Beyond Control
RE-ARISE - RE-ARISE II - Seek The Faith
RE-ARISE - RE-ARISE II - Landscape
RE-ARISE - RE-ARISE II - Go Ahead
RE-ARISE - RE-ARISE II - Fu-Shi-Cho (Phoenix)
RE-ARISE - RE-ARISE II - HAYABUSA
RE-ARISE - Revive - The Struggle to Revive
RE-ARISE - Revive - Wasted Days
RE-ARISE - Revive - A Queen of Rising Sun
RE-ARISE - Revive - Negative Reward
RE-ARISE - Revive - Reach the Other Side
RE-ARISE - Revive - The Die Is Cast
RE-ARISE - Revive - Planet 9

もっと詳細な情報が知りたければ Info Pluginをインストールすれば(逆にデフォルトで入ってないのが不思議だ)、全情報を参照することが出来る。beetsのデータベースに沿った情報4を表示する場合は-lを付ける。

$ beet info Saber Tiger Disc
/mnt/hdd1/My Music/Saber Tiger/Live- OBSCURE DIVERSITY Disc 1/12_The Forever Throne.flac
           album: Live: OBSCURE DIVERSITY Disc 1
     albumartist: Saber Tiger
             art: True
          artist: Saber Tiger
        bitdepth: 16
         bitrate: 1037882
    bitrate_mode:
        channels: 2
            date: 2020-01-01
            disc: 1
       disctotal: 2
    encoder_info:
encoder_settings:
          format: FLAC
           genre: Heavy Metal
          genres: Heavy Metal
          length: 459.0
      samplerate: 44100
           title: The Forever Throne
           track: 12
      tracktotal: 12
            year: 2020
・・・後略・・・

タグ情報更新

設定ファイルで、edit:に編集したいフィールドを追記すれば、beet edit時に編集フィールドとして表示される。注意が必要なのが、ここのフィールドというのが、実際のタグではなく、beetsで扱われるタグということだ。

なのでdateを編集したくても、beetsではdateyearmonthdayと分割されてしまう。tracknumbertracktotaltrackstracktotalだったりとする。 itemfieldsに載っているのが、使えるフィールドとなる。

また、編集フィールドを増やす場合は-f フィールド--field フィールドを付ける。これは、デフォルトに追加するだけなので、指定したフィールドだけにはならない。複数、編集フィールドを追加する場合はbeet edit -f disc -f disctotal クエリとして複数オプションを使う。

そして、混乱しそうな点としては、-aアルバムオプションというのがあり、そこでは当然、albumalbumartistというのがあるけれども、これらは個々のトラックを一括で編集するだけかと思いきや、別。itemfieldsalbumfieldsに分かれている。初め、albumartistどおりにフォルダ名が変更されないので、どうしてかな、と思ったら、albumfieldsとしてのalbumartistが変更されていなかった。

beet edit -a myrath Karma

albumfields

album: Karma
albumartist: Myrath
id: 4276

beet edit myrath Karma

itemfields

album: Karma
albumartist: Myrath
artist: Myrath
disc: 1
disctotal: 0
genre: ' '
id: 54772
title: To The Stars
track: 1
tracktotal: 0
year: 0
---
album: Karma
albumartist: Myrath
artist: Myrath
disc: 1
disctotal: 0
genre: ' '
id: 54773
title: Into The Light
track: 2
tracktotal: 0
year: 0
・・・省略・・・

編集が完了したら、continue [E]diting, Apply, Cancelと編集を継続するか、適用するか、取消しするか確認されるので、適用Aと回答したら更新される。

Myrath - Karma - To The Stars
  tracktotal: 00 -> 11
  year: 0000 -> 2024
  genre:   -> Heavy Metal
・・・後略・・・

タグ情報書き込み

プラグインによってはbeetsのデータベースとタグを同期(更新と同時に書き込み)してくれているものもあるが、基本、データベースはデータベース内だけのタグ情報として留まるので、ファイルに書き込まないと他の音楽プライヤーからは変更前のまま。結構、忘れてしまうこともある。人によっては、データベースとファイルタグが分かれているのも悪くないかも知れない。

こちらも書き込み前には確認がある。

$ beet write myrath karma
Myrath - Karma   Into The Light
  tracktotal: 00 -> 11
  year: 0000 -> 2024
  genre:   -> Heavy Metal
Myrath   Karma   Into The Light
  tracktotal: 00 -> 11
  year: 0000 -> 2024
  genre:   -> Heavy Metal
・・・後略・・・

フォルダ移動、ファイル名変更

beet moveで設定ファイルのとおりにフォルダ移動とファイル名がされる。

paths:
  default: $albumartist/$album%aunique{}/${filetrack}_${title}
  singleton: Singletons/$artist - $title
  comp: Various Artists/$album%aunique{}/${filetrack}_${title}
  albumtype:soundtrack: Original Soundtrack/$album/${filetrack}_${title}

moveに関しては確認なしで実行される。

$ beet move myrath karma
Moving 11 items.

移動先を確認したい場合は、-pプレビューオプションを付ける。アルバムとして移動をしたい場合は-aアルバムオプションを付ける。正直、あまり気にしたことない。-aを付けても付けなくても、albumfieldsを見てフォルダ移動している。

$ beet move -p myrath karma
Moving 11 items.
/home/arimasou16/.var/app/com.usebottles.bottles/data/bottles/bottles/custom/drive_c/users/arimasou16/Music/mora/Myrath/Karma/001-To The Stars.flac
  -> /mnt/hdd1/My Music/Myrath/Karma/01_To The Stars.flac

厄介なのが、アルバムでなくsingletonと見なされてしまうと、それを修正するのが厄介ということbeet removeで削除してbeet importで再インポートするしかないのな?正直、このsingletonalbumfieldsとして扱いは何がメリットがあるのか分からない。

画像ファイル埋め込み

beet fetchart クエリで画像ファイルを取得して埋め込みまでしてくれる。どこから取得するかは設定ファイルで指定できる。

fetchart:
  sources: filesystem coverart itunes amazon albumart
  cover_format: JPEG

音楽ファイルと同フォルダ内から探すfilessytem。その次は Cover Art Archivethe iTunes StoreAmazonAlbumArt.org

自分で画像ファイルをダウンロードなどして用意している場合は、beet embedart -f 画像ファイルパス クエリを使う。私はこちらの方を良く使う。

$ beet embedart -f ~/Downloads/8129KiquG7L._AC_SL1500_.jpg Revive RE-ARISE
RE-ARISE - Revive - The Struggle to Revive
RE-ARISE - Revive - Wasted Days
RE-ARISE - Revive - A Queen of Rising Sun
RE-ARISE - Revive - Negative Reward
RE-ARISE - Revive - Reach the Other Side
RE-ARISE - Revive - The Die Is Cast
RE-ARISE - Revive - Planet 9
Modify artwork for 7 files (Y/n)? y

埋め込み対象となるファイルの確認がされるものありがたい。fetchartembedartどちらも既に埋め込み済であっても強制埋め込む-fというオプションがある。これを利用して既に同フォルダに配置した画像ファイルを埋め込み直す場合は、beet embedart -f folder.jpg クエリとするか、beet fetchart -f ^art_source:filesystem クエリとすることで可能となる。

逆に埋め込まれた画像ファイルを抽出する場合はbeet extractart -o 出力フォルダ+ファイル名(拡張子抜き) クエリとなる。

ちょっとややこしいのが、出力フォルダ+ファイル名(拡張子抜き)という部分。正直、デフォルトでクエリ対象の曲の同フォルダに出力してくれればと思うが、コマンド実行フォルダとなるので、出力フォルダまで指定する必要がある。

また、beet extractart -o ~/Music/有馬総一郎/folder.jpg 有馬総一郎 1stアルバムと拡張子まで指定すると、folder.jpg.jpgというファイル名で出力されてしまう。実体のファイルと、拡張子が不一致にならないための配慮だと思うけど、ちょっと戸惑う。

曲再生

beetsはタグ編集だけでなく、曲再生も出来る!単体としてではなく、連携する形なのでmpvといったCLIで動作する再生アプリと相性が当然良い。

再生アプリは設定ファイルで指定する。

play:
  command: /usr/bin/mpv

beet play クエリでクエリで対象となった曲が再生されていく。

$ beet play myrath karma
Playing 11 tracks.
Playing: /mnt/hdd1/My Music/Myrath/Karma/01_To The Stars.flac
 (+) Video --vid=1 [P] (mjpeg 1600x1600 1.000fps)
     Video --vid=2 [P] 'folder.jpg' (mjpeg 1600x1600 1.000fps) (external)
 (+) Audio --aid=1 (flac 2ch 44100Hz)
File tags:
 Artist: Myrath
 Album: Karma
 Album_Artist: Myrath
 Composer: Zaher Zorgati, Malek Ben Arbia, Anis Jouini, Kevin Codfert, Morgan Berthet
 Genre: Heavy Metal
 Title: To The Stars
 Track: 1
Displaying cover art. Use --no-audio-display to prevent this.
VO: [gpu] 1600x1600 yuv444p
AO: [pulse] 44100Hz stereo 2ch s32
beets

mpvのデフォルトのキー操作は以下のとおりになっている。

/etc/input.conf

## Seek units are in seconds, but note that these are limited by keyframes
#RIGHT seek  5                          # seek 5 seconds forward
#LEFT  seek -5                          # seek 5 seconds backward
#UP    seek  60                         # seek 1 minute forward
#DOWN  seek -60                         # seek 1 minute backward
#q quit
#ESC set fullscreen no                  # leave fullscreen
#p cycle pause                          # toggle pause/playback mode
#SPACE cycle pause                      # toggle pause/playback mode
#> playlist-next                        # skip to the next file
#ENTER playlist-next                    # skip to the next file
#< playlist-prev                        # skip to the previous file
#9 add volume -2
#/ add volume -2
#0 add volume 2
#* add volume 2
#m cycle mute                           # toggle mute

ヒットする曲が多すぎると、警告が出るのもありがたい。

$ beet play 'saber tiger'
You are about to queue 612 tracks.
[C]ontinue, Abort? A

私はそこまででもないが、クエリを極めに極めた場合、検索対象フィールド、ソート順まで指定できるので、聴きたい音楽が直ぐに再生できるかも知れない。

とはいえ、私のような人はアルバムやアーティスト、最近の曲の再生といった通常の使い方しかしないので、通常の音楽再生アプリの方が使い易いが、マウスを使えない状況では重宝しそうだ。

正直、自分もデータベース更新だけして、ファイルのタグ書き込みを忘れたり、思ったとおりの動作をしてくれなくて難儀することもあるが非常に面白いツールなので紹介してみた。次回は、自分の思い通りにタグ編集しようとすると、設定ファイルの編集だけでは出来そうになかった部分があるので、より深い部分を紹介する。


  1. 基本的なプラグインはplugins: info inline duplicates rewrite edit embedart fetchart scrub zero playと設定ファイルに追記するだけで使えるようになるが、ものによっては別途インストール手順が必要になる。 ↩︎

  2. 既にconfig.yamlがある場合は、その設定ファイルどおりのデフォルト設定が出力される。インストール直後のデフォルトは beets/beets/config_default.yaml at master · beetbox/beets · GitHubドキュメントを参考されたし。 ↩︎

  3. y年、m月、d日なども使える。 ↩︎

  4. bitrate: 2120402という表記がbitrate: 2120kbpsdateyearmonthdayに分かれてる、length: 238.24が、length: 3:58、未設定の数値タグが0で表示される。 ↩︎