Android Assets 文件夹中的 Mp3 音频无法从签名且 zip 对齐的 APK 中播放

发布于 2025-01-02 06:08:06 字数 5568 浏览 1 评论 0原文

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

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

如果我使用“导出 Android 应用程序”打包应用程序,这将创建一个已签名的 APK,准备在 Android 市场中部署,然后将该 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 level 13 (Android 3.2) - 所以我认为这可能与 SDK 工具有关,因此我将 SDK 更新为v.16 和 v.10 的平台工具但这并没有解决问题。

I am loading mp3 files to play in an Android game based on AndEngine. When I package my game as an APK, mp3 audio in the assets folder throws the error "can not be opened as a file descriptor; it is probably compressed."

However, when I run the game using the run > button in Eclipse (MOTODEV Studio 3.0.2), the app is packaged, deployed to a device and the game has sound. Works perfectly on a device.

If I package the app using "Export Android Application", which creates a signed APK ready to deploy in the Android Market and then install that APK on a device, the game functions perfectly except the sound doesn't play and throws the following error:

> 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)

I have tried deploying the APK to a Kindle Fire, Motorolo Droid and Motorolo Droid 2 Global. The game works on all of these devices but without sound.

The audio is stored as mp3 files in a folder under Assets called Sound. An example filename is "music-a-nebulas-promise.mp3". I have tried renaming one of the files, "simple.mp3", worried that dashes are not allowed in the naming but it didn't make any difference.

The code that loads the audio is as follows and please note, when I run the application using MOTODEV Studio the sound is played back perfectly. It is only when I try to export the app as an APK and install it that I get the aforementioned error regarding compression:

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;
        }

The AndEngine method that initializes the audio:

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;
}

I have tried converting the mp3 files to both ogg and wav. Both ogg and wav throw the same error as mp3 files.

Since the game sound works when I run or debug it using Eclipse that seems to leave the final export step as the culprit. I have seen posts that suggest controlling the build process to prevent compression of files in the Assets folder but I'm not sure how to accomplish that from MOTODEV Studio.

I have also seen posts that suggest storing the mp3 audio in the res/raw folder but since audio in the Assets folder plays when run from Eclipse, it seems that it should also work when packaged as an APK.

Version details

I am current targeting Android SDK level 13 (Android 3.2) using Android SDK Tools v.15 and Android SDK Platform-tools v.9 -- so thinking it might have something to do with the SDK tools, I updated the SDK to v.16 and the platform tools to v.10 but that did not fix the problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

慕巷 2025-01-09 06:08:06

您的应用程序在调试时从 Eclipse(或 MOTODEV Studio)内运行时可以正常工作的原因是它不会经历导出时发生的完整路径。我面前没有 SDK 构建流程图,但那里有一个。我确信对 Ant 脚本进行一些探索将会揭示正在发生的事情。

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

The reason your app works when run from within Eclipse (or MOTODEV Studio) on debug is it is not going through the full path that occurs on export. I don't have the SDK build process chart in front of me, but there is one out there. I'm sure a bit of probing the Ant scripts will expose what is going on.

I say this because there's nothing MOTODEV Studio does different from Eclipse wrt the build process. While there is a separate "Export with MOTODEV Studio" menu item, all that's happening there is a couple of fields are being pre-populated with information as a convenience and access to your certificate store. Otherwise, the export process is the same as Eclipse+ADT (which is what it is).

烏雲後面有陽光 2025-01-09 06:08:06

该问题似乎与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;
    }

The problem seems to be related to the mediaPlayer.prepare() method in the MusicFactory.java of AndEngine. I've just comment out line 91 (as in the following code snipet) and the MP3 resource was loaded without any exceptions. I think the same can be done with the asset loading method.

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;
    }
初心未许 2025-01-09 06:08:06

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

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

这样,压缩就不会有问题。

You could put the audio-files in the "RAW" folder and play them via:

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

This way, there should be no problems with compression.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文