为什么MediaPlayer无法正确播放音频?

时间:2019-05-13 16:15:28

标签: android android-mediaplayer

我正在处理一个图像库,其中包含音频,该音频是如何发音的,这些声音是用户在屏幕上查看的事物的发音,该音频通过还包含在屏幕中的按钮执行。

以下代码有效,但是有时音频在完成再现之前就被剪切掉了,问题是我没有收到任何错误日志。

View.OnClickListener eventoPlay = (v) → {
        @Override
        public void onClick(View v) {
            btnPlaySound.setClickable(false);
            try{
                Uri myUri = Uri.parse(urlroot + urlAudio); //global variables by current image
                final MediaPlayer mediaPlayer = new MediaPlayer();
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                mediaPlayer.setDataSource(getApplicationContext(), myUri);
                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        mediaPlayer.start();
                    }
                });

                mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mp) {
                        mp.release();
                        btnPlaySound.setClickable(true);
                    }
                });
                mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                    @Override
                    public boolean onError(MediaPlayer mp, int what, int extra) {
                        btnPlaySound.setClickable(true);
                        Log.e("Error in media player", String.valueOf(what));
                        Log.e("Error in media player", String.valueOf(extra));
                        return false;
                    }
                });
                mediaPlayer.prepareAsync();
            }catch (Exception e){
                e.printStackTrace();
                btnPlaySound.setClickable(true);
            }
        }
    };
btnPlaySound.setOnClickListener(eventoPlay);
btnPlaySound.performClick();

这些是我调试过的方案:

-setOnPreparedListener()总是自然地通话(音频总是开始播放)。

-setOnCompletionListener()仅在音频完成播放(如果音频未剪切)时呼叫。

-setOnErrorListener()永远不会调用,无论音频是否被剪切。

-catch不管音频是否被剪切,也永远不会执行此块。

我在三星Tab S3,三星Tab E,三星Tab A,阿尔卡特A3,小米MiA2,Swissmobility等设备中进行了测试。 在功能最强大的设备中,发生频率较低。但我希望这种失败永远不会发生。

Tnks。

1 个答案:

答案 0 :(得分:1)

您可能要确保在UI线程上正在调用btnPlaySound.setClickable(true)。可能导致错误。另外,媒体播放器可能会在完成垃圾回收之前,保持对MediaPlayer的(强烈)引用以防止垃圾回收。

尝试以下操作以测试是否被垃圾回收了:

View.OnClickListener eventoPlay = (v) → {
        @Override
        public void onClick(View v) {
            btnPlaySound.setClickable(false);
            try{
                Uri myUri = Uri.parse(urlroot + urlAudio); //global variables by current image

                // KEEP A STRONG REFERENCE
                mediaPlayer = new MediaPlayer();
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                mediaPlayer.setDataSource(getApplicationContext(), myUri);
                mediaPlayer.setLooping(false);
                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        mp.start();
                    }
                });

                mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mp) {
                        mp.release();
                        btnPlaySound.setClickable(true);
                    }
                });
                mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                    @Override
                    public boolean onError(MediaPlayer mp, int what, int extra) {
                        mp.release();
                        btnPlaySound.setClickable(true);
                        Log.e("Error in media player", String.valueOf(what));
                        Log.e("Error in media player", String.valueOf(extra));
                        return false;
                    }
                });
                mediaPlayer.prepareAsync();
            }catch (Exception e){
                e.printStackTrace();
                btnPlaySound.setClickable(true);
            }
        }
    };
btnPlaySound.setOnClickListener(eventoPlay);
btnPlaySound.performClick();