【发布时间】:2019-06-03 10:40:12
【问题描述】:
我正在做一个项目,我尝试播放 WhatsApp 之类的音频文件。 假设用户连续发送了三个文件,** 我想像 WhatsApp 一样播放/暂停/恢复音频文件** -
我想做的事:
如果我点击第一个音频文件(播放按钮),它应该开始播放,如果我点击暂停,它应该停止,如果我再次点击播放,它应该从我们暂停的确切位置开始播放(恢复音频文件)。
其他情况是,如果第一个文件正在播放并且我点击了第二个文件,第一个文件应该停止播放(更确切地说是暂停)并且第二个文件应该开始播放第二个音频文件,如果我点击播放第三个文件的第二个文件应该暂停,第三个音频文件应该开始播放。如果我在第一个文件上单击播放,第三个文件应该暂停,第一个文件应该继续播放。
我做了什么: 我正在使用 MediaPlayer 在 recylerview 中播放音频文件。我可以播放和暂停文件,但我无法在暂停后恢复文件(如何存储每个文件的最后一个位置),当我播放第一个文件并点击第二个文件时,两个文件都继续播放,而不是最近的文件。
试过:我试图在堆栈上找出这个问题,但是有很多问题,比如播放暂停和恢复,没有一个可以帮助我解决我的问题,一半的问题没有答案,一半的问题用户不再使用堆栈溢出(最后一次看到)。
我的问题:暂停后如何恢复每个文件,如何保存最后一个位置?
代码: 我正在使用 MVVM 架构,并且我的代码是用其中一个视图持有者编写的。
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.audio_play_button:
mAudioPauseButton.setVisibility(View.VISIBLE);
mAudioPlayButton.setVisibility(View.INVISIBLE);
play();
break;
case R.id.audio_pause_button:
mAudioPauseButton.setVisibility(View.INVISIBLE);
mAudioPlayButton.setVisibility(View.VISIBLE);
pause();
break;
default:
break;
}
}
我使用两个图标来暂停播放和处理点击时可见性。
private void play() {
if (mMediaPlayer == null) {
mMediaPlayer = new MediaPlayer();
setAudioUrltoMediaPlayer();
} else {
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
} else {
setAudioUrltoMediaPlayer();
}
}
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
if (mMediaPlayer != null) {
mMediaPlayer.start();
totalTime = mMediaPlayer.getDuration();
mTextChatAudioTime.setText(millisecondsToString(totalTime));
mAudioSeekBar.setProgress(0);
mAudioSeekBar.setMax(totalTime);
mAudioSeekBar.setClickable(true);
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
mAudioSeekBar.setProgress(mMediaPlayer.getCurrentPosition());
}
}, 0, 200);
mAudioSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@SuppressLint("SetTextI18n")
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
mMediaPlayer.seekTo(progress);
}
final long mMinutes = (progress / 1000) / 60;//converting into minutes
final int mSeconds = ((progress / 1000) % 60);//converting into seconds
mTextChatAudioTime.setText(mMinutes + ":" + mSeconds);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
int CurrentLevel = mAudioSeekBar.getProgress();
if (CurrentLevel < 30)
CurrentLevel = 30;
mAudioSeekBar.setProgress(CurrentLevel);
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
mAudioPauseButton.setVisibility(View.INVISIBLE);
mAudioPlayButton.setVisibility(View.VISIBLE);
mMediaPlayer.stop();
}
}, 200);
}
});
}
}
});
}
private void setAudioUrltoMediaPlayer() {
if (setAudioUrl != null) {
Log.d("audio file", "available" + setAudioUrl);
try {
Log.d("setAudioUrl", ">>>>>>>>>>>>>>>>>>>>>" + setAudioUrl);
mMediaPlayer.reset();
mMediaPlayer.setDataSource(setAudioUrl);
mMediaPlayer.prepare();
mMediaPlayer.setVolume(1.0f, 1.0f);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
} catch (IOException e) {
e.printStackTrace();
}
} else {
Log.d("audio file", "available" + setAudioUrl);
}
}
private void pause() {
if (mMediaPlayer != null) {
if (mMediaPlayer.isPlaying()) {
//lastposition = mMediaPlayer.getCurrentPosition();
mMediaPlayer.pause();
}
}
}
【问题讨论】:
-
您要保存多个状态文件还是一个?
-
我已经将音频文件保存在我的项目文件夹中,我通过在 setdatasource 中设置 uri 直接播放该文件,并且每个音频文件都在单击播放时成功播放。
-
如果您询问位置,那么我想保存所有文件的最后位置
-
@RuchaBhattJoshi 好吧
Whatsapp标签是问与whatsapp相关的问题,你确定他们会使用android mediaplayer来播放功能吗?他们可能有自己的播放引擎。也就是说,您的问题完全与android mediaplayer有关,您可以有类似I want whatsap kinda feature的描述。 -
@RuchaBhattJoshi 我可以帮助您调试您的问题,提供完整的代码,我将编译到我的手机并运行。 (链接到
zip文件应该可以)
标签: java android android-mediaplayer