|
|
@@ -64,81 +64,108 @@ public class VideoFramesView extends RelativeLayout {
|
|
|
recyclerView = findViewById(R.id.recyclerView);
|
|
|
line_start = findViewById(R.id.line_start);
|
|
|
line_end = findViewById(R.id.line_end);
|
|
|
- line_start.setOnTouchListener(new OnTouchListener() {
|
|
|
- private float lastEventX;
|
|
|
-
|
|
|
+ recyclerView.setOnTouchListener(new OnTouchListener() {
|
|
|
+ private View view;
|
|
|
+ private OnTouchListener onTouchListener;
|
|
|
@SuppressLint("ClickableViewAccessibility")
|
|
|
@Override
|
|
|
- public boolean onTouch(View view, MotionEvent event) {
|
|
|
- float maxX = line_end.getX();
|
|
|
- float minX = maxX - (firstEndX - firstStartX);//结束位置 - 可以设置的长度
|
|
|
+ public boolean onTouch(View v, MotionEvent event) {
|
|
|
switch (event.getAction()) {
|
|
|
case MotionEvent.ACTION_DOWN:
|
|
|
- lastEventX = event.getX();
|
|
|
- break;
|
|
|
- case MotionEvent.ACTION_MOVE:
|
|
|
- float mx = Math.max(firstStartX, view.getX() + event.getX() - lastEventX);
|
|
|
- if (mx > maxX)
|
|
|
- mx = maxX;
|
|
|
- if (mx < minX) {
|
|
|
- maxX += mx - minX;
|
|
|
- line_end.setX(maxX);
|
|
|
- view.setX(mx);
|
|
|
+ float x = event.getX();
|
|
|
+ if(Math.abs(x - line_start.getX()) > Math.abs(x - line_end.getX())){
|
|
|
+ view = line_end;
|
|
|
+ onTouchListener = endOnTouchListener;
|
|
|
} else {
|
|
|
- view.setX(mx);
|
|
|
- }
|
|
|
- if (onTimeChangeListener != null) {
|
|
|
- onTimeChangeListener.call((maxX - mx) * video.getDuration() / (rvW - lineW));
|
|
|
+ view = line_start;
|
|
|
+ onTouchListener = startOnTouchListener;
|
|
|
}
|
|
|
break;
|
|
|
- case MotionEvent.ACTION_UP:
|
|
|
- break;
|
|
|
- case MotionEvent.ACTION_CANCEL:
|
|
|
- break;
|
|
|
}
|
|
|
- view.invalidate();
|
|
|
- return true;
|
|
|
- }
|
|
|
- });
|
|
|
- line_end.setOnTouchListener(new OnTouchListener() {
|
|
|
- private float lastEventX;
|
|
|
-
|
|
|
- @SuppressLint("ClickableViewAccessibility")
|
|
|
- @Override
|
|
|
- public boolean onTouch(View view, MotionEvent event) {
|
|
|
- float minX = line_start.getX();
|
|
|
- float maxX = firstEndX - firstStartX + minX;
|
|
|
- float endX = firstStartX + rvW - lineW;
|
|
|
- switch (event.getAction()) {
|
|
|
- case MotionEvent.ACTION_DOWN:
|
|
|
- lastEventX = event.getX();
|
|
|
- break;
|
|
|
- case MotionEvent.ACTION_MOVE:
|
|
|
- float mx = Math.min(view.getX() + event.getX() - lastEventX, endX);
|
|
|
- if (mx < minX)
|
|
|
- mx = minX;
|
|
|
- if (mx > maxX) {
|
|
|
- minX += mx - maxX;
|
|
|
- line_start.setX(minX);
|
|
|
- view.setX(mx);
|
|
|
- } else {
|
|
|
- view.setX(mx);
|
|
|
- }
|
|
|
- if (onTimeChangeListener != null) {
|
|
|
- onTimeChangeListener.call((mx - minX) * video.getDuration() / (rvW - lineW));
|
|
|
- }
|
|
|
- break;
|
|
|
- case MotionEvent.ACTION_UP:
|
|
|
- break;
|
|
|
- case MotionEvent.ACTION_CANCEL:
|
|
|
- break;
|
|
|
+ if(view != null){
|
|
|
+ MotionEvent motionEvent = MotionEvent.obtain(event.getDownTime(), event.getEventTime(), event.getAction(), event.getX() - view.getX(), event.getY(),event.getMetaState());
|
|
|
+ return onTouchListener.onTouch(view, motionEvent);
|
|
|
}
|
|
|
- view.invalidate();
|
|
|
- return true;
|
|
|
+ return false;
|
|
|
}
|
|
|
});
|
|
|
+ line_start.setOnTouchListener(startOnTouchListener);
|
|
|
+ line_end.setOnTouchListener(endOnTouchListener);
|
|
|
}
|
|
|
|
|
|
+ private OnTouchListener endOnTouchListener = new OnTouchListener() {
|
|
|
+ private float lastEventX;
|
|
|
+
|
|
|
+ @SuppressLint("ClickableViewAccessibility")
|
|
|
+ @Override
|
|
|
+ public boolean onTouch(View view, MotionEvent event) {
|
|
|
+ float minX = line_start.getX();
|
|
|
+ float maxX = firstEndX - firstStartX + minX;
|
|
|
+ float endX = firstStartX + rvW - lineW;
|
|
|
+ switch (event.getAction()) {
|
|
|
+ case MotionEvent.ACTION_DOWN:
|
|
|
+ lastEventX = event.getX();
|
|
|
+ break;
|
|
|
+ case MotionEvent.ACTION_MOVE:
|
|
|
+ float mx = Math.min(view.getX() + event.getX() - lastEventX, endX);
|
|
|
+ if (mx < minX)
|
|
|
+ mx = minX;
|
|
|
+ if (mx > maxX) {
|
|
|
+ minX += mx - maxX;
|
|
|
+ line_start.setX(minX);
|
|
|
+ view.setX(mx);
|
|
|
+ } else {
|
|
|
+ view.setX(mx);
|
|
|
+ }
|
|
|
+ if (onTimeChangeListener != null) {
|
|
|
+ onTimeChangeListener.call((mx - minX) * video.getDuration() / (rvW - lineW));
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case MotionEvent.ACTION_UP:
|
|
|
+ break;
|
|
|
+ case MotionEvent.ACTION_CANCEL:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ view.invalidate();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ private OnTouchListener startOnTouchListener = new OnTouchListener() {
|
|
|
+ private float lastEventX;
|
|
|
+
|
|
|
+ @SuppressLint("ClickableViewAccessibility")
|
|
|
+ @Override
|
|
|
+ public boolean onTouch(View view, MotionEvent event) {
|
|
|
+ float maxX = line_end.getX();
|
|
|
+ float minX = maxX - (firstEndX - firstStartX);//结束位置 - 可以设置的长度
|
|
|
+ switch (event.getAction()) {
|
|
|
+ case MotionEvent.ACTION_DOWN:
|
|
|
+ lastEventX = event.getX();
|
|
|
+ break;
|
|
|
+ case MotionEvent.ACTION_MOVE:
|
|
|
+ float mx = Math.max(firstStartX, view.getX() + event.getX() - lastEventX);
|
|
|
+ if (mx > maxX)
|
|
|
+ mx = maxX;
|
|
|
+ if (mx < minX) {
|
|
|
+ maxX += mx - minX;
|
|
|
+ line_end.setX(maxX);
|
|
|
+ view.setX(mx);
|
|
|
+ } else {
|
|
|
+ view.setX(mx);
|
|
|
+ }
|
|
|
+ if (onTimeChangeListener != null) {
|
|
|
+ onTimeChangeListener.call((maxX - mx) * video.getDuration() / (rvW - lineW));
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case MotionEvent.ACTION_UP:
|
|
|
+ break;
|
|
|
+ case MotionEvent.ACTION_CANCEL:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ view.invalidate();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ };
|
|
|
//开头线的进度
|
|
|
public float getStartPercent() {
|
|
|
if (line_start != null && recyclerView != null) {
|
|
|
@@ -284,7 +311,7 @@ public class VideoFramesView extends RelativeLayout {
|
|
|
/**
|
|
|
* 显示视频帧图片列表
|
|
|
*/
|
|
|
- public VideoFramesView showVideoList(final Activity activity) {
|
|
|
+ public VideoFramesView showVideoList1(final Activity activity) {
|
|
|
List<VideoFrame> videoFrameList = new ArrayList<>();
|
|
|
final int size = 10;
|
|
|
long duration = video.getDuration();
|
|
|
@@ -306,7 +333,48 @@ public class VideoFramesView extends RelativeLayout {
|
|
|
protected void convert(BaseViewHolder helper, VideoFrame item) {
|
|
|
ImageView imageView = helper.getView(R.id.item_iv);
|
|
|
Glide.with(activity.getApplicationContext()).load(item.getVideoPath())
|
|
|
- .apply(RequestOptions.frameOf(item.getAtTime()).set(VideoBitmapDecoder.FRAME_OPTION, MediaMetadataRetriever.OPTION_CLOSEST).transform(new VideoFrameTransform(item)))
|
|
|
+ .apply(RequestOptions.frameOf(item.getAtTime()).set(VideoBitmapDecoder.FRAME_OPTION, MediaMetadataRetriever.OPTION_CLOSEST).transform(new VideoFrameTransform(item, false)))
|
|
|
+ .into(imageView);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ recyclerView.setAdapter(baseQuickAdapter);
|
|
|
+
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 显示视频帧图片列表
|
|
|
+ */
|
|
|
+ public VideoFramesView showVideoList(final Activity activity) {
|
|
|
+ if(TextUtils.equals(android.os.Build.CPU_ABI, "x86")) {//x86不兼容,不能在模拟器中连续调用FFmpegMediaMetadataRetriever
|
|
|
+ return showVideoList1(activity);
|
|
|
+ } else {
|
|
|
+ return showVideoList2(activity);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 显示视频帧图片列表
|
|
|
+ */
|
|
|
+ public VideoFramesView showVideoList2(final Activity activity) {
|
|
|
+ List<VideoFrame> videoFrameList = new ArrayList<>();
|
|
|
+ final int size = 10;
|
|
|
+ long duration = video.getDuration();
|
|
|
+ final long per = duration * 1000L / (size -1);
|
|
|
+ String path = video.getFilePath();
|
|
|
+
|
|
|
+ for (int i = 0; i < size; i++) {
|
|
|
+ long atTime = i + 1 == size ? (duration / 1000L * 1000_000L - per / 5) : i * per;
|
|
|
+// LogUtil.println(VideoFramesView.class.getSimpleName(), "showVideoList2", duration, i, per, atTime);
|
|
|
+ videoFrameList.add(new VideoFrame().setVideoPath(path).setAtTime(atTime)
|
|
|
+ .setWidth(video.getWidth()).setHeight(video.getHeight())
|
|
|
+ );
|
|
|
+ }
|
|
|
+ recyclerView.setLayoutManager(new GridLayoutManager(activity.getApplicationContext(), size));
|
|
|
+ BaseQuickAdapter<VideoFrame, BaseViewHolder> baseQuickAdapter = new BaseQuickAdapter<VideoFrame, BaseViewHolder>(R.layout.item_iv_mh, videoFrameList) {
|
|
|
+ @Override
|
|
|
+ protected void convert(BaseViewHolder helper, VideoFrame item) {
|
|
|
+ ImageView imageView = helper.getView(R.id.item_iv);
|
|
|
+ Glide.with(activity.getApplicationContext()).load(R.drawable.qiandao)
|
|
|
+ .apply(new RequestOptions().transform(new VideoFrameTransform(item)))
|
|
|
.into(imageView);
|
|
|
}
|
|
|
};
|
|
|
@@ -314,52 +382,6 @@ public class VideoFramesView extends RelativeLayout {
|
|
|
|
|
|
return this;
|
|
|
}
|
|
|
-// /**
|
|
|
-// * 显示视频帧图片列表
|
|
|
-// */
|
|
|
-// public VideoFramesView showVideoList(final Activity activity) {
|
|
|
-// if(TextUtils.equals(android.os.Build.CPU_ABI, "x86")) {//x86不兼容,不能在模拟器中连续调用FFmpegMediaMetadataRetriever
|
|
|
-// return showVideoList1(activity);
|
|
|
-// } else {
|
|
|
-// return showVideoList2(activity);
|
|
|
-// }
|
|
|
-// }
|
|
|
-// /**
|
|
|
-// * 显示视频帧图片列表
|
|
|
-// */
|
|
|
-// public VideoFramesView showVideoList2(final Activity activity) {
|
|
|
-// List<VideoFrame> videoFrameList = new ArrayList<>();
|
|
|
-// final int size = 10;
|
|
|
-// long duration = video.getDuration();
|
|
|
-// final long per = duration * 1000L / size;
|
|
|
-// int max = 20;
|
|
|
-// int width = max, height = max;
|
|
|
-// if (video.getWidth() > video.getHeight()) {
|
|
|
-// width = max * video.getWidth() / video.getHeight();
|
|
|
-// } else {
|
|
|
-// height = max * video.getHeight() / video.getWidth();
|
|
|
-// }
|
|
|
-// String path = video.getFilePath();
|
|
|
-// for (int i = 0; i < size; i++) {
|
|
|
-// videoFrameList.add(new VideoFrame().setVideoPath(path).setAtTime(i * per)
|
|
|
-// .setWidth(width).setHeight(height)
|
|
|
-// .setWidth(video.getWidth()).setHeight(video.getHeight())
|
|
|
-// );
|
|
|
-// }
|
|
|
-// recyclerView.setLayoutManager(new GridLayoutManager(activity.getApplicationContext(), size));
|
|
|
-// BaseQuickAdapter<VideoFrame, BaseViewHolder> baseQuickAdapter = new BaseQuickAdapter<VideoFrame, BaseViewHolder>(R.layout.item_iv_mh, videoFrameList) {
|
|
|
-// @Override
|
|
|
-// protected void convert(BaseViewHolder helper, VideoFrame item) {
|
|
|
-// ImageView imageView = helper.getView(R.id.item_iv);
|
|
|
-// Glide.with(activity.getApplicationContext()).load(R.drawable.qiandao)
|
|
|
-// .apply(new RequestOptions().transform(new VideoFrameTransform(item)))
|
|
|
-// .into(imageView);
|
|
|
-// }
|
|
|
-// };
|
|
|
-// recyclerView.setAdapter(baseQuickAdapter);
|
|
|
-//
|
|
|
-// return this;
|
|
|
-// }
|
|
|
|
|
|
private Action1<Float> onTimeChangeListener;
|
|
|
|