更快的 onScroll 手势反馈
Faster gesture feedback for onScroll
我有一个视频文件,想让用户通过向右和向左滑动手势来回播放它。用户体验应该是流畅的,如果视频文件包含从左到右的静态场景,用户应该有他在图片上左右滚动的印象(闪电变化的一部分)。这是我目前拥有的代码。
private GestureDetectorCompat mDetector;
private long lengthTourMs;
private long currentPositionMs;
private FFmpegMediaMetadataRetriever mmr;
ImageView video;
@Override
protected void onCreate(Bundle savedInstanceState) {
video = (ImageView)findViewById(R.id.video_frame);
mDetector = new GestureDetectorCompat(this, new SwipeGestureListener());
mmr = new FFmpegMediaMetadataRetriever();
mmr.setDataSource(this, Uri.parse("path/to/video/file"));
lengthTourMs = Long.parseLong(mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION));
currentPositionMs = 2000;
Bitmap frame = mmr.getFrameAtTime(currentPositionMs * 1000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST);
video.setImageBitmap(frame);
}
class SwipeGestureListener extends GestureDetector.SimpleOnGestureListener {
private static final String TAG = "Gestures";
@Override
public boolean onScroll(MotionEvent event1, MotionEvent event2,
float distanceX, float distanceY) {
Log.d(TAG, "onScroll: " + String.valueOf(distanceX));
currentPositionMs += (long)distanceX;
currentPositionMs += lengthTourMs;
currentPositionMs %= lengthTourMs;
Bitmap frame = mmr.getFrameAtTime(currentPositionMs * 1000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST);
Log.d(TAG, "currentPositionMs: " + String.valueOf(currentPositionMs));
video.setImageBitmap(frame);
return true;
}
}
问题是正常的滑动 right/left 手势会调用 onScroll 大约两到三次,因此上述代码的结果只是用户看到的两到三帧,而不是所有流畅的视频- 般的体验。
有没有办法 more/faster 对像 onScroll 这样的手势进行反馈?我也愿意接受其他解决问题的建议。
我用 OnTouchListener
解决了 ImageView
的问题。
private int x,y;
private long lengthTourMs;
private long currentPositionMs;
private FFmpegMediaMetadataRetriever mmr;
ImageView video = (ImageView)findViewById(R.id.video_frame);
video.setOnTouchListener( new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int xx,changeX;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = (int) event.getX();
break;
case MotionEvent.ACTION_MOVE:
xx = (int) event.getX();
changeX = x - xx;
currentPositionMs += changeX;
currentPositionMs += lengthTourMs;
currentPositionMs %= lengthTourMs;
video.setImageBitmap(mmr.getFrameAtTime(currentPositionMs * 1000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST));
x = xx;
break;
default:
break;
}
return true;
}
});
我实际上不再使用 FFmpegeMediaMetadataRetriever
因为实时搜索速度很慢,但这是另一个问题。
我有一个视频文件,想让用户通过向右和向左滑动手势来回播放它。用户体验应该是流畅的,如果视频文件包含从左到右的静态场景,用户应该有他在图片上左右滚动的印象(闪电变化的一部分)。这是我目前拥有的代码。
private GestureDetectorCompat mDetector;
private long lengthTourMs;
private long currentPositionMs;
private FFmpegMediaMetadataRetriever mmr;
ImageView video;
@Override
protected void onCreate(Bundle savedInstanceState) {
video = (ImageView)findViewById(R.id.video_frame);
mDetector = new GestureDetectorCompat(this, new SwipeGestureListener());
mmr = new FFmpegMediaMetadataRetriever();
mmr.setDataSource(this, Uri.parse("path/to/video/file"));
lengthTourMs = Long.parseLong(mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION));
currentPositionMs = 2000;
Bitmap frame = mmr.getFrameAtTime(currentPositionMs * 1000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST);
video.setImageBitmap(frame);
}
class SwipeGestureListener extends GestureDetector.SimpleOnGestureListener {
private static final String TAG = "Gestures";
@Override
public boolean onScroll(MotionEvent event1, MotionEvent event2,
float distanceX, float distanceY) {
Log.d(TAG, "onScroll: " + String.valueOf(distanceX));
currentPositionMs += (long)distanceX;
currentPositionMs += lengthTourMs;
currentPositionMs %= lengthTourMs;
Bitmap frame = mmr.getFrameAtTime(currentPositionMs * 1000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST);
Log.d(TAG, "currentPositionMs: " + String.valueOf(currentPositionMs));
video.setImageBitmap(frame);
return true;
}
}
问题是正常的滑动 right/left 手势会调用 onScroll 大约两到三次,因此上述代码的结果只是用户看到的两到三帧,而不是所有流畅的视频- 般的体验。
有没有办法 more/faster 对像 onScroll 这样的手势进行反馈?我也愿意接受其他解决问题的建议。
我用 OnTouchListener
解决了 ImageView
的问题。
private int x,y;
private long lengthTourMs;
private long currentPositionMs;
private FFmpegMediaMetadataRetriever mmr;
ImageView video = (ImageView)findViewById(R.id.video_frame);
video.setOnTouchListener( new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int xx,changeX;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = (int) event.getX();
break;
case MotionEvent.ACTION_MOVE:
xx = (int) event.getX();
changeX = x - xx;
currentPositionMs += changeX;
currentPositionMs += lengthTourMs;
currentPositionMs %= lengthTourMs;
video.setImageBitmap(mmr.getFrameAtTime(currentPositionMs * 1000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST));
x = xx;
break;
default:
break;
}
return true;
}
});
我实际上不再使用 FFmpegeMediaMetadataRetriever
因为实时搜索速度很慢,但这是另一个问题。