2

我正在加载 mp3 文件以在基于 AndEngine 的 Android 游戏中播放。当我将游戏打包为 APK 时,assets 文件夹中的 mp3 音频会抛出错误“无法作为文件描述符打开;它可能已被压缩。”

但是,当我使用 Eclipse (MOTODEV Studio 3.0.2) 中的运行 > 按钮运行游戏时,应用程序被打包、部署到设备并且游戏有声音。在设备上完美运行。

如果我使用“导出 Android 应用程序”打包应用程序,这会创建一个准备好在 Android Market 中部署的签名 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 部署到 Kindle Fire、Motorolo Droid 和 Motorolo Droid 2 Global。该游戏可在所有这些设备上运行,但没有声音。

音频以 mp3 文件的形式存储在 Assets 下名为 Sound 的文件夹中。一个示例文件名是“music-a-nebulas-promise.mp3”。我曾尝试重命名其中一个文件“simple.mp3”,担心命名中不允许使用破折号,但这没有任何区别。

加载音频的代码如下,请注意,当我使用 MOTODEV Studio 运行应用程序时,声音可以完美播放。只有当我尝试将应用程序导出为 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 文件夹中的文件的帖子,但我不确定如何从 MOTODEV Studio 中实现这一点。

我还看到了建议将 mp3 音频存储在 res/raw 文件夹中的帖子,但是由于从 Eclipse 运行时会播放 Assets 文件夹中的音频,因此它似乎在打包为 APK 时也应该可以工作。

版本详情

我目前使用 Android SDK Tools v.15 和 Android SDK Platform-tools v.9 的目标是 Android SDK 级别 13(Android 3.2)——所以我认为它可能与 SDK 工具有关,我将 SDK 更新为 v。 16 和 v.10 的平台工具,但这并没有解决问题。

4

3 回答 3

1

问题似乎与AndEngine的MusicFactory.java中的mediaPlayer.prepare()方法有关。我刚刚注释掉了第 91 行(如下面的代码片段),并且 MP3 资源被加载,没有任何异常。我认为资产加载方法也可以做到这一点。

public static Music createMusicFromResource(final MusicManager pMusicManager, final Context pContext, final int pMusicResID) throws IOException {
        final MediaPlayer mediaPlayer = MediaPlayer.create(pContext, pMusicResID);
        **//mediaPlayer.prepare();**

        final Music music = new Music(pMusicManager, mediaPlayer);
        pMusicManager.add(music);

        return music;
    }
于 2012-07-10T19:16:04.410 回答
1

您的应用程序在调试时从 Eclipse(或 MOTODEV Studio)中运行时工作的原因是它没有通过导出时出现的完整路径。我面前没有 SDK 构建流程图,但有一个。我敢肯定,对 Ant 脚本的一些探索将揭示正在发生的事情。

我这样说是因为 MOTODEV Studio 在构建过程中与 Eclipse 没有什么不同。虽然有一个单独的“使用 MOTODEV Studio 导出”菜单项,但为了方便和访问您的证书存储,有几个字段正在预先填充信息。否则,导出过程与 Eclipse+ADT 相同(就是这样)。

于 2012-02-03T22:03:10.993 回答
0

您可以将音频文件放在“RAW”文件夹中并通过以下方式播放:

mPlayer2= MediaPlayer.create(this, R.raw.MUSICTAG);
mPlayer2.start();

这样,压缩应该没有问题。

于 2012-02-03T06:46:24.373 回答