その上に組めるプレイヤー
他のプレイヤーが Web サーバーを同梱して得ているものを、rox は持っています。ローカルの JSON-RPC ソケット、変化のたびにプッシュされるイベント、MCP プロキシ、そして Icecast への配信。
rox がなることを拒むサーバー
デスクトッププレイヤーが自分を外へ開くいつものやり方は、Web サーバーを埋め込むことです。それでリモート操作が手に入り、他のすべてを支払います。マシン上のポート、認証の仕組み、プレイヤー自身の見た目を捨てた Web UI、そして音楽プレイヤーが持つ筋合いのない攻撃面。プレイヤーをスクリプトで動かす少数のために、全ユーザーがその代金を払います。
rox は能力を残して、その届け方を拒みます。マシン向けインターフェースはローカルソケットで、Linux と macOS では Unix ドメインソケット、Windows では名前付きパイプ。データディレクトリに紐づくので、2 つのポータブルインスタンスが交差することはありません。認証はファイルシステムの権限です。あなたの音楽を読めるものは、ソケットが許すことを既にできます。ポートで待ち受けるものは無く、バイナリに HTTP サーバーは入っていません。
ソケット 1 本でプレイヤー全部
プロトコルは JSON-RPC 2.0、1 行に 1 オブジェクトで、バージョンのハンドシェイクから始まります。transport.* がデッキを動かします。再生の切り替え、シーク、音量、A-B 区間。queue.* は安定したエントリ id で再生順を編集するので、動かした行はあなたが動かしたつもりの行のままです。library.* は検索し、再生中の曲の完全なタグを返し、カバーアートを渡します。library.rescan と tasks.* は再スキャンと解析パスを開始し、見守り、止めます。開始の応答には、ウィンドウが見せたはずの曲数と所要時間の見積もりが載ります。どのメソッドもパネルと同じプレイヤーとライブラリを読んで動かすので、ソケットが UI の言わないことを言うことはありません。
先行例は mpv の JSON IPC と mpd のプロトコルで、その代償も同じです。サーバーなら curl で済んだところに、利用側はソケットクライアントが要ります。ソースツリーのリファレンスクライアント roxctl がシェルの場面を受け持ちます。1 回の起動で 1 呼び出し、スクリプトが読むなら --json。まだ 1 行も書かないうちから roxctl next も roxctl search miles davis も動きます。
プッシュするから、ポーリングしない
購読できないフロントエンドはポーリングします。だからイベントは最初のバージョンから契約に入っています。subscribe を呼ぶと、ソケットは動きのたびにフレームをプッシュします。曲の変わり目に event.track、再生状態、音量、ミュートが変わると event.playback、順序が変わると event.queue。
遅れた利用側は待たれるのではなく切断されるので、詰まった読み手が再生まで詰まらせることはありません。roxctl watch は届いた順にストリームを表示します。ステータスバー向けの再生中表示が、シェルのループ 1 つで済むということです。
他のどのプレイヤーにもない MCP
アプリの隣に rox-mcp が座ります。片側で stdio 越しに MCP を話し、もう片側でソケットを話す薄いバイナリです。Claude でもどの MCP クライアントでも向ければ、プレイヤーがツールになります。何が鳴っているか、ライブラリの検索、キューの読み取り、再生の操作、再スキャンや解析パスの開始。「70 年代の静かな曲をキューに入れて」は rox が育てるべき機能ではなくなり、アシスタントが実行できる一文になります。
どのツールもソケットのメソッドをプロキシするので、MCP の表面は作りからしてソケットが提供するものの部分集合で、先へ抜け駆けできません。しかもオプトインが二重です。既定でオフの AI 機能トグルが MCP 設定ページとそのスイッチを出し、どのツール呼び出しも応える前に実行中のアプリのトグルを見直します。オフが意味するのはハングではなく、はっきりした拒否です。
音声の側
操作はフロントエンドの半分で、もう半分は何かが聴こえることです。rox はソースクライアントとして Icecast サーバーへ接続しに行き、処理済みのストリームを MP3 にエンコードして指定のマウントへ送ります。タップは処理チェーンの後に来るので、配信はイコライザーも含めてスピーカーが受け取るものそのままです。
向きこそが要点です。rox は接続しに行くだけで、決してサーブしません。マウント、リスナー、ネットワークの顔はすべて Icecast のものです。届かないサーバーにはチャンクを捨てるだけで、ローカルの再生には触れません。シンクは設定が残るかぎり、自分のペースで再接続し続けます。
そこから開けるもの
各部品は単体で役に立ちます。メディアキーのデーモンやステータスバーのウィジェットは、ソケットと数行。ハードウェアコントローラー、ストリームデッキでもマイコンのつまみでも、それはソケットに届くものからの transport.* です。リスニングルームのキオスク係は、キューのメソッドと event.track が動かすディスプレイ。
合わせれば、rox は個人のストリーミング構成のバックエンドです。ソケット越しの再生操作とキュー、Icecast マウントから埋め込む音声、好きなもので書くフロントエンド。ライブラリは、それを保存しているマシンで鳴ります。
ソケットクライアントを持ってくる
ソケットは rox が動くところならどこでもオンで、rox-mcp はアプリの隣に同梱され、設定の MCP ページにはクライアント用の設定行があります。roxctl は ソース から cargo コマンド 1 つでビルドできます。