Wprowadzam niestandardowy odtwarzacz wideo, ponieważ potrzebuję niestandardowych elementów sterowania wideo. Mam aplikację z tylko jedną aktywnością, która po uruchomieniu powinna natychmiast rozpocząć odtwarzanie wideo.Dziwne zachowanie z mediaplayer i seekTo
Teraz problem mam jest:
Nie chcę wideo, aby rozpocząć od początku, ale z późniejszym pozycji. Dlatego wykonuję seekTo (16867). Ponieważ seekTo jest asynchroniczne, umieszczam wywołanie startowe mediaplayer (player.start()) w onSeekComplete of onSeekCompleteListener.
Dziwne zachowanie, którego doświadczam, polega na tym, że widzę/słyszę wideo odtwarzane od początku przez kilka milliseków, zanim faktycznie odtworzy się/przeskoczy do pozycji, której szukałem. Ale - z drugiej strony - wynik Logu, który wywołuję przed player.start zwraca poprawną pozycję 16867, gdzie szukałem.
Poniżej znajduje się odpowiedni odcinek kod, pełna klasa jest http://pastebin.com/jqAAFsuX
(jestem na Nexus One/2,2 stagefright)
private void playVideo(String url) {
try {
btnVideoPause.setEnabled(false);
if (player==null) {
player=new MediaPlayer();
player.setScreenOnWhilePlaying(true);
}
else {
player.stop();
player.reset();
}
url = "/sdcard/myapp/main/videos/main.mp4"; // <--- just for test purposes hardcoded here now
player.setDataSource(url);
player.setDisplay(holder);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnCompletionListener(this);
player.setOnPreparedListener(this);
player.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
public void onSeekComplete(MediaPlayer mediaPlayer) {
Log.d("APP", "current pos... "+ player.getCurrentPosition());
player.start(); // <------------------ start video on seek completed
player.setOnSeekCompleteListener(null);
}
});
player.prepareAsync();
}
catch (Throwable t) {
Log.e(TAG, "Exception in btnVideoPause prep", t);
}
}
public void onPrepared(MediaPlayer mediaplayer) {
width=player.getVideoWidth();
height=player.getVideoHeight();
if (width!=0 && height!=0) {
holder.setFixedSize(width, height);
progressBar.setProgress(0);
progressBar.setMax(player.getDuration());
player.seekTo(16867); // <------------------ seeking to position
}
btnVideoPause.setEnabled(true);
}
btw: Doświadczam tego samego podczas korzystania z VideoView w SDK, zamiast mojego własnego odtwarzacza multimedialnego + implementacji powierzchni. Zastanawiam się również, dlaczego VideoView nie dostarcza setOnSeekCompletionListener, chociaż zapewnia seekTo. Czy nie jest również asynchronizacja seekTo? –
Złożył raport o błędzie pod adresem http://code.google.com/p/android/issues/detail?id=9135 –
Powodzenia z obejściami do tej pory? Wiem od 2 lat, ale teraz przeszkadza mi w mojej aplikacji – Slartibartfast