◆aacのアートワーク存在チェックツール(m4a解析ソース付き)

 アートワーク一括チェックツール

フォルダ下の全てのaac/alac楽曲ファイル(.m4a)をチェックし、アートワークを持たない楽曲をリストアップするツールを作成しました。

minidlaのCソースをJavaにしたものです。

m4aのタグに関する仕様はまだ調べつくしていませんので、今回はソースのコンバートで対処しました。

実際にツールを動かした結果を示します。行が多いので省略しています。

Check G:\MUSIC
...........................................................
B-    >Beethoven >チェロ・ソナタ全曲、「魔笛」の主題による変奏曲;Anner Bylsma, Jos Van Immerseel >Beethoven: Cello Sonata #3 In A, Op. 69 - 2. Scherzo: Allegro Molto  has no image
B-    >Beethoven >チェロ・ソナタ全曲、「魔笛」の主題による変奏曲;Anner Bylsma, Jos Van Immerseel >Beethoven: Cello Sonata #3 In A, Op. 69 - 3. Adagio Cantibile  has no image
・・・省略 ・・・
B-    >Beethoven >チェロ・ソナタ全曲、「魔笛」の主題による変奏曲;Anner Bylsma, Jos Van Immerseel >Beethoven: Cello Sonata #5 In D, Op. 102/2 - 3. Allegro Fugato  has no image
B-    >Beethoven >チェロ・ソナタ全曲、「魔笛」の主題による変奏曲;Anner Bylsma, Jos Van Immerseel >Beethoven: 12 Variations On "Ein Madchen Oder Weibchen" In F, Op. 66  has no image
.................
V-    >Vivaldi >Classic On Bossa *Vivaldi* >ヴァイオリン協奏曲”四季”より(春)第2楽章  has no image
V-    >Vivaldi >Classic On Bossa *Vivaldi* >ヴァイオリン協奏曲”四季”より(春)第3楽章  has no image
・・・省略 ・・・
V-    >Vivaldi >Classic On Bossa *Vivaldi* >ヴァイオリン協奏曲”四季”より(冬)第3楽章  has no image
........................
H-    >Haydn >弦楽四重奏曲集 op.33 (全6曲) & op.42 < Buchberger Quartet > ;Buchberger Quartet >Haydn / SQ 39 C-dur op.33 - 3 1. Allegro moderato  has no image
・・・省略 ・・・
H-    >Haydn >弦楽四重奏曲集 op.33 (全6曲) & op.42 < Buchberger Quartet > ;Buchberger Quartet >Haydn / SQ 43 d-moll op.42 4. Finale : presto  has no image
........
S-    >Schubert >交響曲 5番、6番;Colin Davis; Staatskapelle Dresden >Schubert: Symphony #5 In B Flat, D 485 - 2. Andante Con Moto  has no image
・・・省略 ・・・
S-    >Schubert >交響曲 5番、6番;Colin Davis; Staatskapelle Dresden >Schubert: Symphony #6 In C, D 589 - 4. Allegro Moderato  has no image
................................
・・・省略 ・・・
.............
file-count   : 15156
image-lacked : 255
total-length : 5774749770 bytes 5507 MB
続行するには何かキーを押してください . . .

少しはあると思っていたのですが想像以上でした。
これらはアルバムの先頭にのみアートワークが設定されていて、アルバム一覧では気が付きませんでした。

 発見された楽曲の対処

アルバムの情報-「アートワーク」で画像を選択し、コントロールC、その場でコントロールV,[OK]で先頭以外の楽曲にも大概の場合アートワークが設定されます。

しかしながら、アルバム設定ではだめな場合もあり、その場合は、複数の曲情報を選択し、アートワークを一括設定する必要があります。
アートワークが先頭のファイル以外にも入っている場合、入っていないファイルは「あえて入れていない」と判断されるのかも知れません。

 タグチェック・ツールのソース

ソースを示します。
汎用AACタグ解析クラス(AacTagUtil.java)とそれを使ってimage(covr:カバーアートタグ)を持たない楽曲の情報を表示するmainクラス(AudipTagChk.java)です。
画像部のチェック(JPEG-BASE_LINEまたはPNGか)も ◆JPEGのbaseline判定ツール(jpeg構造解析ソース付き)のJpgBLineChkクラスを用いて行っています。

mp3も解析するつもりです。ただ現時点ではiTunes管理の膨大なaac(m4a)の検証が必要で、この段階で提示(メモ書き?)することにしました。

このツールは起動引数としてフォルダを指定すると階層を追って全ファイルをチェックするようになっています。
aac以外のファイルが混ざっていてもはじくようにはしてあるます。

AacTagUtil.get_aactags()はタイトルを始めとして多くの情報を返します。
AudioTagChk.hasArtWork()では情報の中のimage_sizeが0のものをアートワーク欠落としてレポートしています。
レポートの形式はグループ>アルバム・アーティスト>アルバム>タイトルの順としていますが、 必要に応じソースを変更してください。

 ソースのダウンロードとビルド/起動

checkAudioTag.zip には実行可能jarと実行用のバッチ、ソースコード、ビルド用のバッチを入れてあります。

Java8環境が必要です。

A05_run.batのDIR変数にチェックしたいフォルダをセットし実行してください。
オプションの-aはartistタグとalbum artistタグの両方を持っているかをチェックし、-pは画像がjpeg:base_lineかpngであるかをチェックします。

:: A05_run.bat
@echo off
set DIR=G:\MUSIC
set OPTION=-a -p
set MAIN=AudioTagChk
set JAVA=java.exe
"%JAVA%" -jar %MAIN%.jar %OPTION% %DIR%
pause

プログラムを変更した場合は、 A01_build.batを動かすとりビルドされます。

| | トラックバック (0)

◆JPEGのbaseline判定ツール(jpeg構造解析ソース付き)

 JPEGベースライン形式とプログレッシブ形式

JPEGにはベースライン形式とプログレッシブ形式があります。

同じJPEGでも必ずしも全てのプログラムが取り扱える訳ではなく、例えばSONYのwalkmanではアートワーク画像がベースライン形式のJPEGまたはPNGである必要があり、プログレッシブ形式のJPEGの場合表示することが出来ません。

JPEG画像がベースラインかプログレッシブかを確かめる単純なツールを作成しました。PGNの判別もします。

jpgBLineChk.zip をダウンロードし、展開後、A05_run.batを起動すれば、Pictureフォルダ内のファイルをチェックし、ファイル名の後にPROGRESSIVEかBASE_LINEかを示します。1行に1ファイル、で複数行になります。 (JAVA8の実行環境が必要です)

mull.png: PNG
R-1000405-1202393759_jpeg.jpg: PROGRESSIVE
R-3344447-1326656338_jpeg.jpg: BASE_LINE
zamp27.png: PNG
四季 _I MUSICI 1.jpg: BASE_LINE

◇iTunesのアートワークをAAC(.m4a)ファイルに含めるネットから画像を拾って設定 作業ではとても重宝しました。殆どはBASE_LINEですが、たまにPROGRESSIVEがあります。

単純なものですのでソースコードを提示します。

 JPEGベースライン形式判定ツール

JPEGは次の形式をしています。

SOIは0xFFD8、EOIは0xFFD9です。
セグメントは先頭に0xFF、次に1バイトのセグメント種別が続き、その後ろに2バイトの長さ情報があります。長さ情報の後ろに「長さ情報-2」バイトの内容が置かれます。
SOIの後、複数のセグメントがあり、最後がSOSセグメントとなります。SOSセグメントの後ろには画像データがあります。 画像データは長さデータで修飾されておらず、内容を解析しないと終端は分かりません。
画像データの後ろにEOIが置かれますが現実的には意味を持ちません。

セグメント種別でベースライン、プログレッシブの判断ができます。

0xC0 : ベースライン
0xC1 : シーケンシャル
0xC2 : プログレッシブ
0xC3 : 可逆DPCM

これ以外にも多くのセグメントがありますが、他は無視します。

プログラムはSOIを確認後、セグメント単位で読み飛ばしながら、0xC0~0xC1のセグメント出現で判断し、結果を戻します。

// JpgBLineChk.java
import java.io.*;
public class JpgBLineChk {
   final static boolean D=false;// デバグフラグ
   public enum Type{
       BASE_LINE,
       SEQUENCIAL,
       PROGRESSIVE,
       DCPM,
       PNG, // JPEGではないがチェックする
       UNKOWN
       };
   public static Type getType(BufferedInputStream bis_)throws Exception{
      byte[] _buf2 = {0,0};     // SOI取得用
      byte[] _buf4 = {0,0,0,0}; // SEGMENTマーカーと長さ取得用
      // SOIの確認
      if( bis_.read(_buf2)!=2 ) return Type.UNKOWN;
      if( (_buf2[0]&0xff)!=0xFF || (_buf2[1]&0xff)!=0xD8 ){
         // PNGか調べる
         if( (_buf2[0]&0xff)==0x89 && (_buf2[1]&0xff)==0x50 ){
            byte[] _buf6={0,0,0,0, 0,0};
            if( bis_.read(_buf6)!=6 ) return Type.UNKOWN;
            if(   (_buf6[0]&0xff)==0x4E && (_buf6[1]&0xff)==0x47 
                &&(_buf6[2]&0xff)==0x0D && (_buf6[3]&0xff)==0x0A 
                &&(_buf6[4]&0xff)==0x1A && (_buf6[5]&0xff)==0x0A  ){
               return Type.PNG;
               }
            }
         return Type.UNKOWN;
         }
      while(true){
         // セグメントマーカー確認
         if( bis_.read(_buf4)!= 4  ) return Type.UNKOWN;
         if( (_buf4[0]&0xff)!=0xFF ) return Type.UNKOWN;
         long _slen = (long)(((_buf4[2]&0xFF)<<8)+(_buf4[3]&0xFF)-2);
         if(D) System.out.printf("SEGMENT:%02x%02x len:%d\n"
                                ,_buf4[0],_buf4[1],_slen);
         switch( _buf4[1]&0xff ){
         case 0xC0: return Type.BASE_LINE;
         case 0xC1: return Type.SEQUENCIAL;
         case 0xC2: return Type.PROGRESSIVE;
         case 0xC3: return Type.DCPM;
         case 0xDA: return Type.UNKOWN;//SOS(この後ろはSEGMENTではない)
            }
         // セグメント読み飛ばし
         long _len;
         while( _slen>0 && ((_len=bis_.skip(_slen))!=-1) ) _slen -= _len;
         }
      }
   public static Type getType(File file_)throws Exception{
      try(BufferedInputStream _bis = new BufferedInputStream(
                                       new FileInputStream(file_));){
         return getType(_bis);
         }
      }
   public static void main(String[] args_){
      for(String _arg:args_){
         try{
            File[] _files= new File(_arg).listFiles();
            if( _files!=null ){
               for(File _file:_files){
                  try{
                     System.out.println(_file.getName()+": "
                                        +JpgBLineChk.getType(_file));
                     }
                  catch(Exception _ex){
                     System.out.println(_ex);
                     }
                  }
               }
            }
         catch(Exception _ex){
            System.out.println(_ex);
            }
         }
      }
   }

このプログラムでは先頭が0xFFD8でない場合補足的にPNGではないかのチェックも行っています。

main部はコマンド引数としてフォルダ名を受け、フォルダ内のファイルに関してチェックを行い結果を表示するものとなっています。

補足:
 _bis.read(_buf)は長さ分読むのでくりかえしの必要はありません。
 _bis.skip(_skip)は短い場合もあるので繰り返さなくてはなりません。
 _bis.skip(_skip)は最後まで到達した後は-1を返します。

 実行バッチ

実行用のバッチファイルA05_run.batは次のようになっています。

 実行用バッチ

:: A05_run.bat
@echo off
set DIR=%UserProfile%\Pictures
set MAIN=JpgBLineChk
set JAVA=java.exe
"%JAVA%" -cp . %MAIN% %DIR%
pause

この例では変数DIRにユーザのMyPictureフォルダを与えています。
この部分を必要に応じ変更してください。

 実行例

実行例を示します。(長いので一部抜粋)

71mnczFjxrL__SL1200_.jpg: BASE_LINE
81UnrBT5hgL__SL1200_.jpg: BASE_LINE
91jo6WhblIL__SL1418_.jpg: BASE_LINE
desktop.ini: UNKOWN
mull.png: PNG
R-1000405-1202393759_jpeg.jpg: PROGRESSIVE
R-3344447-1326656338_jpeg.jpg: BASE_LINE
R1202393759.jpg: PROGRESSIVE
R12_baseline.jpg: BASE_LINE
zamp27.png: UNKOWN
四季 _I MUSICI 1.jpg: BASE_LINE
惑星 _Previn_Royal Phil.Orc..jpg: BASE_LINE
無題.png: PNG
続行するには何かキーを押してください . . .

これらは先の記事 ◇iTunesのアートワークをACC(.m4a)ファイルに含める の「ネットから画像を拾って設定」でiTunesを介してwalkmanに設定したアートワークファイルです。

赤がwalkmanでアートワーク表示できなかったファイル青はPhotoShopでBASE_LINEに変換保存しwalkmanで表示できるようになったファイルです。

 ソースと再ビルド

jpgBLineChk.zip にはソースコードとビルド用のバッチも入れてあります。

Java8の実行環境が必要です。

JDK8以降があれば、ソースに変更を加えて再ビルドすることができます。

 ビルド用バッチ

:: A01_build.bat
@echo off
set SRCS=JpgBLineChk.java
set JAVAC=javac.exe
"%JAVAC%"  -Xlint:unchecked -encoding utf8 %SRCS%
if ERRORLEVEL 1 goto ERR
echo === OK ===
goto END
:ERR
echo === SOME ERROR OCCURED ===
:END
pause

 クリア用バッチ(の見本)

:: A00_clear.bat
del /q *.class > NULL 1>&2
pause

| | コメント (0) | トラックバック (0)

◆iTunes⇒walkman楽曲転送ツール

 iTunes管理の曲情報をwalkmanに同期/転送するツール

iTunesで管理している曲をwalkmanで聴くために、これまでMusicCenterForPCというソフトを利用しようとしてきました。

残念ながらこのMusicCenterForPCはバグも多く、転送失敗や楽曲重複、プレイリストがうまく取り込めないことがあるといった問題があります。
なによりiTunes上で変更があった場合反映させるのが大変です。

そこでiTunes->walkman転送専用ソフト(i2wSD)を自作しました。

i2wSDは最初にiTunesのライブラリ情報ファイルを読み込み情報を解析します。
ライブラリ情報はデフォルトでは「ミュージック/iTunes/iTunes Music Library.xml」が用いられます。
(「ファイル」⇒「ライブラリ」⇒「ライブラリのエクスポート」で生成したファイルでも構いません)
その情報から楽曲ファイルの保存フォルダを特定し、そのフォルダ全体、または楽曲ファイルごとにWalkman用のSDにデータを転送します。
プレイリストもこのライブラリ情報から取得し、walkman用に生成します。
SD上にファイルが既存の場合、更新時刻とサイズのチェックを行い、必要な場合のみ上書きを行います。

動かした結果の表示情報を示します。walkmanのSDに楽曲ファイルが転送され、問題なく再生できました。

-- 情報 --
iTunes MusicFolder              = D:/iTunes/Music/
ライブラリ情報中の楽曲数        = 15467
見つからなかったファイル数       = 5
重複するファイル数               = 13
重複するため転送しないファイル数 = 13
有効な楽曲ファイル数             = 15449
  .m4a AACオーディオファイル 44100hz/128bit : 14592
  .m4a AACオーディオファイル 44100hz/256bit : 393
  .m4a AACオーディオファイル 44100hz/320bit : 431
  .m4a Appleロスレス・オーディオファイル 44100hz : 31
  .m4a Appleロスレス・オーディオファイル 96000hz : 2
有効楽曲ファイルの総サイズ       = 76198998280bytes (70.97GB)
有効楽曲ファイルの総演奏時間     = 50days 9:12:14
MusicFilder直下のフォルダ数      = 658
Playlist数                      = 21
Playlistに入れられた楽曲数      = 2980

ライブラリ読み込み所要時間 0:05.002

======= 作業開始 2018/10/22 14:56:29
転送 D:/iTunes/Music/ -> G:/MUSIC

*** 楽曲フォルダ転送 開始時刻 2018/10/22 14:56:29
削除されたSD上の楽曲ファイル数       = 0
削除されたSD上のプレイリスト数       = 0
重複回避のため削除したSDファイル数   = 0
既存のためスキップした楽曲ファイル数 = 0
重複回避のためスキップしたファイル数 = 13
転送した楽曲ファイル数               = 15461
*** 楽曲フォルダ転送 完了 所要時間   = 2:52:20.967
*** プレイリスト(m3u8)生成 開示時刻 2018/10/22 17:48:50
生成したプレイリストの数             = 21
*** プレイリスト生成完了 所要時間    = 0:05.859

======= 作業完了 2018/10/22 17:48:56  所要時間 2:52:26.857

フォルダを単純に転送するだけではiTunse上管理からもれたゴミファイルも転送されるかも知れないと心配したのですが、 管理している楽曲ファイル数(15452)と転送した楽曲ファイル数+重複数(15439+13=15452)は一致しました。

 iTunesライブラリ情報上の矛盾について

ライブラリ情報上にありながら、その実体がないものがあります。これはiTunesの何らかの障害のためだと思われます。

 iTunes上の楽曲修正と再転送

特に障害があるわけではないのですが、若干気持ち悪いiTunse上のデータ矛盾を無くすため、 重複やリンク情報(.xml上のLocation)の異常のあった5つのアルバムを置き換えました。

  • A161 Mozart:ピアノ協奏曲 1,2,3,4番 ;Perahia(Pf,Cond)/English Chamber Orc.
  • A159 Mozart:ピアノ協奏曲 5,6番 ;Brendel/Marriner/Academy of St.Martin
  • E072 Beethoven:交響曲 5番,6番;スクロヴァチェフスキー/ザールブリュッケン放送交響楽団
  • A207 Brahms:ブラームス:ハイドン変奏曲/エルガー:エニグマ変奏曲 他;ヨッフム、ロンドン、バイエルン
  • C021 ビートルズ:クラシカル ビートルズ ;アンサンブル SDR

先頭の4文字は管理用にふってあるもので、楽曲データではありません。

次の結果が得られます

-- 情報 --
iTunes MusicFolder              = D:/iTunes/Music/
ライブラリ情報中の楽曲数        = 15454
見つからなかったファイル数       = 0
重複するファイル数               = 0
重複するため転送しないファイル数 = 0
有効な楽曲ファイル数             = 15454
  .m4a AACオーディオファイル 44100hz/128bit : 14533
  .m4a AACオーディオファイル 44100hz/256bit : 393
  .m4a AACオーディオファイル 44100hz/320bit : 431
  .m4a Appleロスレス・オーディオファイル 44100hz : 95
  .m4a Appleロスレス・オーディオファイル 96000hz : 2
有効楽曲ファイルの総サイズ       = 77228069893bytes (71.92GB)
有効楽曲ファイルの総演奏時間     = 50days 10:4:35
MusicFilder直下のフォルダ数      = 657
Playlist数                      = 21
Playlistに入れられた楽曲数      = 2936

ライブラリ読み込み所要時間 0:05.616

======= 作業開始 2018/10/22 23:44:17
転送 D:/iTunes/Music/ -> G:/MUSIC

*** 楽曲フォルダ転送 開始時刻 2018/10/22 23:44:17
削除されたSD上の楽曲ファイル数       = 8
削除されたSD上のプレイリスト数       = 21
重複回避のため削除したSDファイル数   = 0
既存のためスキップした楽曲ファイル数 = 15397
重複回避のためスキップしたファイル数 = 0
転送した楽曲ファイル数               = 64
*** 楽曲フォルダ転送 完了 所要時間   = 2:52.825
*** プレイリスト(m3u8)生成 開示時刻 2018/10/22 23:47:12
生成したプレイリストの数             = 21
*** プレイリスト生成完了 所要時間    = 0:05.589

======= 作業完了 2018/10/22 23:47:18  所要時間 3:01.040

置き換えは全てAppleロスレスにしましたので、ファイルサイズが大きくなっています。
変更ファイルのみの転送ですので、所要時間は大幅に短くなっています(3時間->3分)

アルバムアーティスト名の変更などに伴いSDカード上にある古い名前のフォルダは削除されました。

-- エラー/警告 情報 --
delete file/folder on sd "Brendel_Marriner_Academy of St.Martin_"
delete file/folder on sd "Perahia(Pf,Cond)_English Chamber Orc._"
delete file/folder on sd "アンサンブル SDR"
delete file/folder on sd "アンサンブル SDR_"
delete file/folder on sd "オイゲン・ヨッフム_ロンドン交響楽団(1-24)、バイエルン放送交響楽団"
delete file/folder on sd "スクロヴァチェフスキー/ザールブリュッケン放送交響楽団"
delete file/folder on sd "ピアノ協奏曲 5,6番 _Brendel_Marriner_Academy of"
delete file/folder on sd "not in iTunes folder ピアノ協奏曲 1,2,3,4番 _Perahia(Pf,Cond)_Englis"

 iTunesの問題点

iTunesで見えない重複が有る場合、単純に削除しただけでは、見えなかったものが出てくるだけで、 削除がうまくできない場合があります。一旦削除した上でiTunesを起動しなおし、残っていれば再び削除します。
i2wSDを使い繰り返し[ライブラリ読み込み]を行い確認します。

iTunesのエクスポート情報は曲名によっては上手くいかない場合があるようです。

次の例ではLocation情報が欠落しています、曲名を日本語を使わないものに変更したところLocation情報が出るようになりました。

最初にAlbum名の日本語も外しましたが、Locationは欠落したままでした。

「交響曲第5番ハ短調 第1楽章 アレグロ・コン・ブリオ」の何が気に入らないのかは分かりません。

 トラック名の再取得

トラック名をCDDBから取得する場合日本語は避けた方が良さそうです。

取り込んだ後で自分で日本語に置き換えるのが、面倒でも安全です。

CDDBで希望しないものを選択してしまった場合、iTunes12の場合

  1. タイトルを全部選択する
  2. 「ファイル」メニュー⇒「ライブラリ」⇒「トラック名を取得」
で選びなおすことができます。

 MusicCenterForPCとの共存

MusicCenterForPCにはiTunesの楽曲は一切入れず、Moraからダウンロードする楽曲だけを管理させ、walkmanに転送するとう使い方が(僕の環境では)現実的だともいます。

 i2wSDのダウンロードと使用法

i2wSDは次のアドレスからダウンロードできます。

i2w.zip

i2wSD.zipを展開し、

  • A05_run.bat
を起動すると、冒頭の画面が現れます。

Java8以上の環境が必要です。

XMLの解析のためDTD情報を取得します。
 "http://www.apple.com/DTDs/PropertyList-1.0.dtd"

使用法は最初の画面に出ます。

使用法
-- iTunesで ライブラリをエクスポート
   [編集]->[環境設定]->[詳細]
       iTunesライブラリXMLをほかのアプリケーションと共有
   [ファイル]->[ライブラリ]->[ライブラリを整理]
       (ミュージック)/iTunes/iTunes Music Library.xmlにエクスポートされる
-- walkmanで SDカード初期化(一度だけでよい)
   [設定]->[各種初期化]->[SDカード初期化]
-- 本プログラム
   iTunesでエクスポートされたファイルを 「iTunesのライブラリ.xml」 にドラッグ、または[参照]で設定
   SDを挿し、「sdのMUSICフォルダ」にSDのMUSICフォルダをドラッグ、または[参照]で設定
   [ライブラリ読み込み]
   [楽曲およびプレイリスト転送]
      SDカードのMUSICフォルダ内を削除した上で楽曲を転送しプレイリストを作成します
   [CANCEL]
      転送作業を中断します。ファイルが中途半端になりますので注意してください
      ファイルサイズをチェックしますので、再転送の場合は上書きされます
   [表示]
      進行表示⇒エラー/警告情報⇒情報⇒HELP順で表示を変更します
 設定補足:
  
  [SDのMUSICを一旦削除する] :onの場合SDのMUSICを一旦空にします
  [楽曲情報を転送する]      :offにすると転送しません
  [Playlist(m3u8)を生成する]:offにすると生成しません
  [フォルダを単純コピーする]:onにするとMusicフォルダ内のファイルを単純コピーします
                             offの場合はライブラリ情報に基づき楽曲ファイルを転送します
  [iTunesにないファイルは..]:フォルダの単純コピーの場合、iTunesにないファイルはSDから削除します
  [更新時間とサイズをチェ..]:onにすると転送先の同名ファイルがiTunesのものより新しく
                             かつサイズが同じ場合転送しません
                             offの場合同名ファイルは上書きします
  [転送エラーが起こっても..]:onにすると場合画面にメッセージを出し、処理を続けます
                             offの場合エラーが発生すると処理を停止します
 楽曲ファイルが存在しない場合
  ライブラリ情報読み込み時に楽曲ファイルの有無をチェックします
  ライブラリ情報上のファイルが見つからない場合、フォルダ名を変えて調べます
  ファイルが存在しない場合、[ライブラリ情報によらず..]=off時の転送対象とはなりません

SD無しでiTunesのライブラリ情報のチェックだけを行うこともできます。

 i2wSDのリビルド

i2wSDはA01_build.batでリビルドできます。

用意されているi2wSD.jarが万が一異常を起こすようであれば、ソースi2wSD.javaを修正することができます。
ただしi2wSD.javaは増改築、その場その場での必要機能の追加/削除を行ったものであり、あまり美しくはありません。

 メモ

SDをwalkmanに挿すとデータベース生成が始まります。

計測したところ
 9分41秒
かかりました。

| | トラックバック (0)

◇MusicCenterForPC 2.0について

# 2018/12/01
Music Center for PC 2.0は結局使わず、iTunesフォルダとwalkman用SDのフォルダ同期を行うツールを自作しました。
◆iTunes⇒walkman楽曲転送ツール
これをきっかけにロスレス化やアルバムアートの追加、foobar2000とのデータ共用など多くの作業を行いました。
◆iPod-classicからwalkmanへ移行完了
そのため、本記事は余り意味を持たなくなってしまいましたが、一連の作業の始まりということで、しばらく消さずにおきます。



虫の大群に襲われた

 Music Center for PC 2.0 転送できない曲

Music Center for PC 2.0では iTunesのフォルダからwalkmanに転送できない曲があります。

Music Center for PC 1.0で楽曲を転送したwalkman(左)にはこの曲を含むアルバム(「メンデルスゾーン 交響曲2番"賛歌"」)は入っています。 2.0で転送したwalkman(右)には入っていません

 プレイリストはm3u8で

「M3Uファイル(*.m3u)」では日本語ファイル/フォルダが転送されないので注意。

iTunesからプレイリストを取り込むにはiTunesで

  1. プレイリストを選択する
  2. 「ファイル」メニュー
     ⇒ライブラリ
      ⇒プレイリストをエクスポート
       ファイルの種類「M3Uファイル(*.m3u8)」
とします。

SONYのページの説明ではm3uを指定することになっていますが、検証不足でしょう。

なおプレイリスト読み込みが失敗しても何のメッセージも出ません。
当初リスト内の一部のみ欠けてしまうので原因を調べるのに手間取りました。

 walkmanの全曲削除はwalkmanで

転送がうまくいかなかったのでMusicCenterforPCの機能でwalkman上の楽曲を削除しようとしたところ、 MusicCenterforPC表示が真っ白になったまま動かなくなってしまいました。
一晩そのままにしてみたのですが、変化がなくタスクマネージャで強制停止させました。
起動しなおし、再トライしましたが、同じ症状がでます。

walkmanでSDの初期化を行い、念のため工場出荷状態にして、再転送作業を行いました。
何度繰り返しても転送不能曲は転送不能のままです。

 MusicCenterを使わず直接SDカードに

転送できないのは次の3つのフォルダだけでした。 

D:\iTunes\Music\Wieland Kuijken(gamba),Gustav Leonhardt(\The 3 Sonatas for Viola da Gamba and Har

D:\iTunes\Music\Vladimir Ashkenazy _ Deutsches Symphonie\交響曲 2番_賛歌_ _Vladimir Ashkenazy _ Deutsch

D:\iTunes\Music\Robert Craft_London Symphony Orchestra\Five Pieces for Orchestra, A Survivor fr

このフォルダをwalkman用のsdカードにコピーしました。

G:\MUSIC\Wieland Kuijken(gamba),Gustav Leonhardt(\The 3 Sonatas for Viola da Gamba and Har

G:\MUSIC\Vladimir Ashkenazy _ Deutsches Symphonie\交響曲 2番_賛歌_ _Vladimir Ashkenazy _ Deutsch

G:\MUSIC\Robert Craft_London Symphony Orchestra\Five Pieces for Orchestra, A Survivor fr

walkmanにsdカードを戻すとデータベースが作り直され、無事楽曲は登録されました。もちろん再生も可能です。

プレイリストのファイル内容に関してはまだ調べていませんが、G:\MUSIC\上に並んでいました。多分変換が必要だとしても簡単なものでしょう。

次回は(あるは今後永遠に)MusicCenterを使わず楽曲転送を行うことになると思います。

 1.0と2.0のMUSICフォルダの違い

20018/10/19:追加

1.0と2.0ではSDカード上のMUSICフォルダ内の構成が異なることが分かりました。

  • 1.0:アーティストでまとめられる
  • 2.0:アルバムアーティストでまとめられる

1.0で作成したSD上に2.0で転送するのは危険かもしれません。

1.0で転送したMUSICフォルダ

2.0で転送したMUSICフォルダ

2.0で転送するとき「曲」の画面で全て選択とするか「アーティスト」の画面で全て選択するかによって変わるかと考えましたが、 どちらでも同じでした。
楽曲データの取り込みは「フォルダを指定して取り込む」形でどちらも同じです。

なお、2.0でのフォルダ管理はiTunesのフォルダ管理と同じになりますので、安心感があります。

と、思ったら

20018/10/20:追加

記号文字の取り扱いが違うようです。

iTunesのMusicフォルダ

先の例と比べると

iTunesMusicCenter
(D.F.O)(D_F_O)
A.Davis_BBC_Symp.OrcA_Davis_BBC_Symp_Orc

と、ドット(.)がアンダースコア(_)に置き換わっているのが分かります。

つまり、MusicCenterForPCによる転送と、手作業によるフォルダ転送を組み合わせるのは危険だということになります。

| | トラックバック (0)

緊急メモ:AndroidStudio3.2

 AndroidStudioがまた迷惑なバージョンアップ

AndroidStudioが3.2にバージョンupしこれまでのものが動かなくなりました。

プロジェクト1個をなんとか動作させましたが、同じ方法をとったはずの別プロジェクトは動作にいたりませんでした。

ここに書くのは正しい方法ではないかもしれませんが、忘れない内に書いておきます。

 モジュール定義が必要になりました。

モジュール定義が必要となりました。 モジュールが一体何なのかは今のところさっぱりわかりません。 JDK9で導入されたモジュールとはまたべつのもののようです。

モジュール作成手順は以下の通り。

Project/(プロジェクト)で右クリック
   [Module]
      ->「CreateNewModule(new Module」)窓が出る
         AndroidModuleを選択
            [Next]
              ->「CreateNewModule(AndroidLibrary)」窓が出る
                  [Finish]
                     ->「AddFilesToGit」が出る
                          [OK]

その上でモジュール参照指定を「Run」メニューから行います。

「Run」メニュー
   EditConfiguration
      ->Runウィンドウが出る
         Default
            AndroidApp
              Module選択で多分"app"がリスト内にある
               ("app"なんて名前はどこでも設定したつもりはないが)
              appを選択し[apply]
              [Close]

 Cannot set the value of read-only property 'outputFile'

このエラーは3.0でも出るやつです。対処法は「基本」は同じですが注意点があります。

Project/(プロジェクト)/app/src/build.gradle
applicationVariants.all { variant ->
   if (variant.buildType.name.equals("release")) {
      variant.outputs.all {
         def versionName = variant.versionName
         def date        = new java.text.SimpleDateFormat("yyyyMMdd_HHmmss")
                           .format(new Date())
         def newName     = "apk_v${versionName}_${date}.apk"
         outputFileName   = newName
         }
      }
   }
※:text.SimpleDateFormatの.で行を分割してはいけません
※:apk_vはそれぞれのAPPごとに設定

 Could not find com.android.tools.build:aapt2:3.2.

次の定義が必要です。

Project/(プロジェクト)/build.gradleに
buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.0'
    }
}
allprojects {
    repositories {
        google()
        jcenter()
    }
}
task clean(type: Delete) {
    delete rootProject.buildDir
}

前項とは別のbuild.gradleファイルであることに注意が必要です!!!

 Buil APK(s)で WARNING: Configuration 'compile' is obsole...

エラーではないようですが、次の様に修正します。

app/build.gradleの
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'
}
を
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:22.2.0'
}

 Generate signed Bundle/APKの署名が失われてしまっている場合

署名情報が失われてしまっている場合、新たな署名を行うしかないようです。

 Generate signed Bundle/APKでLint found fatal errors ...

次のエラーが出る場合

Lint found fatal errors while assembling a release target.

To proceed, either fix the issues identified by lint, or modify your build script as follows:
...
android {
    lintOptions {
        checkReleaseBuilds false
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false
    }
}
...

app/build.gradleのAndoid{...}に次の記述を追加します。

    lintOptions {
        checkReleaseBuilds false
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false
    }

 Android端末で「アプリがインストールされまていません」

旧アプリを置き換えようとするとAndroid端末で「アプリがインストールされまていません」が出る場合、 署名情報が旧版と異なることが原因の可能性があります。

Android端末の旧アプリを一旦削除して、ダウンロードしなおします。

 アプリ公開で、アプリの対象 API レベルを 26 以上に変更してください

app/build.gradleのバージョン番号を書き換えます。

app/build.gradle
    compileSdkVersion 27
    buildToolsVersion '28.0.2'

    defaultConfig {
        applicationId "jp.co.hiuric.hisupplemetro2"
        minSdkVersion 15
        targetSdkVersion 27
        versionCode 6
        versionName "1.3.00"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

 ビルド/Run手続き

残念ながら実行に至る手続きは良く分かっていません。

あるプロジェクトでは、 あれのビルド、これのビルド、あれのRun、これのDebugと色々やっているうちにマークが有効になって、 エミュレーター上で試験を実行できました。

残念ながら別のプロジェクトはエラーはでなくなりましたが、どうやってもが有効にならず何も実行できません。

| | トラックバック (0)

◇PhotoShopでホワイトバランス

[イメージ]⇒[色調補正]⇒[トーンカーブ]⇒右端のスポイト⇒ポイント選択⇒[OK]

 PhotoShopでホワイトバランスを取る。

例えば次の写真は、白いはずの楽譜の紙が白になっていません。
紙の部分を指定して「ホワイトバランス」をとりたいと思います。

不思議なことにPhotoShopでは「ホワイトバランス」という項目は有りません。

 [イメージ]⇒[色調補正]⇒[トーンカーブ]

 完成

この様になります。

 人間の目

人間の目の「ホワイトバランス」機構ってどうなってるんでしょうね。

冒頭のホワイトバランスの狂った絵も、視野全体に入るとちゃんと白が白に見えるんでしょうか?

| | トラックバック (0)

緊急メモ:Java-XMLでHTTPタイムアウト

 JavaのXMLReader.parse(InputSource)がHTTPアクセスでタイムアウト

これまでずっと動いていた JavaのSAX機構(org.xml.sax)が昨夜突如HTTPアクセスでタイムアウトするようになりました。

何度トライしても同じでした。

特にhttpアクセスなどを意識しては行っておらず、怪しいのは
 setFeature("http://xml.org/sax/features/namespaces", true);
だけ。
この名前は単なるスイッチ名で実際にhttpアクセスする訳ではないと考えていました。

どうやら実際にHTTPアクセスする(場合もある)ようなのです。

webでこのアドレスにアクセスしてみるとPage not foundでした。

調べると、他でもこのタイムアウト問題は発生しているようで、原因はxml.orgが死んでいること。
記事では「1週間後くらいに試したら動いた」となっていました。

で、

なんと!

僕のところでも、昨日動かなかったものが今日は動きました。

これはダメでしょ。
こんな不安定なものを使うわけにはいきません。
それに意図せず外部へのネットアクセスが発生するライブラリなど怖くて使えません。

細かく調べようとしていましたが、今日は動いているので調べるのも難しい。

XMLに未来があるとは思えませんので代替機構を作成するコストをかける気にはなりません。

JSONには「コメントが書けない」という人間が記述するには「致命的な欠陥」があります。

さて、どうするか

 愚痴:切り分けの難しさ

実はJDK8とJDK11の混在試験をしている最中に発生したのでJDK11のせいではないかと色々調べました。

JDK11では別の問題も発生しているので、結構混乱しました。

| | トラックバック (0)

メモ:jdeps/jlinkによる縮小JREでは不足が出る

 jdeps/jlinkではJREに不足がでる

JDK9で導入されたモジュール機能によるJREのコンパクト化ですが、限定的にしか使えないようです。

例えば次のコードを、通常のフルセットのJREで動かす試験とjdeps/jlinkを用いてコンパクト化したJREで動かす試験をします。

// HelloWorld2.java
import java.nio.charset.*;
public class HelloWorld2{
   public static void main(String[]args_){
      try{
         Charset charSet_EUCJP  = Charset.forName("EUC-JP");
         System.out.println("OK");
         }
      catch(Exception _ex){
         _ex.printStackTrace(System.err);
         }
      }
   }

試験は次のバッチスクリプトで行いました。

  • JDK8でビルドし
    • JDK8環境
    • JDK11によるコンパクトJRE
    で動作確認
  • JDK11でビルドし
    • JDK11環境
    • JDK11によるコンパクトJRE
    で動作確認

jlinkによりコンパクトJREに取り込んだモジュールはjava.baseのみです。依存関係はjdepsで確認。

:: A12_test.bat
@echo off
set JDK8=C:\Program Files\Java\jdk1.8.0_152
set JDK11=C:\Program Files\Java\jdk-11
set JDEPS=C:\Program Files\Java\jdk-11\bin\jdeps
set JLINK=C:\Program Files\Java\jdk-11\bin\jlink
set JMODS=C:\Program Files\Java\jdk-11\jmods

echo build JDK8
"%JDK8%\bin\javac" HelloWorld2.java

echo "%JDEPS%" --list-deps HelloWorld2.class
"%JDEPS%" --list-deps HelloWorld2.class
rd /q /s jre > NUL 2>&1
echo "%JLINK%" --compress=2 --module-path "%JMODS%" --add-modules java.base --output jre
"%JLINK%" --compress=2 --module-path "%JMODS%" --add-modules java.base --output jre 

echo run with JDK8
"%JDK8%\bin\java" HelloWorld2
echo run with mini-jre
jre\bin\java HelloWorld2

echo build JDK11
"%JDK11%\bin\javac" HelloWorld2.java
echo "%JDEPS%" --list-deps HelloWorld2.class
"%JDEPS%" --list-deps HelloWorld2.class
rd /q /s jre > NUL 2>&1
echo "%JLINK%" --compress=2 --module-path "%JMODS%" --add-modules java.base --output jre
"%JLINK%" --compress=2 --module-path "%JMODS%" --add-modules java.base --output jre

echo run with JDK11
"%JDK11%\bin\java" HelloWorld2
echo run with mini-jre
jre\bin\java HelloWorld2

pause

動作させると次の結果が得られます。

build JDK8
"C:\Program Files\Java\jdk-11\bin\jdeps" --list-deps HelloWorld2.class
   java.base
"C:\Program Files\Java\jdk-11\bin\jlink" --compress=2 --module-path "C:\Program Files\Java\jdk-11\jmods" --add-modules java.base --output jre
run with JDK8
OK
run with mini-jre
java.nio.charset.UnsupportedCharsetException: EUC-JP
        at java.base/java.nio.charset.Charset.forName(Charset.java:529)
        at HelloWorld2.main(HelloWorld2.java:6)
build JDK11
"C:\Program Files\Java\jdk-11\bin\jdeps" --list-deps HelloWorld2.class
   java.base
"C:\Program Files\Java\jdk-11\bin\jlink" --compress=2 --module-path "C:\Program Files\Java\jdk-11\jmods" --add-modules java.base --output jre
run with JDK11
OK
run with mini-jre
java.nio.charset.UnsupportedCharsetException: EUC-JP
        at java.base/java.nio.charset.Charset.forName(Charset.java:529)
        at HelloWorld2.main(HelloWorld2.java:6)
続行するには何かキーを押してください . . .

と、いうことでどうやれば、Charset.forName("EUC-JP")を動作させることができるのか、現時点では分かっていません。

| | トラックバック (0)

メモ:Java8とJava11の差

 Java8とJava11の差

同じソースでもJava8とJava11では動作が異なります。

次のコードはディスプレイのサイズを取得しています。これをJDK8とJDK11で動かすと異なる結果となります。

// HelloWorld.java
import java.awt.*;
public class HelloWorld{
   public static void main(String[]args_){
      System.err.println("win-height="
                        +GraphicsEnvironment
                        .getLocalGraphicsEnvironment()
                        .getDefaultScreenDevice()
                        .getDefaultConfiguration()
                        .getBounds()
                        .height
                        );
      }
   }

次の様にJava8とJava11でコンパイルし動作させると

:: A10_test.bat
@echo off
set JDK8=C:\Program Files\Java\jdk1.8.0_152
set JDK11=C:\Program Files\Java\jdk-11

echo JDK8
del /q /s HelloWorld.class  > NUL 2>&1
"%JDK8%\bin\javac" HelloWorld.java
"%JDK8%\bin\java" HelloWorld

echo JDK11
del /q /s HelloWorld.class  > NUL 2>&1
"%JDK11%\bin\javac" HelloWorld.java
"%JDK11%\bin\java" HelloWorld

echo build-JDK8 run-JDK11
del /q /s HelloWorld.class  > NUL 2>&1
"%JDK8%\bin\javac" HelloWorld.java
"%JDK11%\bin\java" HelloWorld

del /q /s HelloWorld.class  > NUL 2>&1

pause

次の結果が得られます。

JDK8
win-height=2160
JDK11
win-height=1440
build-JDK8 run-JDK11
win-height=1440
続行するには何かキーを押してください . . .

画面は4KなのでJDK8の動作が正しく、JDK11は正確ではありません。

Java9では多くのクラスが初期化時に異常を起こしたり、JVM自体が発狂したりしました。それに比べると、ましにはなりましたが、まだまだ採用できるレベルではなさそうです。

| | トラックバック (0)

◇電源コードと電源ボタンの位置

 電源コードと電源ボタンの位置

上の写真のマシンですが、電源コネクタと電源ボタンが反対の側についています。

電源コードを上から挿すと、電源ボタンは下になります。

で、写真のようにアプリを使おうとして、電源ボタンが下になり押されてしまい、電源がoffに。。。。。
汚い言葉は慎みますが。。

電源を挿すところと電源ボタンの位置が反対側になっている意味が分かりません。 僕の空間認識能力を超えた仕様です。

充電しながら使うというのはこのマシンにとって想定外、奇想天外、驚天動地の使い方なんだとは思います。
方向としては電源ボタンが上に位置し、電源コネクタは下で、使用するときは電源ケーブルは挿さない。
使用する前に十分に充電をしておくのが「神との暗黙の約束」で、それを守らない人間が悪い。文句を言う人間は許さない。そういう宗教なんでしょうね。


本当に難しいマシンです。windows10もCreatorsUpdate以降問題噴出ですが、こういう根本的な感性の部分で拒絶されている感じは受けません。
「無理!」と心が叫びます。

| | トラックバック (0)

より以前の記事一覧