Почему MediaPlayer не воспроизводит звук правильно? - PullRequest
0 голосов
/ 13 мая 2019

Я работаю в галерее изображений, которые содержат аудио о том, как произносятся вещи, которые пользователь просматривает на экране, что выполняется с помощью кнопки, также включенной в экран.

Следующеекод работает, но иногда звук обрезается до того, как он заканчивает воспроизведение, проблема в том, что я не получаю никакого журнала ошибок.

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 Этот блок также никогда не выполняется, независимо от того, обрезан ли звук.

Я проверялв таких устройствах, как Samsung S3, Samsung, E, Samsung, Alcatel A3, Xiaomi MiA2, Swissmobility.В самых мощных устройствах бывает реже.но я хочу, чтобы этот сбой никогда не происходил.

Tnks.

1 Ответ

1 голос
/ 13 мая 2019

Возможно, вы захотите убедиться, что 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();
...