| < 2007年2月 > | ||||||
|---|---|---|---|---|---|---|
| 28 | 29 | 30 | 31 | 1 | 2 | 3 |
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 1 | 2 | 3 |
次の日記: 2007/02/21 21:06 [ちぃずけぇき]
| < 2007年2月 > | ||||||
|---|---|---|---|---|---|---|
| 28 | 29 | 30 | 31 | 1 | 2 | 3 |
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 1 | 2 | 3 |
先に書いておきますが、プログラマ以外にはさっぱりな話です。苦手な人は読まないことを推奨します(笑
いい加減 iTunes の重さにぶち切れそうになったので、管理を iTunes、再生をほかのプレーヤでーとか悩んだ結果。CPU が暇してる silky に働いてもらうことにしました。
一応2つについて軽く。icecast はストリーミングのサーバプログラム。単体でも、mp3 ファイルなどをリクエストに応じて転送する機能は有する。liveice は、マイク入力やプレイリストで指定した mp3 ファイルを icecast サーバに送信するプログラム。プレイリストだけなら、icecast パッケージに入っている shout でも可能。
ちなみに iTunes はテキストファイルでプレイリストを出力できるので、出力されたデータを Perl に食わせて silky 上のファイルのパスに変換可能。smb でマウントするなりすればストレージの問題なんてっ。
さて、この icecast+shout/liveice を使って困ったこと&解決案のメモ。
まず、shout だと VBR や、エンコードのビットレートがばらばらなファイルを食わせるとどうしても転送エラーが出て切断されてしまう。自動調整とかいろいろあるけど、どうにもうまく働いてくれてない模様。
liveice は、mpg123 を mp3 デコーダとして、lame などをエンコーダとして利用していて、元のファイルのビットレートなどを気にしないで使える。プレイリストなどの機能も持っているので、動いてるだけである程度の CPU 負荷がかかるということ以外は shout よりよい。まぁ、結構文句はあるんですが。
割と説明はほかのサイトさんでもやってるというか、んなもんサンプルの設定ファイル読めばわかるんで、ほかの事を。
まず、iTunes などでいじった mp3 ファイルの一部が実は読めない。これは mpg123 に問題があって、MPEG の開始ヘッダ?を最初の 64KB しか検索しない。ID3 タグがアートワークなどで膨れ上がった mp3 ファイルだと、ヘッダが見つからなくて fail になる。
FreeBSD ports にある mpg123-0.59r の場合、make してファイルをダウンロード、コンパイルが始まったところで停止させて、ファイルを編集する。common.c L215〜L225 あたりにあるのがヘッダ検索のロジックで、/* step in byte steps through next 64K */ とあるとおり、for ループで 65536 までループしている。とりあえず手元にあるファイルが再生できればいいやー、ということで、1024*1024 に変更。あとは make && make install で OK。
次は liveice のバグ。liveice.cfg には、次のようなことが書いてあります。
# update script can be executed at every track change...
# Not well documented - in fact not documented at all
1曲再生が開始される度に、指定したプログラムが実行されるという、なんとも素敵なモノなんですが、これ、動きません。
あとでまとめますが、meta_data.c の execute_update_script で printf みたいに引数の展開とかやってるんですが、1文字処理するごとに system をコールしちゃってて、/home/〜 とか指定すると、system("/")、system("/h")…と大量のエラーが出るわけです。
この system を一個外のループに追い出して、ついでに /* really should fork before this */ とか書いてあるので、#include <roken.h> を加えた上で、
if(fork() == 0) {
char *args[] = {0};
execve(exec_line, args, environ);
}
これでちゃんと動きます。引数の解析ができないのでちょっとアレですが、んなもんはシェルスクリプトに食わせればいいのです。というか、動かないよかマシ。
これで起動すればストリーミングサーバの完成。定期的にプレイリストのファイルを上記の UPDATE_SCRIPT で変えてやればおいしいかなーっと…思ったらプレイリストは読み直してくれなかった orz
以上、考えないで動いたら少し痛い目にあいました。しかしまぁ、最近はやっとオープンソースなプログラムの読み方というか、人のコードが理解できるようになったのでよかったかな、と。
さて、またまとめなきゃいけないモノが増えたぞーっ。
<Trackback URI> http://linkage.white-void.net/cgi/tb.cgi/diary/2007022001
コメントフォーム