MediaPlayer-声音停止播放

时间:2018-10-16 22:14:28

标签: android android-mediaplayer

我正在创建一个女巫类,它会加载一些声音。但是,一段时间之后,isPlaying会继续引发异常,然后永久停止播放该特定声音,而其他声音则继续正常播放。

public class MySound {
   int m_IdMyId;
   int m_ResId;
   boolean m_IsLoaded;
   MediaPlayer m_Media;

   public MySound(int idMyId, int resId){
       m_IdMyId = idMyId;
       m_ResId = resId;
       m_IsLoaded = false;
       m_Media = null;
   }
}

在此m_IdMyId中,这只是我的游戏的ID。 m_ResId类似于R.raw.mysound1。我认为m_IsLoaded在同步加载时会自动设置为truem_MediaMediaPlayer对象。

我经常打电话给stop(),因为这是一场比赛,我需要每秒检查一次,以确保某些声音停止播放。在此处调用snd.m_Media.isPlaying()时会引发异常。

我似乎无法访问e来查看错误是什么。

我还想知道如何正确设置m_IsLoaded。我怎么知道声音何时完全加载并可以使用?

这是我的管理班:

public class MySoundManager {
    MainActivity m_Context;
    ArrayList<MySound> mySounds;

    public MySoundManager(MainActivity context) {
        m_Context = context;
        mySounds = new ArrayList<MySound>();
        mySounds.add(new MySound(8, R.raw.mysound1));
        mySounds.add(new MySound(10, R.raw.mysound2));
        mySounds.add(new MySound(22, R.raw.mysound3));
        mySounds.add(new MySound(100, R.raw.click));
        mySounds.add(new MySound(101, R.raw.error));

       for(MySound mysound : mySounds) {
           mysound.m_Media = MediaPlayer.create(m_Context, mysound.m_ResId); // no need to call prepare(); create() does that for you
           mysound.m_IsLoaded = true;
        }
    }

    // I call this when the main thread calls onResume
    public void onResume(){
        for(MySound mysound : mySounds) {
            if(mysound.m_Media == null) {
                mysound.m_Media = MediaPlayer.create(m_Context, mysound.m_ResId); // no need to call prepare(); create() does that for you
                mysound.m_IsLoaded = true;
            }
        }
    }

    // I call this when the main thread calls onPause
    public void onPause(){
        for(MySound mysound : mySounds) {
            if(mysound.m_Media != null) {
                mysound.m_Media.stop();
                mysound.m_Media.release();
                mysound.m_Media = null;
            }
        }
    }

    public boolean IsAllLoaded(){
        for(MySound mysound : mySounds) {
            if(!mysound.m_IsLoaded) return false;
        }
        return true;
    }

    public MySound FindMySoundByIdMyId(int idMyId){
        try {
            for(MySound mysound : mySounds) {
                if (mysound.m_IdMyId == idMyId) return mysound;
            }
        }catch(Exception e) {
            MySound snd;
            snd = null; // ToDo
        }
        return null;
    }

    public void play(int idMyId){
        MySound snd;
        try{
            if((snd = FindMySoundByIdMyId(idMyId)) != null)
                snd.m_Media.start();
        }catch(IllegalStateException e) {
            snd = null; // ToDo
        }
    }

    public void pause(int idMyId){
        MySound snd;
        try{
            if((snd = FindMySoundByIdMyId(idMyId)) != null &&
                    snd.m_Media.isPlaying())
               snd.m_Media.pause();
        }catch(IllegalStateException e) {
            snd = null; // ToDo
        }
    }

    public void pauseAll(){
        try{
            for (MySound mysound : mySounds) {
                if(mysound.m_Media.isPlaying())
                    mysound.m_Media.pause();
            }
        }catch(IllegalStateException e) {
            MySound snd;
            snd = null; // ToDo
        }
    }

    public boolean isPlaying(int idMyId, MySound[] fill){
        MySound snd;

        fill[0] = null;
        try{
            if((snd = FindMySoundByIdMyId(idMyId)) != null){
                fill[0] = snd;
                return snd.m_Media.isPlaying();
            }
        }catch(IllegalStateException e) {
            snd = null; // ToDo
        }
        return false;
    }

    public void stop(int idMyId){
        MySound snd;
        try{
            if((snd = FindMySoundByIdMyId(idMyId)) != null &&
                    snd.m_Media.isPlaying())
                snd.m_Media.stop();
        }catch(IllegalStateException e) {
            snd = null; // ToDo
        }
    }

    // The str is in the format
    // number id, 1 = on 0 = off,dont play if this id playing;
    public void PlaySound(String str) {
        boolean isplaying;
        int i, len, id, idDontPlay, milliNow;
        String[] strARR = str.split(";");
        String[] strARR2;
        Integer[] tmpIntARR;
        ArrayList<Integer[]> onARR = new ArrayList<Integer[]>();
        ArrayList<Integer> offARR = new ArrayList<Integer>();
        MySound snd;

        for (i = 0, len = strARR.length; i < len; i++) {
            if(strARR[i].length() <= 0) continue;
            if((strARR2 = strARR[i].split(",")) != null &&
                strARR2.length >= 3 &&
                strARR2[0].length() > 0 &&
                strARR2[1].length() > 0 &&
                strARR2[2].length() > 0){
                id = Integer.parseInt(strARR2[0]);
                idDontPlay = Integer.parseInt(strARR2[2]);
                tmpIntARR = new Integer[2];
                tmpIntARR[0] = id;
                tmpIntARR[1] = idDontPlay;
                if(Integer.parseInt(strARR2[1]) == 1){
                    onARR.add(tmpIntARR);
                } else offARR.add(id);
            }
        }

        // Turn off all sounds that need to be turned off
        for (i=0,len=offARR.size();i<len;i++) {
           id = offARR.get(i);
           stop(id);
        }

        // Turn all sounds that need to be turned on,
        // but only if the sound that blocks a new sound is not playing
        for (i=0,len=onARR.size();i<len;i++) {
            tmpIntARR = onARR.get(i);
            id = tmpIntARR[0];
            idDontPlay = tmpIntARR[1];

            // We dont play if the idDontPlay sound is already playing
            if((snd = FindMySoundByIdMyId(idDontPlay)) != null &&
                    snd.m_Media.isPlaying())
                continue;
            if((snd = FindMySoundByIdMyId(id)) != null){
                isplaying = snd.m_Media.isPlaying();
                milliNow = snd.m_Media.getCurrentPosition();
                if(milliNow > (snd.m_Media.getDuration() - 1000) ||
                    (!isplaying && milliNow > 0)){
                    snd.m_Media.seekTo(0); // Half a second inside
                }

                if(!isplaying) snd.m_Media.start();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

为每种声音创建MediaPlayer实例不是获得低延迟的好习惯,特别是对于短片。 MediaPlayer用于较长的剪辑,例如音乐文件,它使用较大的缓冲区,因此,较大的缓冲区意味着高延迟。另外,Android上有AudioFocus机制可能会干扰您的声音播放会话。因此,我强烈建议您使用SoundPool播放诸如游戏声音之类的短片。