为什么 MediaPlayer 不能正确播放音频?
Why MediaPlayer does not play the audio correctly?
我在图像库中工作,其中包含用户在屏幕上查看的内容的发音方式的音频,通过屏幕中也包含的按钮执行。
以下代码有效,但有时音频在完成再现之前被剪切,问题是我没有收到任何错误日志。
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 tab S3、Samsgung tab E、Samsung tab A、Alcatel A3、小米 MiA2、Swissmobility 等设备上进行了测试。
在最强大的设备中发生的频率较低。但我希望这种故障永远不会发生。
Tnks.
您可能希望确保 btnPlaySound.setClickable(true) 在 UI 线程上被调用。它可能会导致错误。此外,媒体播放器可能会在完成之前收集垃圾,并保留对 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();
我在图像库中工作,其中包含用户在屏幕上查看的内容的发音方式的音频,通过屏幕中也包含的按钮执行。
以下代码有效,但有时音频在完成再现之前被剪切,问题是我没有收到任何错误日志。
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 tab S3、Samsgung tab E、Samsung tab A、Alcatel A3、小米 MiA2、Swissmobility 等设备上进行了测试。 在最强大的设备中发生的频率较低。但我希望这种故障永远不会发生。
Tnks.
您可能希望确保 btnPlaySound.setClickable(true) 在 UI 线程上被调用。它可能会导致错误。此外,媒体播放器可能会在完成之前收集垃圾,并保留对 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();