在这里,我开发了一个应用程序,可以流式传输存储在服务器中的音频文件。
这是使用MediaPlayer
类完成的。歌曲的当前播放位置和缓冲级别显示在自定义Seekbar
中。
到目前为止,我已经设法将缓冲进度显示为seekbar的次要进度,将seekbar的主要进度与MediaPlayer播放同步,并在单击相应按钮时播放,暂停和停止播放。
但是现在,我陷入了一个问题,即缓冲进度未显示出大于86%到89%的水平,这同样反映在搜索栏的次要进度上,即,搜索栏的缓冲进度在之后不会增加(86-89%)。我已经捕获了缓冲百分比在日志中,并在下面附加相关的日志详细信息。
07-02 14:21:34.484 14537-14559/com.appy.unofficialsultanapp I/MediaPlayer: prepared
07-02 14:21:34.484 14537-14537/com.appy.unofficialsultanapp E/MediaPlayer: Should have subtitle controller already set
07-02 14:21:34.494 14537-14537/com.appy.unofficialsultanapp I/Choreographer: Skipped 366 frames! The application may be doing too much work on its main thread.
07-02 14:21:34.514 14537-14537/com.appy.unofficialsultanapp E/MediaPlayer: Should have subtitle controller already set
07-02 14:21:34.544 14537-14537/com.appy.unofficialsultanapp I/Buffering: 5
07-02 14:21:35.524 14537-14537/com.appy.unofficialsultanapp I/Buffering: 8
07-02 14:21:36.524 14537-14537/com.appy.unofficialsultanapp I/Buffering: 15
07-02 14:21:37.524 14537-14537/com.appy.unofficialsultanapp I/Buffering: 29
07-02 14:21:38.524 14537-14537/com.appy.unofficialsultanapp I/Buffering: 43
07-02 14:21:39.524 14537-14537/com.appy.unofficialsultanapp I/Buffering: 59
07-02 14:21:40.524 14537-14537/com.appy.unofficialsultanapp I/Buffering: 75
07-02 14:21:41.524 14537-14537/com.appy.unofficialsultanapp I/Buffering: 89
07-02 14:22:31.034 14537-14537/com.appy.unofficialsultanapp E/MediaPlayer-JNI: QCMediaPlayer mediaplayer NOT present
07-02 14:22:31.034 14537-14710/com.appy.unofficialsultanapp D/MediaHTTPConnection: filterOutInternalHeaders: key=User-Agent, val= stagefright/1.2 (Linux;Android 5.1.1)
07-02 14:22:31.034 14537-14559/com.appy.unofficialsultanapp D/MediaHTTPConnection: proxy null port 0
07-02 14:22:33.554 14537-14559/com.appy.unofficialsultanapp D/MediaHTTPConnection: mTotalSize_1=4673664
mTotalSize_2=4673664
07-02 14:22:37.004 14537-14560/com.appy.unofficialsultanapp I/MediaPlayer: prepared
07-02 14:22:37.004 14537-14537/com.appy.unofficialsultanapp E/MediaPlayer: Should have subtitle controller already set
07-02 14:22:37.004 14537-14537/com.appy.unofficialsultanapp I/Choreographer: Skipped 357 frames! The application may be doing too much work on its main thread.
07-02 14:22:37.034 14537-14537/com.appy.unofficialsultanapp E/MediaPlayer: Should have subtitle controller already set
07-02 14:22:37.054 14537-14537/com.appy.unofficialsultanapp I/Buffering: 3
07-02 14:22:38.034 14537-14537/com.appy.unofficialsultanapp I/Buffering: 6
07-02 14:22:39.034 14537-14537/com.appy.unofficialsultanapp I/Buffering: 10
07-02 14:22:40.034 14537-14537/com.appy.unofficialsultanapp I/Buffering: 17
07-02 14:22:41.034 14537-14537/com.appy.unofficialsultanapp I/Buffering: 27
07-02 14:22:42.044 14537-14537/com.appy.unofficialsultanapp I/Buffering: 40
07-02 14:22:43.044 14537-14537/com.appy.unofficialsultanapp I/Buffering: 56
07-02 14:22:44.044 14537-14537/com.appy.unofficialsultanapp I/Buffering: 70
07-02 14:22:45.044 14537-14537/com.appy.unofficialsultanapp I/Buffering: 86
07-02 14:22:49.914 14537-14537/com.appy.unofficialsultanapp D/yuan: onVisibilityChanged----android.widget.ListView{2b9dfca7 VFED.VC. .F...... 20,83-700,1066 #7f040024 app:id/list}
07-02 14:22:55.004 14537-14555/com.appy.unofficialsultanapp W/MediaPlayer-JNI: MediaPlayer finalized without being released
我还将在歌曲搜索栏中附上歌曲缓冲级别的屏幕截图,并用红色突出显示。
我已经在网络上进行了大量研究以寻找其原因和解决方案,但没有一个对我有用。即使在将搜索栏拖到缓冲歌曲位置之前的位置(屏幕截图中的白条)),大约在86后%,歌曲播放没有任何问题,但如屏幕截图所示,次要进度被卡住了。
这是在MediaPlayer
和SeekBar
之间进行整体交互的代码
在Songs.java中创建的Songs类的代码段
private void primarySeekBarProgressUpdater() { /**method to update
primary progress of seekbar**/
seekBar.setProgress((int) (((float) mediaPlayer.getCurrentPosition() /
mediaFileLengthInMilliseconds) * 100));
tvElapsedTime.setText(getTimeString(mediaPlayer.getCurrentPosition()));
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
@Override
public void run() {
primarySeekBarProgressUpdater();
}
};
handler.postDelayed(notification, 1000);
}
}
@Override
public void onClick(View v) { /**onClick event handler to handle
play, pause and stop button clicks for mediaplayer **/
if (v.getId() == R.id.buttonPlay) {
if (mediaPlayer != null) {
mediaPlayer.start();
imPause.setVisibility(View.VISIBLE);
imPlay.setVisibility(View.INVISIBLE);
primarySeekBarProgressUpdater();
}
} else if (v.getId() == R.id.buttonPause) {
mediaPlayer.pause();
imPlay.setVisibility(View.VISIBLE);
imPause.setVisibility(View.INVISIBLE);
primarySeekBarProgressUpdater();
} else if (v.getId() == R.id.buttonStop) {
if (mediaPlayer != null) {
mediaPlayer.stop();
seekBar.setProgress(0);
seekBar.setSecondaryProgress(0);
imPlay.setVisibility(View.VISIBLE);
imPause.setVisibility(View.INVISIBLE);
}
} else if (v.getId() == R.id.buttonPlay && !itemClicked) {
Toast.makeText(getApplicationContext(), "Please touch a song to start
playing it.", Toast.LENGTH_LONG).show();
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() == R.id.seekBar) {
/** Seekbar onTouch event handler. Method which seeks MediaPlayer to
seekBar primary progress position*/
if (mediaPlayer != null) {
SeekBar sb = (SeekBar) v;
int playPositionInMilliseconds = (mediaFileLengthInMilliseconds /
100) * sb.getProgress();
mediaPlayer.seekTo(playPositionInMilliseconds);
tvElapsedTime.setText(getTimeString(mediaPlayer.getCurrentPosition()));
}
}
return false;
}
public String getTimeString(long millis) { /**method to convert passed
milliseconds to minutes and seconds and return in form of string**/
StringBuffer buf = new StringBuffer();
int mins = (int) ((millis % (1000 * 60 * 60)) / (1000 * 60));
int secs = (int) (((millis % (1000 * 60 * 60)) % (1000 * 60)) / 1000);
buf.append(String.format("%02d", mins)).append(":")
.append(String.format("%02d", secs));
return buf.toString();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public void onBackPressed() {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
}
super.onBackPressed();
}
下面是列表项(即单击任何歌曲)时相同类别的代码段
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, final
int position, long id) {
list.setItemChecked(position, true);
url = songdetails.get(position).getUrl(); // your URl
if (mediaPlayer != null) {
mediaPlayer.stop();
}
mediaPlayer = new MediaPlayer(); // create instance of
mediaplayer here
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
itemClicked = true;
} catch (IOException e) {
e.printStackTrace();
}
mediaFileLengthInMilliseconds = mediaPlayer.getDuration();//
gets the song length in milliseconds from URL
mediaPlayer.setOnPreparedListener(new
MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
imPlay.setVisibility(View.INVISIBLE);
imPause.setVisibility(View.VISIBLE);
primarySeekBarProgressUpdater();
tvEndTime.setText(getTimeString(mediaFileLengthInMilliseconds));
mediaPlayer.setOnBufferingUpdateListener(new
MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, int
percent) {
if (percent < seekBar.getMax()) {
seekBar.setSecondaryProgress(percent);
/** This is the point where secondary progress is set on buffering update **/
Log.i("Buffering", "" + percent); /**
and this is the point where tat buffered percentage is captured in logcat **/
}
}
});
mediaPlayer.setOnCompletionListener(new
MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.start();
}
});
}
});
primarySeekBarProgressUpdater();
}
});
所以我的缓冲进度没有达到我期望的100%。