我已经解决了,包括播放网络视频,而且运行的很好!!我发现一个规律,只要多次seekto 之后,肯定能准确跳转。所以我写了一个重复seekto 的机制:
首先初始化加入配置项:
//SeekTo设置优化
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "http-detect-range-support", 0L);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "fflags", "fastseek"); //快速seekto
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "opensles", 0);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 0);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "reconnect", 1);
//重复seekto 的过渡值
private int curSeekPos = -1;
private int curSeekCount = 0;
mPlayerSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (!fromUser) {
return;
}
long duration = getDuration();
long newposition = (duration * progress) / 1000L;
seekTo((int) newposition);
if (mPlayerTime != null)
mPlayerTime.setText(stringForTime((int) newposition));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
curSeekPos = 0;
curSeekCount = 0;
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
long duration = getDuration();
long newposition = (duration * seekBar.getProgress()) / 1000L;
if (mMediaPlayer != null && mMediaPlayer instanceof IjkMediaPlayer) {
((IjkMediaPlayer) mMediaPlayer).setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "seek-at-start", newposition);
}
seekTo((int) newposition);
//记录最后需要seekto 的position。
curSeekPos = (int) newposition;
}
});
//重复 seekto
private void repeatSeekTo() {
curSeekCount++;
if (mMediaPlayer != null && mMediaPlayer instanceof IjkMediaPlayer) {
((IjkMediaPlayer) mMediaPlayer).setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "seek-at-start", curSeekPos);
}
seekTo(curSeekPos);
}
// 监听是不是 seekto 成功了,不成功重seekto,最大次数为 3 次
private IMediaPlayer.OnSeekCompleteListener mSeekCompleteListener = new IMediaPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete(IMediaPlayer mp) {
boolean isSeekComplete = true;
if (curSeekPos > 0) {
if (Math.abs(mMediaPlayer.getCurrentPosition() - curSeekPos) <= 1000) {
curSeekPos = 0;
curSeekCount = 0;
} else if (curSeekCount <= 3) {
repeatSeekTo();
isSeekComplete = false;
}
}
}
};