iTunesサーバーをたてて、LANで曲を共有するようにした


前から使ってたけど今はあまり使ってないデスクトップ、最近主力のMacBook、たまに使うLet’s NoteとうちにはPCが3台ある。あとGentooサーバー。全部の環境からmp3を共有したかったので、GentooでiTunesサーバーをたてて共有することにした。

まずはデスクトップからごっそり外付けHDDにmp3をコピー。1万曲超、60GBくらいあった。これをGentooにぶっさして、とりあえず放置。Gentooで環境構築。

wget http://www.porchdogsoft.com/download/howl-1.0.0.tar.gz
tar zxf howl-1.0.0.tar.gz
cd howl-1.0.0
./configure && make && sudo make install && cd
sudo emerge libogg
sudo emerge libvorbis
sudo emerge mt-daapd
sudo cp /etc/mt-daapd.conf.example /etc/mt-daapd.conf

confは適当にmp3の入った外付けHDDのmount先を指定したりweb_rootのパスワード指定したりする程度。これであっさり行くと思ったら、まずこのままではmt-daapdが起動しない。なぜか知らないが/etc/init.d/mt-daapdで、depend()部分が間違ってるのが原因。mDNSResponderをmDNSResponderPosixに修正、mDNSResponderPosixを起動してから再度動かすと動いた。

これでとりあえず動いたものの、MacのiTunes上からは文字化けの嵐。WindowsのiTunesでは問題ない。つまり文字コードの問題だな。ここは先人の知恵を借り、ググってみるとwindows上で変換しるとよいことが判明。HDDを一旦デスクトップにつないで、iTunesで曲を全部選択して「ID3タグを変換」→「Unicodeを元に戻す」。何故かうまく行かないで化けちゃうのがあるので、個々に探して同様に変換したら直った。とりあえずこれでタグは問題なくUnicodeになったので、再度Gentooにつないでmountしてmt-daapdのキャッシュをクリアしたらok。ちなみにmountするときには、mount -o noauto,users,umask=000,iocharset=utf8とか言ってやらないと正しくGentoo上で日本語が読めない。

これでokかと思いきや、やっぱり文字化けは解消せず。色々調べてみたら、パッチを当てれば解決することが判明。

sudo emerge -C mt-daapd
wget http://nchc.dl.sourceforge.net/sourceforge/mt-daapd/mt-daapd-0.2.4.2.tar.gz
tar zxf mt-daapd-0.2.4.2.tar.gz
cd mt-daapd-0.2.4.2
wget http://www.kzsoft.to/~kazu/mt-daapd/patch/mt-daapd-0.2.4-cp932.patch
patch < mt-daapd-0.2.4.2.tar.gz

parser.cのパッチでこけるので、手動でパッチした。とりあえずdiffを残しておく。

--- src/parser.c.orig   2008-04-20 04:44:54.000000000 +0900
+++ src/parser.c        2008-09-23 17:16:15.000000000 +0900
@@ -132,8 +132,18 @@
 #define AGO 287
 #define INTERVAL 288
 
+#define USE_CP932
 
-
+#ifdef USE_CP932
+  #define UNKNOWN_STR    "UNKNOWN"
+  #ifndef FILESYSTEM_CES
+    #define FILESYSTEM_CES "CP932"
+  /*
+    #define FILESYSTEM_CES "UTF-8"
+    #define FILESYSTEM_CES "EUC-JP"
+  */
+  #endif
+#endif
 
 /* Copy the first part of user declarations.  */
 #line 1 "parser.y"
@@ -167,6 +177,11 @@
 #include <string.h>
 #include "playlist.h"
 
+#ifdef USE_CP932
+ #include <iconv.h>
+ #include <errno.h>
+#endif
+
 #define YYERROR_VERBOSE 1
 
 extern int yyerror(char *msg);
@@ -1828,6 +1843,43 @@
 
 
 #line 174 "parser.y"
+#ifdef USE_CP932
+#define MAX_ICONV_BUF 1024
+
+typedef enum {
+  ICONV_OK,
+  ICONV_TRYNEXT,
+  ICONV_FATAL
+} iconv_result;
+
+static iconv_result do_convert(const char* to_ces, const char* from_ces, 
+                              char *inbuf,  size_t inbytesleft,
+                              char *outbuf_orig, size_t outbytesleft_orig) {
+  size_t rc;
+  iconv_result ret = ICONV_OK;
+
+  size_t outbytesleft = outbytesleft_orig - 1; 
+  char* outbuf = outbuf_orig;
+
+  iconv_t cd  = iconv_open(to_ces, from_ces);
+  if (cd == (iconv_t)-1) {
+    return ICONV_FATAL;
+  }
+  rc = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
+  if (rc == (size_t)-1) {
+    if (errno == E2BIG) {
+      ret = ICONV_FATAL;
+    } else {
+      ret = ICONV_TRYNEXT;
+      memset(outbuf_orig, '&#92;&#48;', outbytesleft_orig);
+    }
+  }
+  iconv_close(cd);
+
+  return ret;
+}
+#endif
+
 
 PL_NODE *pl_newintpredicate(int tag, int op, int value) {
     PL_NODE *pnew;
@@ -1867,7 +1919,25 @@
     pnew->op=op;
     pnew->type=T_STR;
     pnew->arg1.ival=tag;
+#ifdef USE_CP932
+    if (!strcasecmp(FILESYSTEM_CES, "UTF-8")) {
     pnew->arg2.cval=value;
+      } else {
+       char* iconv_buf = (char*)calloc(MAX_ICONV_BUF, sizeof(char));
+       if (iconv_buf) {
+         iconv_result rc = do_convert("UTF-8", FILESYSTEM_CES, value, strlen(value), 
+                                      iconv_buf, MAX_ICONV_BUF);
+         if(rc == ICONV_OK) {
+           pnew->arg2.cval = iconv_buf;
+         } else {
+           pnew->arg2.cval = strdup(UNKNOWN_STR);
+           free(iconv_buf);
+         }
+       }
+      } // if utf-8
+#else
+    pnew->arg2.cval=value;
+#endif
     return pnew;
 }

こけるのは#ifdef USE_CP932から#endifまでなので、まぁ手動で当てても特別問題はないだろう。あとは普通にconfigureしてmake && make installなんだが。このままだと/etc/init.d/mt-daapdが使えないので、適当に以下のように編集する。

PIDFILE="/var/run/mt-daapd.pid"
CONFFILE="/etc/mt-daapd.conf"

depend() {
    need net
    need mDNSResponderPosix
}

start() {
    ebegin "Starting mt-daapd DAAP server"
    /usr/sbin/mt-daapd -c ${CONFFILE} &
    eend $?
}

stop() {
    ebegin "Stopping mt-daapd DAAP server"
    kill `cat ${PIDFILE}`
    eend $?

    rm -f ${PIDFILE}
}

とりあえず今あるものを共有する、という意味ではこれで万事よいのだが、俺の環境ではまだ問題があった。実は外付けHDDは元々Windowsで使っていたものなので、当然フォーマットはNTFS。でもmountしてるのはGentooなわけなので、普通にmountしたのではどうがんばってもリードオンリーになってしまう。これでは新しく曲を追加したり出来ない訳で、これは困る。メインはMacBookなので、samba経由で書き込めないと困ってしまう訳だ。色々試行錯誤したんだけど、ntfs-3gとかいうのを使ったらすげーあっさりと書き込みできるようになった。

sudo emerge ntfs3g
sudo update-modules
sudo su -
echo "/dev/sdb5   /mnt/usbhdd ntfs-3g    noauto,users,umask=000,iocharset=utf8 0 0" >> /etc/fstab
logout
sudo mount  /dev/sdb5 /mnt/usbhdd

あとは/etc/mt-daapd.confで、rescan_intervalを適当な値に設定しておいてやればok。