2012年8月26日日曜日

AndroidとPC(Winamp)の楽曲同期

AndroidとPC(Winamp)の楽曲プレイリスト同期に手こずった記録です。

前提

  • 自宅では楽曲ファイルの再生とプレイリスト管理をWindows PC上のWinampで行う
  • 楽曲ファイルはすべてUbuntu PCに保存されていて、Windows PCからはsamba経由でアクセス
  • 外出時にはAndroid (NEC N-01D) で音楽を聴く

やりたいこと

  • Winampの任意のプレイリストのファイルをAndroidで同期・聴けるようにしたい
  • 対象のプレイリストは時々更新するので出来る限り手軽に同期したい
  • USBケーブルでPCとAndroid機を繋ぐのはめんどくさいのでWi-Fiで済ませたい

まずはWinampの世界で


Android版Winampを使えばWi-Fi経由で任意のプレイリストを同期できるらしい! 素敵!

  • PCのWinampからAndroidデバイスが見つからない
    1. とりあえずUSBで繋いでみると当然見つかります
    2. 無線LAN接続のノートPCのWinampからもOK(・∀・
    3. 有線LANで接続されたPCから無線LAN接続のAndroid機は見つけられない……?
    4. ルーターが無線LANポートへのマルチキャストパケットの転送を制限していたので解除
    5. 同期できた!(・∀・
  • 文字化け
    • 同期できた楽曲をAndroidで見るといくつか文字化けが見つかる
    • Webで検索したら、ID3タグがUnicode系でないとAndroidでは文字化けするという情報多数
    • ID3Uniで全部Unicode化
    • だいぶ改善されました。が、まだ文字化けしている楽曲が残っています…
  • ファイル名が文字化け or 失われる
    • ファイル名が失われていた
    • Winampは転送時にファイル名の変更をしている?
    • ダメなファイル名の特徴を調べればわかるかもしれませんがここで気力が尽きました
  • Wi-Fiでの転送が不安定
    • 同期中に途中で通信が切れる
    • 症状は、Android側のWinampがクラッシュするか、Wi-Fi接続が切れる
    • どちらが発生するかは不定

…Winampの世界で完結させるのは諦めることにしました。


次の戦略 - rsync backup for android で同期

  1. WinampからプレイリストをM3U形式で出力
    • Winampのプレイリストビューで保存(Ctrl+S)するだけです
  2. Ubuntu PCでM3Uを解釈して必要な楽曲ファイルのシンボリックリンクを同期用フォルダに作る
    • 同期用フォルダには、楽曲フォルダのツリーをそのままコピーして、必要なファイルのみシンボリックリンクを作ります
    • cronで固定のパスのm3uを読み、実行
  3. rsync backup for android で同期
    • シンボリックリンクを解決してコピーする設定

M3Uを解釈して同期用フォルダを構築
  • Winampが吐き出すM3Uは次の通りということにしています。
    • Shift-JIS (CP932)
    • '#' から始まる行以外がファイルのリスト
  • 波ダッシュ問題
  • ファイルパスと正規表現
    • '/' で囲むとわけわかんなくなります。
    • '|' がいいと思います。
#!/bin/bash

if [ ! -f "$1" ]; then
  echo "no playlist is specified."
  exit
fi

WINDIRARR=(S:/sound/ T:/sound2/)
SRCDIRARR=(/home/library/sound1/ /home/library/sound2/)
OUTDIRARR=(/home/users/android-rsync/data/1/ /home/users/android-rsync/data/2/)
TMPFILE=$1.tmp

for (( i = 0; i < ${#OUTDIRARR[*]}; i++ )); do
  find ${OUTDIRARR[$i]} -type l -exec rm {} \;
done

sed -e 's|\\|\/|g' $1 > $TMPFILE

while read LINE; do
  LINE=`echo $LINE | nkf --ic=CP932 --oc=UTF-8 | sed 's|\\s*$||g'`
  
  if test 0 -ne ${#LINE} && ! echo $LINE | grep -sq '^#'; then
    RELPATH=$LINE
    for (( i = 0; i < ${#WINDIRARR[*]}; i++ )); do
      WINDIR=${WINDIRARR[$i]}
      SRCDIR=${SRCDIRARR[$i]}
      OUTDIR=${OUTDIRARR[$i]}
      RELPATH=`echo "$LINE" | perl -pe "s|$WINDIR||i"`
      if [ "$LINE" != "$RELPATH" ]; then break; fi
    done
    
    if [ "$LINE" != "$RELPATH" ]; then
      RELDIR=${RELPATH%/*}
      if [ ! -d "$OUTDIR$RELDIR" ]; then mkdir -p "$OUTDIR$RELDIR"; fi
      ln -s "$SRCDIR$RELPATH" "$OUTDIR$RELPATH"
    else
      echo "ERROR: $RELPATH"
    fi
  fi
done < $TMPFILE

rsync backup for android
  • Ubuntu側にコレ専用のユーザを作り、鍵を登録します
    •  鍵は rsync backup for android で作ったものを使います
  • Additional rsync options
    • 同期方向は Ubuntu→Android への一方通行になるように設定
    • シンボリックリンクを解決してコピー
      • -l    copy symlinks as symlinks    ←初期状態ではこちら
      • -L    transform symlink into referent file/dir    ←これに変更
Rescan Media
  • Androidはメディアストレージサービスというプロセスでプレイリストを管理しています。
  • 通常はOS起動時やストレージのマウント時にスキャンしてプレイリストを構築するらしいです。
  • なので rsync で引いてきただけでは楽曲はプレイリストに入りません。
  • メディアストレージサービスのスキャンを手軽に手動実行できるのがこのアプリ。
  • 初回起動時は "Auto quit?" が off になっています。チェックをONにしたあと手動でアプリケーションを明示的に終了させないと、2度目以降rescanされていないようでした。
  • アプリを起動したタイミングでrescanが実行されるのかな?

他の戦略 - FUSE


シンボリックリンクではなく Filesystem in Userspace(FUSE) がいいのでは? というアドバイスも貰いました。FUSEというものは知らなかったのですが面白そうです。

0 件のコメント:

コメントを投稿