在setDataSource之后mediaPlayer.getDuration()返回0并导致应用崩溃 [英] mediaPlayer.getDuration() returns 0 after setDataSource and crashes app
问题描述
老实说,我不知道为什么会发生这种情况,因为代码很有意义,并且按照相同的方式进行教程.我首先设置数据源,然后尝试捕获它,设置音频流类型,然后尝试从媒体播放器获取持续时间,但它返回0.它不应该返回0,因为它们确实是音频并且可以播放声音很好.可能是由于数据源来自Firebase Storage位置而引起的错误,但是我不知道.错误也指向mediaPlayer.prepareAsync()方法,但这不是问题,因为没有mediaPlayer.getDuration()的代码也可以工作.
I honestly have no idea why this is happening, when the code makes sense and following tutorials the same way. I first set the data source and surround it in a try and catch, set the audio stream type, and attempt to get the duration from the media player but it returns 0. It shouldn't return 0 because their is indeed audio and it plays the audio fine. Maybe the error is caused because the data source is from Firebase Storage location, but I wouldn't know. Also the error points to the method mediaPlayer.prepareAsync(), but that's not the issue as the code works without mediaPlayer.getDuration().
@Override
public void onBindViewHolder(@NonNull final TrackHolder holder, final int position) {
final Track track =tracks.get(position) ;
holder.mInstrumentalName.setText(tracks.get(position).getInstrumentalName());
holder.mProducer.setText(tracks.get(position).getProducer());
holder.mPlayButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (start_notifying > 0) {
notifyItemChanged(previous_position, false);
previous_position = holder.getAdapterPosition();
Log.d("adapter", Integer.toString(holder.getAdapterPosition()));
holder.mPlayButton.change(false);
} else {
start_notifying++;
holder.mPlayButton.change(false);
previous_position = holder.getAdapterPosition();
}
if (mediaPlayer.isPlaying()) {
Log.d("playing", "is_playing");
mediaPlayer.reset();
holder.mMusicSeekbar.setEnabled(true);
try {
mediaPlayer.setDataSource(tracks.get(position).getMusicLink());
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
}
});
mediaPlayer.prepareAsync();
} else {
Log.d("playing", "just_started");
current_position = holder.getAdapterPosition();
mediaPlayer.reset();
holder.mMusicSeekbar.setEnabled(true);
try {
mediaPlayer.setDataSource(tracks.get(position).getMusicLink());
previous_link = tracks.get(position).getMusicLink();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
Log.d("playing", Integer.toString(mediaPlayer.getDuration())); // Error here, and causes crash.
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
}
});
mediaPlayer.prepareAsync();
}
}
});
track.isPlaying = start_notifying < 0;
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.stop();
notifyItemChanged(previous_position, false);
previous_position = -1;
start_notifying = 0;
}
});
holder.setItemClickListener(new ItemClickListener() {
@Override
public void onItemClick(View v, int pos) {
Toast.makeText(context, Integer.toString(position), Toast.LENGTH_SHORT).show();
}
});
}
错误日志
09-14 12:37:27.275 6401-6401/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: maginate.net.thebestrapper, PID: 6401
java.lang.IllegalStateException
at android.media.MediaPlayer.prepareAsync(Native Method)
at maginate.net.thebestrapper.essentials.TrackAdapter$1.onClick(TrackAdapter.java:130)
at android.view.View.performClick(View.java:5697)
at android.view.View$PerformClick.run(View.java:22526)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7224)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
推荐答案
一旦准备好OnPreparedListener回调内的数据源,就应该调用mediaPlayer.getDuration().
You should call mediaPlayer.getDuration() once data source is prepared that is inside OnPreparedListener call back
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.getDuration()
mediaPlayer.start();
}
});
这篇关于在setDataSource之后mediaPlayer.getDuration()返回0并导致应用崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!