Android MediaPlayer - onBufferingUpdate called with 100 before called with 0 -
the code below minimal example of activity hosting mediaplayer play mp3 stream url. pressing "btn1" triggers url1 play (an npr podcast). pressing "btn2" triggers url2 play (mp3 recording of different station).
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 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); } }); } }
when btn1 clicked, summary of logspew prior hearing audio following:
02-28 19:47:43.764 d/mainactivity: =================== 02-28 19:47:43.764 d/mainactivity: starting new player 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 ...
when btn2 pressed other url, there's different behavior:
02-28 19:47:18.892 d/mainactivity: =================== 02-28 19:47:18.893 d/mainactivity: starting new player url: http://www.selbie.com/wrekapp/fri0130.mp3 02-28 19:47:20.453 d/mainactivity: onbufferingupdate: 100 <==== notice 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 ...
in first case, there onbufferingupdate(0)
event fired prior onprepared
. periodic interval of onbufferingupdate
calls incrementing 0 100 stream plays.
but in second case, there spurious onbufferingupdate(100)
event fired. few seconds later it's corrected onbufferingupdate(0)
after onprepared
.
it not matter button user clicked on first or stream gets started. i've moved mp3 file of url2 original server one. there's mp3 stream of second url causes mediaplayer want behave way. in actual application, causes "secondary progress" line of progress control show solid line second before shows expected buffering. it's visual blemish on app.
my workaround ignore onbufferingupdate
events until after onprepared
fired. before make change, i'd insight why happens. , make sure safe assume there can't legitimate case buffering gets 100% prior stream being started. right fix?
given no other option, decided ignore call onbufferingupdate value of 100 when mediaplayer in preparing state , hasn't been called non-zero value before:
effectively, code becomes this:
_player.setonbufferingupdatelistener(new mediaplayer.onbufferingupdatelistener() { @override public void onbufferingupdate(mediaplayer mp, int percent) { // percent can awkward "-2147483648" on live source. clamp it. if (percent < 0) { percent = 0; } else if (percent > 100) { percent = 100; } if ((_state == preparing) && (_secondarypercent == 0) && (percent == 100)) { log.d(tag, "onbufferingupdate(100) invoked while in preparing state - ignoring"); } else if (_secondarypercent != percent) { _secondarypercent = percent; handlebufferingupdate(percent); } } });
Comments
Post a Comment