AndEngineをベースにしたAndroidゲームで再生するmp3ファイルを読み込んでいます。ゲームをAPKとしてパッケージ化すると、アセットフォルダー内のmp3オーディオが「ファイル記述子として開くことができません。おそらく圧縮されています」というエラーをスローします。
ただし、Eclipse(MOTODEV Studio 3.0.2)で[実行]>ボタンを使用してゲームを実行すると、アプリがパッケージ化されてデバイスにデプロイされ、ゲームにサウンドが表示されます。デバイス上で完全に動作します。
「Androidアプリケーションのエクスポート」を使用してアプリをパッケージ化すると、Androidマーケットにデプロイする準備ができた署名付きAPKが作成され、そのAPKがデバイスにインストールされます。ゲームは完全に機能しますが、サウンドが再生されず、次のエラーがスローされます。
> 02-02 20:42:31.433: E/AndEngine(1925): AndEngine 02-02 20:42:31.433:
> E/AndEngine(1925): java.io.FileNotFoundException: This file can not be
> opened as a file descriptor; it is probably compressed 02-02
> 20:42:31.433: E/AndEngine(1925): at
> android.content.res.AssetManager.openAssetFd(Native Method) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> android.content.res.AssetManager.openFd(AssetManager.java:330) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> org.anddev.andengine.audio.music.MusicFactory.createMusicFromAsset(MusicFactory.java:75)
> 02-02 20:42:31.433: E/AndEngine(1925): at
> com.snoffleware.android.roshambomb.PlayLevelActivity.onLoadResources(PlayLevelActivity.java:255)
> 02-02 20:42:31.433: E/AndEngine(1925): at
> org.anddev.andengine.ui.activity.BaseGameActivity.doResume(BaseGameActivity.java:168)
> 02-02 20:42:31.433: E/AndEngine(1925): at
> org.anddev.andengine.ui.activity.BaseGameActivity.onWindowFocusChanged(BaseGameActivity.java:85)
> 02-02 20:42:31.433: E/AndEngine(1925): at
> com.android.internal.policy.impl.PhoneWindow$DecorView.onWindowFocusChanged(PhoneWindow.java:2012)
> 02-02 20:42:31.433: E/AndEngine(1925): at
> android.view.View.dispatchWindowFocusChanged(View.java:3924) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:659)
> 02-02 20:42:31.433: E/AndEngine(1925): at
> android.view.ViewRoot.handleMessage(ViewRoot.java:1968) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> android.os.Handler.dispatchMessage(Handler.java:99) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> android.os.Looper.loop(Looper.java:130) 02-02 20:42:31.433:
> E/AndEngine(1925): at
> android.app.ActivityThread.main(ActivityThread.java:3683) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> java.lang.reflect.Method.invokeNative(Native Method) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> java.lang.reflect.Method.invoke(Method.java:507) 02-02 20:42:31.433:
> E/AndEngine(1925): at
> com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:850)
> 02-02 20:42:31.433: E/AndEngine(1925): at
> com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> dalvik.system.NativeStart.main(Native Method)
APKをKindleFire、Motorolo Droid、Motorolo Droid2Globalにデプロイしてみました。ゲームはこれらすべてのデバイスで動作しますが、音は鳴りません。
オーディオは、サウンドと呼ばれるアセットの下のフォルダにmp3ファイルとして保存されます。ファイル名の例は「music-a-nebulas-promise.mp3」です。ファイルの1つである「simple.mp3」の名前を変更してみましたが、名前にダッシュが使用できないのではないかと心配していましたが、違いはありませんでした。
オーディオをロードするコードは次のとおりです。MOTODEVStudioを使用してアプリケーションを実行すると、サウンドが完全に再生されることに注意してください。アプリをAPKとしてエクスポートしてインストールしようとすると、圧縮に関する前述のエラーが発生します。
SoundFactory.setAssetBasePath("sound/");
MusicFactory.setAssetBasePath("sound/");
try {
if (!level.getMusic().equals("")) {
backgroundMusic = MusicFactory.createMusicFromAsset(this.mEngine.getMusicManager(), this, level.getMusic());
backgroundMusic.setLooping(true);
} else {
// music is turned on but there is no music file -- protect
// against crash
isMusic = false;
}
} catch (final IOException e) {
Debug.e(e);
// music is turned on but the music file was not found -- protect
// against crash
isMusic = false;
}
try {
collisionSound = SoundFactory.createSoundFromAsset(this.mEngine.getSoundManager(), this, "sfx-collision.mp3");
portalSound = SoundFactory.createSoundFromAsset(this.mEngine.getSoundManager(), this, "sfx-portal-activated.mp3");
winningSound = SoundFactory.createSoundFromAsset(this.mEngine.getSoundManager(), this, "sfx-winning.mp3");
losingSound = SoundFactory.createSoundFromAsset(this.mEngine.getSoundManager(), this, "sfx-losing.mp3");
} catch (final IOException e) {
Debug.e(e);
isSound = false;
}
オーディオを初期化するAndEngineメソッド:
public static Music createMusicFromAsset(final MusicManager pMusicManager, final Context pContext, final String pAssetPath) throws IOException {
final MediaPlayer mediaPlayer = new MediaPlayer();
final AssetFileDescriptor assetFileDescritor = pContext.getAssets().openFd(MusicFactory.sAssetBasePath + pAssetPath);
mediaPlayer.setDataSource(assetFileDescritor.getFileDescriptor(), assetFileDescritor.getStartOffset(), assetFileDescritor.getLength());
mediaPlayer.prepare();
final Music music = new Music(pMusicManager, mediaPlayer);
pMusicManager.add(music);
return music;
}
mp3ファイルをoggとwavの両方に変換してみました。oggとwavの両方がmp3ファイルと同じエラーをスローします。
ゲームサウンドは、Eclipseを使用して実行またはデバッグすると機能するため、最終的なエクスポート手順が原因であるように見えます。Assetsフォルダー内のファイルの圧縮を防ぐためにビルドプロセスを制御することを提案する投稿を見たことがありますが、MOTODEVStudioからそれを実行する方法がわかりません。
mp3オーディオをres/rawフォルダーに保存することを提案する投稿も見ましたが、AssetsフォルダーのオーディオはEclipseから実行すると再生されるため、APKとしてパッケージ化した場合にも機能するようです。
バージョンの詳細
現在、Android SDKToolsv.15とAndroidSDKPlatform-toolsv.9を使用してAndroidSDKレベル13(Android 3.2)をターゲットにしているので、SDKツールと関係があるのではないかと考えて、SDKをvに更新しました。 16およびv.10のプラットフォームツールですが、問題は解決しませんでした。