媒体播放器太快切断了声音

Jes*_*sky 11 android android-mediaplayer

我有两个可以测试游戏的设备:美国Celluar手机(SCH-R880)和Kindle Fire,Kindle Fire比手机更强大.

我有几个短(小于或约1秒)的声音效果.为了节省内存,我加载,播放和释放其中一些声音效果.在电话中,他们(大多数)按预期播放.然而,在Kindle Fire上,它们被缩短了.真正短暂的声音被切断得如此之快,我听不到任何声音.然而,在设置时加载并保持的那些播放正常.

任何人都知道这里发生了什么?我是否会以某种方式过早发布我的媒体?以下是这方面的一个例子.在电话里,我听到"二级!" 但是在Kindle上我听到了类似"Lev tw"的内容.

mpNum = null;

try
{
    switch (level)
    {
        case 2:
            mpNum = MediaPlayer.create(contxt, R.raw.l2); break;
        case 3:
            mpNum = MediaPlayer.create(contxt, R.raw.l3); break;
        case 4:
            mpNum = MediaPlayer.create(contxt, R.raw.l4); break;
        case 5:
            mpNum = MediaPlayer.create(contxt, R.raw.l5); break;
        case 6:
            mpNum = MediaPlayer.create(contxt, R.raw.l6); break;
        case 7:
            mpNum = MediaPlayer.create(contxt, R.raw.l7); break;
        case 8:
            mpNum = MediaPlayer.create(contxt, R.raw.l8); break;
        default:
            return;
    }

    MediaPlayer vLevel = MediaPlayer.create(contxt, R.raw.level);

    vLevel.setOnPreparedListener(new MediaPlayer.OnPreparedListener()
    {
        public void onPrepared(MediaPlayer mp)
        {
            mp.start();
        }
    });

    vLevel.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
    {
           public void onCompletion(MediaPlayer mpl)
           {
            mpNum.start();
            mpl.release();
           }
       });

        mpNum.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
        {
            public void onCompletion(MediaPlayer mp)
            {
                mp.release();
            }
        });
    }
    catch (Exception e) {}
Run Code Online (Sandbox Code Playgroud)

为了尝试解决这个问题,我尝试了SoundPool,但它不起作用; 我什么都没听到.以下是我尝试使用SoundPool播放音乐的方法:

SoundPool soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 100);
    soundPool.load(contxt, R.raw.song2, 1);
    AudioManager mgr = (AudioManager)contxt.getSystemService(Context.AUDIO_SERVICE);
    float streamVolumeCurrent = mgr.getStreamVolume(AudioManager.STREAM_MUSIC);
    float streamVolumeMax = mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
    float volume =  streamVolumeMax;  

    soundPool.play(1, volume, volume, 1, 5, 2);
Run Code Online (Sandbox Code Playgroud)

UPDATE

我注意到应该播放的声音(但没有)出现此错误:

AudioPolicyManager: stopOutput() oldDevice 2
AudioPolicyManager: [getDeviceForStrategy] strategy : 0,forceUse(0)
Run Code Online (Sandbox Code Playgroud)

小智 16

我有同样的问题,它确实是一个垃圾收集器问题!如果将媒体播放器的实例分配给方法内的某个局部变量,则在离开该方法后该实例不再存在,因此GC可以随时随机删除它.

为避免这种情况,您需要在其他位置至少保留一个指向该实例的指针.我创建了一个静态集来保存所有指针,它看起来像这样:

private static Set<MediaPlayer> activePlayers = new HashSet<MediaPlayer>();
Run Code Online (Sandbox Code Playgroud)

然后创建媒体播放器如下:

MediaPlayer player = MediaPlayer.create(context, context.getResources().getIdentifier(id, "raw", pkg));
activePlayers.add(player);
player.setOnCompletionListener(releaseOnFinishListener);
player.start();
Run Code Online (Sandbox Code Playgroud)

releaseOnFinishListener是一个侦听器,它在完成时释放媒体播放器,就像你的一样,但也从activePlayers集中删除指针:

MediaPlayer.OnCompletionListener releaseOnFinishListener = new MediaPlayer.OnCompletionListener() {
    public void onCompletion(MediaPlayer mp) {
        mp.release();
        activePlayers.remove(mp);
    }
};
Run Code Online (Sandbox Code Playgroud)

我希望这可以帮助你.


Jes*_*sky 0

这很奇怪,不是一个好的解决方案,但却是我迄今为止发现的唯一解决方案。如果我删除mp.setOnPreparedListener和 ,mp.setOnCompletionListener并且只有mp.start(),它就可以工作。