最近社内ではiTunes専用のPCを用意して社内BGMを流しています。
「コマンドラインから曲のリクエストを出せないかな」と思って、勉強がてらRubyを使ってジュークボックスサーバ、ジュークボックスクライアントを作ってみました。
必要な機能は、
- 簡単に曲のリクエストを出せるクライアント
- 複数のクライアントから曲のリクエストを受付け、保持し、順次再生するサーバ
- クライアントが自動的にサーバを見つけるためのネームサーバ
などで、考えてみるとかなり面倒臭そうです。iTunesはDAAP(Digital Audio Access Protocol)というプロトコルで音楽をやり取りしたり、mDNS(Multicast Domain Name Service)というネームサービスを使ってサーバを見つけたりしているそうです。
今回は、dRubyを使って曲をやり取りし、RindaのTupleSpaceを使って曲の保持、クライアントとの待ち合わせをし、Ringをつかってクライアントがサーバを見つける仕組みを作りました。
スクリプトはそれぞれ下記のようになっています。
- jukebox_client.rb - 曲のリクエストを出すクライアント
- jukebox_server.rb - 曲のリクエストを保持し、順次再生するサーバ
- jukebox_ring_server.rb - クライアントが自動的にサーバを見つけるためのネームサーバ
利用方法
サーバ側では音楽再生のためにコマンドラインでmp3などが再生できるmpg123が必要です。(下記はUbuntu 7.04の場合)また、サーバ、クライアント共にRubyが必要です。(Ruby 1.8.6で動作確認をしています)
sudo apt-get install mpg123 mpg123-alsa
まず、サーバ側で下記でネームサーバを立ち上げます。
ruby jukebox_ring_server.rb
同じくサーバ側でジュークボックスサーバを立ち上げます。
ruby jukebox_server.rb
あとはクライアント側で再生したいMP3ファイルをしていしてクライアントを実行します。
ruby jukebox_client.rb Heart_Of_The_Sunrise.mp3
クライアントは同じLAN内にブロードキャストしてネームサーバを見つけ、そこに登録してあるジュークボックスサービスに曲のリクエストを追加します。サーバは曲がくるまで待ちうけ、リクエストを順次再生します。
ソースを見てもらうとわかりますが、Ringのサンプルほぼそのままです。
jukebox_server.rb:
#!/usr/bin/env ruby require 'rinda/ring' require 'rinda/tuplespace' require 'tmpdir' class JukeboxServer def initialize @play_list = Rinda::TupleSpace.new end def play puts "waiting..." name, music_file = @play_list.take([:music, nil]) puts "playing..." system "mpg123 #{music_file}" File.delete "#{Dir.tmpdir}/#{music_file}" end def request(file_name, music_data) open("#{Dir.tmpdir}/#{file_name}", "w") {|f| f.write music_data } @play_list.write([:music, "#{Dir.tmpdir}/#{file_name}"]) end end jukebox_server = JukeboxServer.new DRb.start_service(nil, jukebox_server) provider = Rinda::RingProvider.new(:jukebox, DRbObject.new(jukebox_server), 'Jukebox Server') provider.provide loop { jukebox_server.play } DRb.thread.join
クライアントはDRbオブジェクト経由でサーバ側のtmpディレクトリに音楽ファイルを保存し、そのパスをTubpleSpaceに保持して、サーバーが順次再生します。
こんな短いコードで分散オブジェクトやネームサービスが実現できることに驚きました。Ringに関しては複数のIPがある場合にうまくいかないところがあってまだ勉強中です。
コマンドラインから音楽のリクエストが出せて嬉しいかどうかはさておき、他に色々と面白い使いかたができそうです。
ソース: jukebox.tar.bz2