Android MediaPlayer 背景音乐线程随机停止

Posted

技术标签:

【中文标题】Android MediaPlayer 背景音乐线程随机停止【英文标题】:Android MediaPlayer background music thread randomly stops 【发布时间】:2020-06-03 00:47:50 【问题描述】:

我在玩单活动游戏时(登录和选择角色后)。我的 SFX 声音池效果很好,但我的背景音乐随机停止播放。我尝试添加 setOnErrorListener,但从未在那里看到任何东西。我想知道线程是否正在被垃圾收集?

当您在不同的城镇或荒野时,音乐会发生变化,请在此处查看:!currentPlayingMusicFilename.equals(shortFilename)。如果您停留在同一个音乐区,音乐会随机停止循环播放。

我在这里和谷歌上阅读了很多帖子,但找不到播放游戏背景音乐的“正确”方式。我尝试过 soundpool,但它们超过 1MB,看到很多东西说不提供服务,并且这种方法存在问题。非常感谢任何帮助。

我将留在“SFX”部分,以防该代码可以帮助任何人并提供完整的图片。

public static void playSoundOrMusic(final String shortFilename, final String type, double distanceFactor) 
    String fullFilename = "";

    if (type.equals("SFX"))
        fullFilename = "res/sounds/sfx/" + shortFilename;
     else if (type.equals("MUSIC"))
        if (mp3MUSICPlayer != null && mp3MUSICPlayer.isPlaying() && !currentPlayingMusicFilename.equals(shortFilename))
            mp3MUSICPlayer.stop();
        
        fullFilename = "res/sounds/music/" + shortFilename;
    

    float volumeManipulation = 1.0f;
    if (type.equals("SFX"))
        int sfxVolume = MyCommandReceiver.GetSharedPreferences().getInt(MyCommandReceiver.GetStringById(R.string.pref_general_sfx_volume_key), 100);
        sfxVolume *= distanceFactor;
        volumeManipulation = (float) (sfxVolume / 100.0);
        //volumeManipulation = (float) (1 - (Math.log(MAX_VOLUME - sfxVolume) / Math.log(MAX_VOLUME)));
        LoggerWrite("v", TAG, "sfxVolume: " + volumeManipulation);
     else if (type.equals("MUSIC"))
        int musicVolume = MyCommandReceiver.GetSharedPreferences().getInt(MyCommandReceiver.GetStringById(R.string.pref_general_music_volume_key), 100);
        volumeManipulation = (float) (musicVolume / 100.0);
        //volumeManipulation = (float) (1 - (Math.log(MAX_VOLUME - musicVolume) / Math.log(MAX_VOLUME)));
        LoggerWrite("v", TAG, "musicVolume: " + volumeManipulation);
    
    final float finalVolume = volumeManipulation;

    if (MyCommandReceiver.GetActiveActivity() == null) //if not yet in Activity
        return;
    
    try 
        Uri myUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/KisnardOnline/" + fullFilename));
        if (type.equals("SFX"))
            if (!soundPoolIds.containsKey(Environment.getExternalStorageDirectory() + "/KisnardOnline/" + fullFilename)) //not yet in soundpool
                int soundId = soundPool.load(Environment.getExternalStorageDirectory() + "/KisnardOnline/" + fullFilename, 1);
                soundPoolIds.put(Environment.getExternalStorageDirectory() + "/KisnardOnline/" + fullFilename, soundId);
                //play it manually one time
                mp3SFXPlayer = new MediaPlayer();
                mp3SFXPlayer.setAudiostreamType(AudioManager.STREAM_MUSIC);
                mp3SFXPlayer.setVolume(finalVolume, finalVolume);
                mp3SFXPlayer.setDataSource(MyCommandReceiver.GetActiveActivity(), myUri);
                new Thread(new Runnable() 
                    @Override
                    public void run() 
                        try 
                            mp3SFXPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() 
                                @Override
                                public void onPrepared(MediaPlayer mp) 
                                    mp3SFXPlayer.start();
                                
                            );
                            mp3SFXPlayer.prepare();
                         catch (Exception ex) 
                            GameActivity.LoggerWrite("e", TAG, "Sound(sfx) playing issue" + ex);
                        
                    
                ).start();
             else  //already in soundpool - play it
                soundPool.play(soundPoolIds.get(Environment.getExternalStorageDirectory() + "/KisnardOnline/" + fullFilename), finalVolume, finalVolume, 0, 0, 1);
            
         else if (type.equals("MUSIC"))
            if (!currentPlayingMusicFilename.equals(shortFilename))
                mp3MUSICPlayer = new MediaPlayer();
                mp3MUSICPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                mp3MUSICPlayer.setVolume(finalVolume, finalVolume);
                mp3MUSICPlayer.setDataSource(MyCommandReceiver.GetActiveActivity(), myUri);
            
        
     catch (Exception e) 
        GameActivity.LoggerWrite("e", TAG, "Sound file issue" + e);
    

    if (type.equals("MUSIC") && !currentPlayingMusicFilename.equals(shortFilename))
        new Thread(new Runnable() 
            @Override
            public void run() 
                try 
                    mp3MUSICPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() 
                        @Override
                        public void onPrepared(MediaPlayer mp) 
                            currentPlayingMusicFilename = shortFilename;
                            mp3MUSICPlayer.start();
                        
                    );
                    mp3MUSICPlayer.prepare();
                    mp3MUSICPlayer.setLooping(true);
                 catch (Exception ex) 
                    GameActivity.LoggerWrite("e", TAG, "Sound(music) playing issue" + ex);
                
            
        ).start();
    

【问题讨论】:

您应该将设备中的日志(当音乐停止时)添加到问题中。 我没有任何日志 - 它随机发生,有时我必须玩一个多小时才能发生:( 也许与 ***.com/questions/30700930/mediaplayer-playback-limit 有关系,因为它在播放 28 次后停止,也没有可接受的答案,这可能很有趣。此外,此链接groups.google.com/forum/#!topic/android-platform/_tmA8DRg8q4 提到只能并行处理 30 个实例。你确定不超过?尝试以某种方式记录该号码 有趣。也许那时我不会失去它。那很好。我这里就放弃了,写了一些逻辑,看看是不是播放不出来,重新开始备份。 【参考方案1】:

这是我解决这个问题的方法,因为它似乎没有答案为什么它会随机死亡。

if (type.equals("MUSIC") && (!currentPlayingMusicFilename.equals(shortFilename) || !mp3MUSICPlayer.isPlaying()))
        new Thread(new Runnable() 
        ...

【讨论】:

以上是关于Android MediaPlayer 背景音乐线程随机停止的主要内容,如果未能解决你的问题,请参考以下文章

MediaPlayer 仅在调试模式下播放音乐文件(Android)

Android MediaPlayer 背景音乐线程随机停止

Android开发---MediaPlayer简单音乐播放器

Android 利用MediaPlayer实现音乐播放

android 使用MediaPlayer播放音乐要添加的权限是啥?

如何在 android 的 mediaplayer 中停止和播放新歌曲?