下面的代碼是託管的MediaPlayer從URL播放MP3流的活動的最小例子之前。按「btn1」觸發URL1播放(NPR播客)。按「btn2」觸發URL2播放(不同電臺的mp3錄音)。的Android MediaPlayer的 - 用100 onBufferingUpdate稱爲調用0
public class MainActivity extends AppCompatActivity {
public static final String TAG = MainActivity.class.getSimpleName();
static final String URL1 = "http://13503.mc.tritondigital.com/WAITWAIT_PODCAST/media-session/822d578a-af47-4d7e-b3ca-d18af78071bc/anon.npr-podcasts/podcast/344098539/464996449/npr_464996449.mp3";
static final String URL2 = "http://www.selbie.com/wrekapp/Fri0130.mp3";
MediaPlayer _player;
void startPlayerAsync(String url) {
stopPlayer(); // _player.reset(); _player.release(); _player=null;
Log.d(TAG, "===================");
Log.d(TAG, "Starting new player for URL: "+url);
_player = new MediaPlayer();
try
{
_player.setDataSource(url);
}
catch (IOException e) {
Log.d(TAG, "IOException", e);
return;
}
_player.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
Log.d(TAG, "onBufferingUpdate: " + percent);
}
});
_player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
if (mp == _player)
{
Log.d(TAG, "onPrepared");
_player.start();
}
}
});
_player.prepareAsync();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startPlayerAsync(URL1);
}
});
findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startPlayerAsync(URL2);
}
});
}
}
當點擊BTN1,之前聽到音頻logspew的總結如下:
02-28 19:47:43.764 D/MainActivity: ===================
02-28 19:47:43.764 D/MainActivity: Starting new player for URL: http://13503.mc.tritondigital.com/WAITWAIT_PODCAST/media-session/822d578a-af47-4d7e-b3ca-d18af78071bc/anon.npr-podcasts/podcast/344098539/464996449/npr_464996449.mp3
02-28 19:47:44.695 1D/MainActivity: OnBufferingUpdate: 0
02-28 19:47:44.697 D/MediaPlayer: setSubtitleAnchor in MediaPlayer
02-28 19:47:44.699 D/MainActivity: onPrepared
02-28 19:47:44.703 D/MainActivity: onBufferingUpdate: 0
02-28 19:47:45.703 D/MainActivity: onBufferingUpdate: 6
02-28 19:47:46.704 D/MainActivity: onBufferingUpdate: 9
...
當按下爲其他URL BTN2,有一個稍微不同的行爲:
02-28 19:47:18.892 D/MainActivity: ===================
02-28 19:47:18.893 D/MainActivity: Starting new player for URL: http://www.selbie.com/wrekapp/Fri0130.mp3
02-28 19:47:20.453 D/MainActivity: onBufferingUpdate: 100 <==== NOTICE THIS
02-28 19:47:20.453 D/MediaPlayer: setSubtitleAnchor in MediaPlayer
02-28 19:47:20.465 D/MainActivity: onPrepared
02-28 19:47:20.676 D/MainActivity: onBufferingUpdate: 0
02-28 19:47:21.680 D/MainActivity: onBufferingUpdate: 2
...
在第一情況下,存在之前onPrepared
早期onBufferingUpdate(0)
事件燒製。然後onBufferingUpdate
呼叫的週期性間隔遞增從0到100作爲流播放。
但是在第二種情況下,存在虛假onBufferingUpdate(100)
觸發的事件。但幾秒鐘後,它與onPrepared
後onBufferingUpdate(0)
糾正。
不要緊,用戶點擊第一或流哪個按鈕被啓動。我甚至將URL2的mp3文件從其原始服務器移到另一個。關於第二個URL的mp3流會引起MediaPlayer想要以這種方式行事。在我的實際應用程序中,這會導致我的進度控制的「二級進度」行在顯示預期緩衝之前顯示一秒的實線。這是應用程序的視覺缺陷。
我的解決方法是忽略所有onBufferingUpdate
事件,直到onPrepared
被觸發爲止。在我做出改變之前,我想了解一下爲什麼會發生這種情況。並且確保它安全地假設在流開始之前緩衝達到100%是不可能的。這是正確的修復嗎?
好像有與這裏提到的媒體播放器回調問題(https://code.google.com/p/android/issues/detail?id=65564) 。您發佈解決方案和解決方法很好。 –