<
>

JetPack开发中使用CameraX完成拍照和拍视频功能

2020-06-04 15:00:41 来源:易采站长站 作者:于海丽

调用ImageCapture的takePicture方法来拍照 传入一个文件地址用来保存拍好的照片 onImageSaved方法是照片已经拍好并存好之后的回调 onFileSaved方法中将前面保存的文件添加到媒体中,最后跳转到预览界面。

录视频:

//创建视频保存的文件地址
File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath(),
 System.currentTimeMillis() + ".mp4");
mVideoCapture.startRecording(file, Executors.newSingleThreadExecutor(), new VideoCapture.OnVideoSavedCallback() {
 @Override
 public void onVideoSaved(@NonNull File file) {
 outputFilePath = file.getAbsolutePath();
 onFileSaved(Uri.fromFile(file));
 }

 @Override
 public void onError(int videoCaptureError, @NonNull String message, @Nullable Throwable cause) {
 Log.i(TAG,message);
 }
});
videoCapture.stopRecording();
使用VideoCapture的startRecording方法来录视频 传入一个File文件用来保存视频, 录制完成之后回调onVideoSaved方法,并返回该文件的实例。 调用onFileSaved方法将前面保存的文件添加到媒体中,最后跳转到预览界面。 到达录制时间的时候,需要调用videoCapture.stopRecording();方法来停止录像。

到这里使用CameraX拍照和录制视频的功能都能完成了,是不是非常简单。下面来点题外的,自定义一个View,实现点击拍照,长按录像的效果。效果如下:

代码:

public class RecordView extends View implements View.OnLongClickListener, View.OnClickListener {
 private static final int PROGRESS_INTERVAL = 100;
 private int mBgColor;
 private int mStrokeColor;
 private int mStrokeWidth;
 private int mDuration;
 private int mWidth;
 private int mHeight;
 private int mRadius;
 private int mProgressValue;
 private boolean isRecording;
 private RectF mArcRectF;
 private Paint mBgPaint, mProgressPaint;
 private OnRecordListener mOnRecordListener;
 private long mStartRecordTime;

 public void setOnRecordListener(OnRecordListener onRecordListener) {
 mOnRecordListener = onRecordListener;
 }

 public RecordView(Context context) {
 this(context, null);
 }

 public RecordView(Context context, @Nullable AttributeSet attrs) {
 this(context, attrs, 0);
 }

 public RecordView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RecordView);
 mBgColor = typedArray.getColor(R.styleable.RecordView_bg_color, Color.WHITE);
 mStrokeColor = typedArray.getColor(R.styleable.RecordView_stroke_color, Color.RED);
 mStrokeWidth = typedArray.getDimensionPixelOffset(R.styleable.RecordView_stroke_width, SizeUtils.dp2px(5));
 mDuration = typedArray.getInteger(R.styleable.RecordView_duration, 10);
 mRadius = typedArray.getDimensionPixelOffset(R.styleable.RecordView_radius, SizeUtils.dp2px(40));
 typedArray.recycle();

 mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 mBgPaint.setStyle(Paint.Style.FILL);
 mBgPaint.setColor(mBgColor);

 mProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 mProgressPaint.setStyle(Paint.Style.STROKE);
 mProgressPaint.setColor(mStrokeColor);
 mProgressPaint.setStrokeWidth(mStrokeWidth);

 setEvent();
 }

 private void setEvent() {
 Handler handler = new Handler(Looper.getMainLooper()) {
  @Override
  public void handleMessage(@NonNull Message msg) {
  super.handleMessage(msg);
  mProgressValue++;
  postInvalidate();
  if (mProgressValue < mDuration*10) {
   sendEmptyMessageDelayed(0, PROGRESS_INTERVAL);
  } else {
   finishRecord();
  }
  }
 };
 setOnTouchListener(new OnTouchListener() {
  @Override
  public boolean onTouch(View v, MotionEvent event) {
  if(event.getAction() == MotionEvent.ACTION_DOWN){
   mStartRecordTime = System.currentTimeMillis();
   handler.sendEmptyMessage(0);
  }else if(event.getAction() == MotionEvent.ACTION_UP){
   long duration = System.currentTimeMillis() - mStartRecordTime;
   //是否大于系统设定的最小长按时间
   if(duration > ViewConfiguration.getLongPressTimeout()){
   finishRecord();
   }
   handler.removeCallbacksAndMessages(null);
   isRecording = false;
   mStartRecordTime = 0;
   mProgressValue = 0;
   postInvalidate();
  }
  return false;
  }
 });
 setOnClickListener(this);
 setOnLongClickListener(this);
 }

 private void finishRecord() {
  if(mOnRecordListener!=null){
  mOnRecordListener.onFinish();
  }
 }

 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
 super.onSizeChanged(w, h, oldw, oldh);
 mWidth = w;
 mHeight = w;
 mArcRectF = new RectF(mStrokeWidth / 2f, mStrokeWidth / 2f,
  mWidth - mStrokeWidth / 2f, mHeight - mStrokeWidth / 2f);
 }

 @Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);

 canvas.drawCircle(mWidth / 2f, mHeight / 2f, mRadius, mBgPaint);

 if (isRecording) {
  canvas.drawCircle(mWidth / 2f, mHeight / 2f, mRadius/10f*11, mBgPaint);
  float sweepAngle = 360f * mProgressValue / (mDuration*10);
  Log.i("sweepAngle",sweepAngle+"");
  canvas.drawArc(mArcRectF, -90, sweepAngle, false, mProgressPaint);
 }

 }

 @Override
 public boolean onLongClick(View v) {
 isRecording = true;
 if(mOnRecordListener!=null){
  mOnRecordListener.onRecordVideo();
 }
 return true;
 }

 @Override
 public void onClick(View v) {
 if(mOnRecordListener!=null){
  mOnRecordListener.onTackPicture();
 }
 }

 public interface OnRecordListener {
 void onTackPicture();

 void onRecordVideo();

 void onFinish();
 }
}
              
暂时禁止评论

微信扫一扫

易采站长站微信账号