石器时代
public class VideoControllerOverlay extends FrameLayout ... {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
...
// 获取视频时长ms
long duration = mPlayerListener.getDuration();
// 根据SeekBar取千分比
long newposition = (duration * progress) / 1000L;
// Seek
mPlayerListener.onSeekTo((int) newposition);
...
}
}
public class VideoPlayer ... {
@Override
public void onSeekTo(int time) {
// 调用到SurfaceView中
mVideoView.seekTo(time);
}
}
public class CMCCVideoView extends SurfaceView ... {
@Override
public void seekTo(int msec) {
if (isInPlaybackState()) {
// 系统API的MediapLayer接口
mMediaPlayer.seekTo(msec);
mSeekWhenPrepared = 0;
} else {
mSeekWhenPrepared = msec;
}
}
}
我们可以看到,应用层的源码中seek部分没有多余的操作,看不出导致ANR的地方。
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// 取消静音
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamMute(AudioManager.STREAM_MUSIC, false);
mDragging = false;
// 同步progress到视频实际位置
setProgress();
// 更新View
show(sDefaultTimeout);
// 继续同步
mHandler.sendEmptyMessage(SHOW_PROGRESS);
}
public int setProgress() {
...
// 获取位置和视频时长,计算progress位置
int position = mPlayerListener.getCurrentPosition();
int duration = mPlayerListener.getDuration();
if (mSeekBar != null) {
if (duration > 0) {
long pos = 1000L * position / duration;
mSeekBar.setProgress((int) pos);
} else {
mSeekBar.setProgress(0);
}
int percent = mPlayerListener.getBufferPercentage();
mSeekBar.setSecondaryProgress(percent * 10);
}
...
return position;
}
手势完成后也只是取消静音和更新了View状态,LOG打印没有卡在这里,没有发现会导致ANR的。
MPEG2PSExtractor: [AUDIO] start_pos=802101469, pos=802101248, ts=4608343266
这个LOG在seek后飞速刷新不停止,而其他视频没有刷这么多,所以问题就在这里
int64_t MPEG2PSExtractor::Track::utilSearch(int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret) {
// ts为64位
int64_t pos, ts;
// 为毛这里是32位?
int preTs = 0;
...
while (pos_min < pos_limit) {
...
// LOG出处
MPEG2PS_LOGI("start_pos=%lld, pos=%lld, ts=%lld", start_pos, pos, ts);
...
// 32位与64位比较
if (preTs == ts && pos == prePos && no_change == 0){
break;
}
// 一个64位值赋给32位,单位是us(微秒),会有精度丢失
preTs = ts;
...
}
...
}
//int preTs = 0;
int64_t preTs = 0;