music player daemon

2022-12-09 linux sound

pyspa Advent Calendar 2022 9日目です。8日目は分散処理に詳しいオタク kumagi でした。

去年のエントリでswayをコンポジターにしてwayland生活をするようにしたわけだが、軽量なデスクトップにしていくのでも音楽を聴く余裕は欲しいものである。 mpd (Music Player Daemon) は名前の通りデーモンで動くミュージックプレイヤーである。もちろんヘッドレスでGUIどころかクライアントは別途選ぶもので、軽量デスクトップ野郎どもの友と言えるミュージックプレイヤーだ。

Linuxで音楽を聴く

ところでLinuxで音楽を快適に聴くにはある程度仕組みを知っていないと設定がおぼつかない。一応mpdを設定する上で調べてみたところを書いておく

alsa, pulseaudio,pipewire

まずはdacなりHDMIなりのデジタルオーディオデバイスを操作する部分が必要だが、これはALSA(Advanced Linux Sound Architecture) というカーネルコンポーネントの仕組みとなっている。とりあえずALSAが設定されてないとそもそも音を出せないが、まあ最近のディストロはデバイスを認識して設定してくれるのでそれほど問題ないだろう。ここでつまずいた場合はなんかがんばってください。そしてアプリケーションがどう音を出すかだが、直接alsa APIを扱うアプリケーションもあるがデスクトップ環境ではソフトウェアミキサーがあって多くのアプリケーションはそこを経由して効果音や音楽など音を出す。過去にはGNOMEがesound、KDEがartsだったが、どちらもpulseaudioに移行した。 pulseaudioは音質が抑えめでjackという高音質な代替もある。さらにpulseaudioからpipewireに移行しつつある。色々あるがwaylandでは画面共有などの都合もあるのでpipewireを使うのが普通な気がする。

pipewireとwireplumber, spa

ということでwaylandにした環境でさらにpulseaudioを捨ててpipewireに移行。 debianを使っているので PireWire - Debian Wiki を参考にpipewireやspa(pipewireのプラグインみたいなやつ?)をインストールしてpulseaudioのインターフェイスも動くようにした。

mpdのインストールと設定

mpdをインストールしてサービス起動を設定

さて、本題のmpdである。aptで入れたので、他のディストロ使っている人やソースから入れる人は Download the Music Player Daemon のページなどを参照のこと。

mpdはデーモンなのでsystemdのservice unitで管理したい。 debianでインストールするとsystemd service unitの定義も一緒に入ってるのでこれを利用する。デフォルトでsystem sessionで起動するようになっているが、音楽ファイルのディレクトリはユーザー以下にしたいのでuser sessionのサービスとして扱いたい。

さらにservice unitだけでなくsocket activationも用意されているのでこれらをuser sessionで有効にする。 socket activateは直接サービス起動するのではなくポートへのアクセスで初めて本体が起動するやつ。まあどうせすぐ使うからログインしたらすぐ起動しちゃってもいいんだけど。

$ sudo systemctl --now disable mpd.socket
$ systemctl --now --user enable mpd.socket

mpdの設定

システム的なmpd自体の設定は /etc/mpd.conf にあるが、ディレクトリの指定やoutputなどだいたい変更するのであんまり気にしない。ユーザーとして実行する場合の設定ファイルはXDGを尊重して /.config/mpd/mpd.conf を使うことにする。ログやキャッシュのディレクトリもなるべくXDGを尊重する。outputをpipewireにしてあるが、spa-pulseaudioを設定してあるならpulseaudioをoutputにしてもいい。ただせっかくpipewireにしたしdebian sidのmpdだとpipewireをサポートしているのだからここはpipewireで設定しておく。

music_directory "~/Music"
playlist_directory "~/.local/cache/mpd/playlists"
db_file "~/.local/cache/mpd/tag_cache"
state_file "~/.local/cache/mpd/state"
sticker_file "~/.local/cache/mpd/sticket.sql"
log_file "~/.local/cache/mpd/mpd.log"

bind_to_address "localhost"

audio_output {
  type "pipewire"
  name "My Pipewire Output"
  dsd "no"
}

input_cache {
    size "1 GB"
}

decoder {
  plugin "hybrid_dsd"
  enabled "no"
}

decoder {
  plugin "wildmidi"
  enabled "no"
}

設定を変えたら systemctl --user restart mpd なりなんなりしておきましょうね。

mpc コマンドラインのクライアント

デーモンが動いたので次はクライアントである。 mpc はコマンドラインで扱えるmpdクライアント (Music Player Clientだろうな)でmpdインストールすれば一緒にインストールされているはずだ。

コマンドライン

mpcのサブコマンドはmpdでできることをすべてカバーしていると思うので結構多いが、曲を選んで再生するといった普通の操作としては以下のものくらいを覚えておけばいいだろう。

  • queued - Show the currently queued (next) song.
  • play <position> - Starts playing the song-number specified. If none is specified, plays number 1.
  • pause - Pauses playing.
  • next - Starts playing next song on queue.
  • prev - Starts playing previous song.
  • add <file> - Adds a song from the music database to the queue. Can also read input from pipes. Use “mpc add /” to add all files to the queue.
  • ls [<directory>] - Lists all files/folders in <directory>. If no <directory> is specified, lists all files in music directory.

プレイリストキューに追加して再生

ではmpcを使って音楽ライブラリをサーチしてみよう

まずは全曲からアーティスト名だけを取り出してみよう。 mpc ls は全曲の一覧を表示する。 -f%artist% をフォーマットにすればアーティスト名だけが返ってくるので uniq してあげればいい。

$ mpc ls -f %artist% | sort | uniq
B'z
ZARD

ここで mpc search を使ってartistがZARDのものからアルバム名だけ取り出してみる。全曲のアルバム名が並ぶのでこれも uniq した結果を見よう。

$ mpc search -f %album% artist ZARD | sort | uniq
Good-bye My Loneliness
HOLD ME
OH MY LOVE
TODAY IS ANOTHER DAY
ZARD BLEND II `LEAF & SNOW`
ZARD Forever Best ~25th Anniversary~
forever you
もう探さない
永遠
揺れる想い

でアルバム指定で曲のリストを出すには mpc search album 揺れる想い などとすればいいのだがプレイリストキューに追加するには音楽ライブラリディレクトリからのパスが必要だ。フォーマットに %file% を使えばファイルパスが帰ってくる。

$ mpc search -f %file% artist ZARD album 揺れる想い
ZARD/揺れる想い/01 揺れる想い.mp3
ZARD/揺れる想い/02 Season.mp3
ZARD/揺れる想い/03 君がいない (B-version).mp3
ZARD/揺れる想い/04 In my arms tonight.mp3
ZARD/揺れる想い/05 あなたを好きだけど.mp3
ZARD/揺れる想い/06 負けないで.mp3
ZARD/揺れる想い/07 Listen to me.mp3
ZARD/揺れる想い/08 You and me (and...).mp3
ZARD/揺れる想い/09 I want you.mp3
ZARD/揺れる想い/10 二人の夏.mp3

この一覧を mpc add でプレイリストキューに追加してあげればいい。

$ mpc search -f %file% artist ZARD album 揺れる想い | mpc add
$ mpc playlist
ZARD - 揺れる想い
ZARD - Season
ZARD - 君がいない (B-version)
ZARD - In my arms tonight
ZARD - あなたを好きだけど
ZARD - 負けないで
ZARD - Listen to me
ZARD - You and me (and...)
ZARD - I want you
ZARD - 二人の夏

ここで mpc play を実行すればプレイリストキューを順に再生してくれる。一時停止したければ mpc pause だ。

$ mpc play
ZARD - 揺れる想い
[playing] #1/10   0:00/4:28 (0%)
volume:100%   repeat: off   random: off   single: off   consume: off
$ mpc pause
ZARD - 揺れる想い
[paused]  #1/10   0:13/4:28 (4%)
volume: 98%   repeat: off   random: off   single: off   consume: off

mpcをfzfと組み合わせる

しかし、音楽聴くためにこんなコマンド入力を毎回するわけがない。こういうコマンドはビルディングブロックの一部だ。多分 UNIXの哲学 とかにそんなことが書いてあったと思う。ということでなんか色々絞り込みできる fzf を使って上の流れをもっと簡単にできるようにしてみよう。

#!/bin/bash

MPC=/usr/bin/mpc
CMD=/usr/bin/fzf

artist=$($MPC ls -f %artist% | sort | uniq | $CMD)
album=$($MPC search -f %album% artist "$artist" | sort | uniq | $CMD)
$MPC search -f %file% artist "$artist" album "$album" | $MPC add
$MPC play

ncmpcpp

でもまあプレイリストキューとか一目で見れるようなGUIなりTUIなりの画面がないと辛い。そして軽量デスクトップ野郎どもに知ってほしいのはTUIのncmpcppだ。覚えにくい名前だ。まずはmpcがあり、ncursesで作られたのがncmpcでそこからフォークされて改善されたのが nc mpc pp だ。

インストールと設定

ncmpcppもaptで入れてます。プレイリストキューとか再生とかする分にはデフォルトでそのまま動くはず。メタデータの編集をするためにライブラリディレクトリの指定が必要なくらいか。設定ファイルはこれもXDGを守って ./config/ncmpcpp/config を使う。

mpd_music_dir = ~/Music

画面

weztermで表示してみたところ。必要最低限って感じだ。

一応これ以外にもビューがあって、キーボードで 1とか2とか押せば変更できる。

  1. プレイリストキュー
  2. ライブラリディレクトリビュー
  3. 検索画面
  4. アーティスト、アルバム、曲一覧という3ペインのビュー
  5. プレイリスト
  6. タグエディタ

だいたいこれでことたりる。あとncmpcpp自体はプレイヤーじゃないので閉じてしまっても再生は停止しない。ちなみに q で閉じる。

emacsで聴く

ところで私はだいたいemacsで作業しているのである(今年の抱負はvs codeに移行するとかだったはずなのだが)。 emacsからmpdを操作できればいいじゃないか。そして実際に emms を使えばmpdを操作できるのだ。

emms

emmms (Emacs Multimedia System) はバックエンドにmpg123などのコマンドを使ってemacsから音楽を聴くようになっている。が、外部コマンドを使うということはmpdのフロントエンドとしても使えるということであり、ちゃんと emms-player-mpd というものがプリセットとして用意されている。これは使うしかない!

通常は音楽ライブラリはディレクトリを指定するがmpdを使う場合はそちらから情報を取得するように設定する。まあこんなん公式ドキュメント見てくれたほうが正確なので、私の設定を晒すだけにしておこう。

(use-package emms
  :straight t
  :init
  (setq emms-source-file-default-directory (expand-file-name "~/Music/"))
  (setq emms-player-mpd-server-name "localhost")
  (setq emms-player-mpd-server-port "6600")
  (setq emms-player-mpd-music-directory "~/Music")
  :config
  (require 'emms-setup)
  (emms-all)
  (add-to-list 'emms-info-functions 'emms-info-mpd)
  (add-to-list 'emms-player-list 'emms-player-mpd)
  (add-hook 'emms-playlist-cleared-hook 'emms-player-mpd-clear)
  (emms-player-mpd-connect)
  (emms-cache-set-from-mpd-all))

これで準備は整ったので M-x emms-smart-browse でemmsを起動するとライブラリとプレイリストキューが表示される。ライブラリで曲やアルバムを選んでenterでキューに追加してプレイリストキュー側で再生開始(enterかなんか押せば開始する)だ。モードラインに現在再生中の曲名なども出るのでいかにもemacsで生活してますというアピールにもってこいだ。

それ以外のクライアント

デスクトップ環境をあまり入れないようにしているとはいえ、一応連携方法を知っておくと便利なのでメモ。まずデスクトップ環境でメディアプレイヤーの情報がタスクバーに出てたりするのは mpris というD-BUSサービスで情報を提供しているからだ。 mpd自体はmprisを実装していないが、 mpDris2 というプロキシデーモンあってこれがmpdの情報を提供してくれる。ついでに playerctl を使えば様々な mpris サービスに再生や停止といった操作を実行できる。(ほんとにそれくらいしかできないのであんまり使いやすいわけではない)

軽量デスクトップ野郎は重厚なタスクバーではなくconkyとかswaybarとかを使っているだろう。だいたいこういうのにはmpd pluginが用意されている。再生中の曲名やプレイタイムを表示してくれたり、一時停止次曲前曲などの簡易なコントロールを提供したりととりあえず入れておくといいだろう。

2022年

  • 2022年について
    • 何か新しいことを身につけられたのかなぁと毎年のように思ってしまう
    • 何かはしてたと思うんだけどなぁ