mpvとギャップレス再生について

mpvとは

メディアプレイヤーの一種である。おおよそこの世にあるほとんど全てのメディア形式に対応しており、オープンソースで開発されている。UNIX系でもWindowsでも動作する。また、バックエンドのAPIがlibmpvとして公開されており、これを使用する派生メディアプレイヤー(フロントエンド)も多く存在する。

ギャップレス再生というのは、楽曲間に無音時間を生じさせることなく再生する機能のことである。ファイル形式にもよるが、きちんと対応しているソフトウェアは意外と少ないなかで、mpvの対応状況はほぼ完璧に近いものと言えるだろう。

Windows向けビルド

Linuxを使える人にインストール方法の説明は不要だろう。Windows版はhttps://sourceforge.net/projects/mpv-player-windows/files/ からダウンロードできる。Weeklyビルドのほうがよくダウンロードされているようだが、ギャップレス再生に問題があることがあった(一時的なものかもしれないが)。changelogはあまり追っていないがreleaseにあるもの(2022/11/04時点で最新はほぼ1年前の0.34.0)でもそうそう不便はしないだろう。なお、設定ファイル(mpv.conf)は、mpv.exeと同じフォルダに入れておけばいいようである。

UIの改善

筆者の個人的な印象では、mpvの最大の欠点は(クリックで該当曲を再生できるような)プレイリスト画面がないことである。libmpvを使用する各種フロントエンドの中にはプレイリスト機能を持つものもあるが、その分ギャップレス再生の対応が怪しいものも多い。mpv.netなんかはそこそこ知名度もあるようだが、音量が小さくなっている気がするし、ちょっと怪しそう。Linuxを使用しているのであれば、お勧めはcelluloid(旧称GNOME MPV)である。ただし(他の多くのフロントエンドにも共通するが)標準入力からのデータ受け取りはできないことに注意。Windowsにはあまり良いものがないが、https://github.com/mpv-player/mpv/issues/5500 で紹介されているhttps://github.com/tomasklaen/uoscLuaで書かれたUIのプラグイン(?)で、mpv.confと同じ場所に展開すれば最低限のプレイリスト機能が使えるUIになる。

ギャップレス再生関係のオプション

以前は以下のようなオプションを指定しないとギャップレス再生されないことが多かったが、最近はデフォルトのままでもほぼ問題なく動く。ただしWeb上のリソースをギャップレス再生したい場合はprefetch-playlist=yesaudio-buffer=数字のどちらかを指定する必要がありそうである。上の3つは指定しておいても損はないだろう。数値は一例である。

詳しくは公式ドキュメント参照。

  • cache=yes キャッシュが行われる。キャッシュを表す線が表示される。
  • demuxer-max-bytes=5000KiB キャッシュの最大容量?
  • demuxer-readahead-secs=10 前読みの時間?
  • prefetch-playlist=yes Web上のリソース(HTTP等のリンク)を再生する際に予めリソースを取ってくることでギャップ発生を防ぐ?ドキュメントによると、highly experimentalな機能で、デメリットもあるらしい(例えばプレイリストが書き換わった場合などにうまく動作しない恐れがあるらしい)。後述のyoutubeのリンクに対しては無効。
  • gapless-audio=yes デメリットもありそう。デフォルトのweakで十分そうなので指定しなくてよさそう。
  • audio-buffer=2 曲の終了2秒前から次の曲の再生フェーズに切り替わる。Webリソースのギャップレス再生に有効。短すぎるとギャップレス再生に失敗する。
  • player-operation-mode=pseudo-gui CUIからの起動でもGUIを強制する。
  • fs=yes フルスクリーン表示になる。オプションが効いているかどうかのテスト用に使える。

YouTubeへの対応

内部でyoutube-dlを使用しているためYouTubeのリンクは(再生リストも含め)一通り再生できる。しかし、ギャップレス再生はできない。また、youtube-dlの最新リリース(2021.12.17)ではダウンロードが異常に遅くなる不具合が解決していないため、mpvでも問題が発生する可能性がある。

celluloidビルドメモ

余談だが、celluloidをWindows向けにビルドしてみたので、その際のメモを載せておく。

MSYS2の64bit版を入れる。READMEに書いてある通り基本的には

meson build && cd build && ninja && sudo ninja install

という流れ。

meson buildをするとbuildというフォルダになんかビルド用ファイルたちができる。この時点でライブラリが足りなかったら出るはずなのでそれを入れていく。全部ちゃんとMSYS2にある。MSYS2でダウンロードがうまくいかないときは--disable-download-timeoutを付けるといいかも。

次にninjaをする。どこで止まってるかよくわからんので、なんかのファイルにリダイレクトしてログを取って、そこで「error」で検索した。エラーが出るたびにその場しのぎの適当な修正をしていたら意外と通った。出たエラー一覧

  • いつ出たか忘れたが(最初のほうだったかな)、なんか色々とヘッダが足りんと言われるのでmeson.buildに global_cflags = ['-ID:/msys2/usr/include'] と追加する(この例ではD:\msys2にMSYS2をインストールしている)
  • struct flockが多重定義されている →後に出てきた方(usr\include\sys\_default_fcntl.hだったかな?)をコメントアウトした
  • glib-unix.hにある#error "This header may only be used on UNIX” というプリプロセッサ命令に引っ掛かる→コメントアウトした
  • celluloid-mpv.cにおいて、gdk/gdkwin32.hってのが見つからんと言われる →探したらgdk**/win32**/gdkwin32.hがあったのでそう書き換えた
  • mingw64/include/winsock.hにあるselectgethostnameの型が以前に定義されているものと違うと言われる→winsockが悪いと判断して以前のものと揃えた
  • (ldのエラー)undefined reference to `__stack_chk_fail'と言われる →meson.buildでgccの(リンカの?)オプションにfno-stack-protectorを指定する(ただし既に-fstack-protector-strongが指定されているのでそれを変更する形になる)
  • (ldのエラー)celluloid-application.cにおいてundefined reference to `g_unix_signal_add'と言われる →g_unix_signal_addが使われている3行(連続している)をコメントアウト(※これをするならglib-unix.h自体がいらない気がするので前述のglib-unix.hの編集も不要?)

結果として、videoは一切動作しない(動画は見れない)が、音声は正常に再生できるし、動画ファイルでも--video=no(celluloidのオプションとしては--mpv-video=no)を指定すれば中の音声は聴ける。しかし、他にも以下のような問題があり、残念ながら音声ファイルに関してもまだ実用に適するとは言えない。

  • 文字小さくて見えない→どうすればいいかわからん
  • mpvと違って再生終了後にウインドウ閉じない→--mpv-keep-open=no指定してみたけどだめ、これもわからん(これLinux版でも同じ?)
  • タスクバーのアイコンに再生の経過が表示されない(これはしょうがない)
  • 変なことすると落ちる