
Ubuntu日本語フォーラム

ログインしていません。
こんにちは.初めて質問を投稿します.
重複したファイル名のmp3データを,RhythmboxでiPodに転送しようとするとエラーが出ました.
重複したファイル名のmp3データとは,例えば
/home/username/ミュージック/AAAAA/Track01.mp3
と
/home/username/ミュージック/BBBBB/Track01.mp3
などのようなファイルです.
エラー症状は,「"Track01.mp3" というファイルを上書きしますか?」というダイアログです.
iPodに曲を転送している最中にこのダイアログが出て止まってしまいます.
ファイル名が重複しているからこのエラー(ダイアログ)が出てしまったのでしょう.
しかし,ファイル名が重複していなくても同様の症状が出ることがあります.
「あああ.mp3」というmp3データをiPodに転送すると,「___.mp3」のように,
日本語部分が「_」に変換されたものがiPodに転送されてしまいます.
だから,「あああ.mp3」と「いいい.mp3」を転送しようとすると,両方とも「___.mp3」
になって結局ファイル名が重複し,同様の症状が発生します.
シェルスクリプトを使い,拡張子の前に乱数を付けて,
「Track01_cj0j0i5u.mp3」,「Track01_2rk2h93g.mp3」のようにしてファイル名の重複を
避けて,とりあえずこのエラーを回避できました.
質問は2つあります.
1.ファイル名に乱数をくっ付けるという方法以外に,この問題を回避する方法はありますか?
2.日本語ファイル名を転送する時の挙動を変更することはできますか?
環境
•Ubuntu 9.10 Desktop x86版
•Rhythmbox 0.12.5
•Apple iPod classic 80GB
以上です.よろしくお願い致します.
オフライン
同バージョンのRhythmboxでiPod Touchに「あああ.mp3」と「いいい.mp3」を入れたところ、ファイル名はともに「___.mp3」になったのですが、それぞれ別ディレクトリに保存されました。「iTunes_Control/Music/F27/___.mp3」、「iTunes_Control/Music/F44/___.mp3」という感じです。
iPod classicではどのような場所に保存されていますか。
オフライン
返信ありがとうございます.
> iPod classicではどのような場所に保存されていますか。
iPod classic でも「F27」のようなフォルダが作成されます.だから2曲程度なら
重複したファイル名のデータを転送してもエラーになりません.
しかし,フォルダ数に限界があるので,500曲ほど転送すると結局はエラーが出てしまいます.
> 「iTunes_Control/Music/F27/___.mp3」、「iTunes_Control/Music/F44/___.mp3」という感じです。
この問題には関与していないと思いますが,私の環境では,「iPod_Control/Music/F27/___.mp3」のような感じでした.
オフライン
iPodプラグインのソースを読んだところ、ascii以外の文字は「_」で置換するようになっていました。
この付近のソースを改造し、名前を乱数にする仕様にすれば重複回避が出来るっと思いますが、…
開発者にバグとして報告したほうがいいかな。
オフライン
http://www.tuaw.com/2005/10/21/terminal-tips-the-ipods-file-structure/
http://old.nabble.com/Syncing-problems-td6557940.html
本家iTunesだと「iPod_Control/Music/F49/AMOB.mp3」のようになり,
GTKPodだと「iPod_Control/Music/F49/gtkpod527817.mp3」のようになるみたいです.
RhythmboxだとiPodに転送した後でもファイル名から曲名が推測できるのが利点です.
でも転送エラーが発生するぐらいならiTunesのように 大文字英字*4 の乱数でもよい気がしますが.
# その仕様だと (26^4) * 50 = 22848800 ≒ 2300万 曲ぐらい転送するとファイル名が
# 重複し始めますがそんなに転送する人はいないでしょうし.
ここら辺の判断はソフトの開発者に任せおきましょうか.
とりあえずシェルスクリプトで乱数を付ける方法で凌ぐことにします.ありがとうございました.
オフライン
> iPodプラグインのソースを読んだところ、ascii以外の文字は「_」で置換するようになっていました。
iPodプラグインのソースコードはどこで入手できますか?
適当に改造して自分用に使おうと思うのですが.
オフライン
次を端末内で実行することで、カレントディレクトリにダウンロード出来ます。
apt-get source rhythmbox
また、コンパイルの為に以下を実行して必要パッケージをインストールしてください。
sudo apt-get build-dep rhythmbox
プラグインは「.../plugins/ipod」内と思われますが、gnome独自の型や関数があるようなので注意してください。例:gchar≈char?(gnome関係の開発よく分からないので…)
成功することを期待しております。
オフライン
ありがとうございます.
plugins/ipod/rb-ipod-source.c の
static gchar * generate_ipod_filename (const gchar *mount_point, const gchar *filename)
あたりですかね.
この関数内に
/* FIXME: should create a unique filename */
って書いてあるぐらいだから開発者もこの問題には気づいていたみたいですね.早速FIX.
オフライン
とりあえずできました.iPod内のファイル名は 英大文字乱数8桁.拡張子 になります.
初心者丸出しの汚いコードですが,使いたい人は
rhythmbox-0.12.5/plugins/ipod/rb-ipod-source.c の中の同名の関数を上書きしてください.
インストール方法はよく分からなかったので無理矢理 make install してコピーしましたがもっといい方法があるはず.
diffとか使ったことないのでソース直で.
static gchar *
generate_ipod_filename (const gchar *mount_point, const gchar *filename)
{
gchar *ipod_filename = NULL;
gchar *pc_filename;
gchar *tmp;
gint tries = 0;
gint i;
/* Make a random file name */
pc_filename = g_malloc (sizeof (gchar) * 20);
for (i = 0; i < 20; i++)
pc_filename[i] = '\0';
for (i = 0; i < 8; i++)
pc_filename[i] = 'A' + g_random_int_range (0, 26);
strcat (pc_filename, strrchr (filename, '.'));
g_assert (g_utf8_validate (pc_filename, -1, NULL));
/* Now we have a random filename, try to find out where to put
* it on the iPod
*/
do {
g_free (ipod_filename);
ipod_filename = get_ipod_filename (mount_point, pc_filename);
tries++;
if (tries > MAX_TRIES) {
break;
}
} while ((ipod_filename == NULL)
|| (g_file_test (ipod_filename, G_FILE_TEST_EXISTS)));
g_free (pc_filename);
if (tries > MAX_TRIES) {
/* FIXME: should create a unique filename */
return NULL;
} else {
return ipod_filename;
}
}g_mallocがあってg_callocが無いのにはびっくり.それとこの関数の上の方にある
suffix = g_random_int_range (0, 49);
はバグなのか仕様なのか.これじゃF49フォルダに何も入らないから(0, 50)のほうがいいような.
オフライン
どうも有り難うございます。
ちょっとした提案ですが、生成したファイル名が既存のものと衝突してしまった場合の為に、存在確認を行う処理を入れた方がいいかもしれません。
ファイルの正しい存在確認方法がよく分からないので、fopenの戻り値で調べる(セコイ?)やり方でいいでしょうか。
/* Make a random file name */
pc_filename = g_malloc (sizeof (gchar) * 20);
do {
for (i = 0; i < 20; i++)
pc_filename[i] = '\0';
for (i = 0; i < 8; i++)
pc_filename[i] = 'A' + g_random_int_range (0, 26);
strcat (pc_filename, strrchr (filename, '.'));
g_assert (g_utf8_validate (pc_filename, -1, NULL));
/* Now we have a random filename, try to find out where to put
* it on the iPod
*/
do {
g_free (ipod_filename);
ipod_filename = get_ipod_filename (mount_point, pc_filename);
tries++;
if (tries > MAX_TRIES) {
break;
}
} while ((ipod_filename == NULL)
|| (g_file_test (ipod_filename, G_FILE_TEST_EXISTS)));
} while(fopen(ipod_filename, "rb") == NULL);オフライン
ファイル名が被り始めるのは10.4兆曲ぐらいからなのでエラー処理は入れるか入れないか悩んでいたのですが,
入れてくださったのですね.ありがとうございます.
ファイルの存在確認方法はstat()という関数を使えばよいらしいのですがfopen()が一番わかりやすくていいのかもしれません.
こういう場合はfclose()は必要無いんでしたっけ?C言語は普段全く書かないからよく理解していないのですが.
GLibを扱ったのは今回が初めてなのですが,関数名の初めには「g_」を付けるべきなのか
そうでないのかなど,まだまだわからないことだらけで書いたものなのでこのプログラム非常に怪しいです.
あとpc_filenameという変数にはもうpcのfilenameが入ることは無いので,
変数名をrandom_filenameなどに変えておくといいかもしれません.
オフライン
#10のコードですが、これでは無限ループに入ってしまいます。条件式が逆でした。
bigmound による投稿:
こういう場合はfclose()は必要無いんでしたっけ?
必要なはずです、忘れてました。
そういえばtriesやMAX_TRIES関連がナゾなんですけど、何でしょうね。
static gchar *
generate_ipod_filename (const gchar *mount_point, const gchar *filename)
{
gchar *ipod_filename = NULL;
gchar *rand_filename;
gchar *tmp;
gint tries = 0;
gint i;
FILE *fp;
/* Make a random file name */
rand_filename = g_malloc (sizeof (gchar) * 20);
for (;;) {
for (i = 8; i < 20; i++)
rand_filename[i] = '\0';
for (i = 0; i >= 7; i++)
rand_filename[i] = 'A' + g_random_int_range (0, 26);
strcat (rand_filename, strrchr (filename, '.'));
g_assert (g_utf8_validate (rand_filename, -1, NULL));
/* Now we have a random filename, try to find out where to put
* it on the iPod
*/
do {
g_free (ipod_filename);
ipod_filename = get_ipod_filename (mount_point, rand_filename);
tries++;
if (tries > MAX_TRIES) {
break;
}
} while ((ipod_filename == NULL) || (g_file_test (ipod_filename, G_FILE_TEST_EXISTS)));
/* If ipod_filename already exist, re-create a random filename. */
fp = fopen(ipod_filename, "rb");
if(fp == NULL)
break;
fclose(fp);
}
g_free(rand_filename);
if (tries > MAX_TRIES) {
return NULL;
} else {
return ipod_filename;
}
}パッケージ化したいのであれば、端末でrhythmbox-0.12.5に入り、以下を実行してください。上位ディレクトリにdebファイルが作成されます。
dpkg-buildpackage -rfakeroot -uc -b
オフライン
何度もすみません。
コード15行目
for (i = 0; i < 8; i++)
としておいてください。
オフライン