Sound.extract()したByteArrayの末尾にID3v1が残ってしまって困ったので、その対処方法

投稿者: | 2014/03/05

2014/3/5 19:30追記:勘違いしていた部分があったので訂正。「ID3v1があるとおかしい」っていうのは変わらないのですが。

確認環境

FlashPlayer 12,0,0,70 Mac

状況

ID3v1が入っているMP3を使ってSoundオブジェクトを作成し、Sound.extract()使って曲の最後まで音情報取ろうとすると、末尾に入っているID3v1情報まで取られてしまう(訂正:むしろデータ量が足りてなかった。ID3v1が入っている方が短い。何故?)。普通に元のSoundオブジェクトを使ってSound.play()する分には問題ないが、このPCM情報を利用して、SAMPLE_DATAイベントを利用したサウンドジェネレート機能による再生(バイトの直接書き込み)を行うと、そのID3v1部分で(訂正:データの末尾で)FlashPlayerがクラッシュする。

ちなみにID3v2は問題ないっぽい。

対処方法

  • ID3v1を入れたMP3にしないように気をつける。

プロジェクト上、どうしても入れなければならない場合、対処方法は以下の2つ。

  • まず、URLLoaderでmp3ファイルを一旦「URLLoaderDataFormat.BINARY」で読み込む。末尾から128バイト目を「ByteArray.readUTFBytes()」で3文字分読み込んで、それが「TAG」であれば「ByteArray.length -= 128;」で末尾128バイトを取り除く。その上で、「Sound.loadCompressedDataFromByteArray()」を利用してID3v1を取り除いたバイトデータをサウンドデータにして、「extract()」すれば完了。
  • 「extract()」でID3v1が入った状態(訂正:データが足りていない状態)のByteArrayを、「Sound.loadPCMFromByteArray()」で再度Soundに落とし込むと、ID3v1が消えるっぽいので(訂正:足りなかったデータが何故か補完されているので)、それをまた「extract()」すれば完了。

まとめ

一番最後の方法は処理が大きいので、オススメはしません。ID3v1を入れないように気をつけたほうが良いでしょう。

参考

mp3ファイルの構造
http://www.cactussoft.co.jp/Sarbo/divMPeg3UnmanageFile.html