I'm currently trying to find a solution to the same problem. The best I've come up with so far is as follows.
On 4.2 I've noticed that the following call backs are received:
1) onVideoSizeChanged() - where height and width = 0
2) onPrepared()
3) onVideoSizeChanged() - proper heights and widths
You can't call seekTo in (1) as the player is not yet prepared.
As you noted, if you call seekTo in (2) the media player generates the warning "Attempt to seek to past end of file"
You only receive (3) if MediaPlayer.start() has been called, but at this point you can call seekTo() successfully.
MediaPlayer mMediaPlayer = new MediaPlayer(); // + some initialisation code
boolean mVideoSizeIsSet = false;
boolean mMediaPlayerIsPrepared = false;
public void onPrepared(MediaPlayer mediaplayer) {
Log.d(TAG, "onPrepared called");
mMediaPlayerIsPrepared = true;
if (mVideoSizeIsSet) {
mMediaPlayer.seekTo();
}
mMediaPlayer.start()
}
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
Log.d(TAG, "onVideoSizeChanged called");
if (width == 0 || height == 0) {
Log.d(TAG, "invalid video width(" + width + ") or height(" + height + ")");
} else {
mVideoSizeIsSet = true;
if (mMediaPlayerIsPrepared) {
mMediaPlayer.seekTo();
}
}
}
(I personally don't like the use of the boolean guards, but if you look at the media player sample provided with the sdk, it does something similar).
Testing across a range of devices/OS versions, this provides a generic solution. However, there is a bug with 4.2. The call to mMediaPlayer.start() seems to cause the first few frames of the video start playing before the seekTo() occurs, this is barely visible for my situation, but may be more visible for you. I'm currently looking into hiding my surface view in some way until I receive the onSeekComplete() event, but this isn't ideal.
If anyone has a better solution that works across all OS versions I'd love to hear it.