How to use Android to implement WeChat small video recording

Source: Internet
Author: User
This article mainly introduces detailed information about the implementation of the Android small video recording function. the specific implementation ideas and code are provided here, for more information about how to implement the Android small video recording function, see this article.

Android small video recording function

Before development

In the past few days, I have come into contact with video-related controls. as a result, I have come up with the ability to record small videos. There are many features available, I take some time every day to write and write. to tell the truth, some things are still difficult. I hope you can take a closer look. please correct me in the comments if you say something wrong. if you don't talk nonsense, go to the topic.

Development Environment

Those who have just updated recently and have not updated the updates are all in the hurry.

  1. Android Studio 2.2.2

  2. JDK1.7

  3. API 24

  4. Gradle 2.2.2

Related knowledge points

  1. Usage of SurfaceView on the video recording page

  2. Use of Camera

  3. Camera focus and zoom

  4. Use of the video recording control MediaRecorder

  5. Simple custom View

  6. Use of GestureDetector

There are a lot of things to use, but don't worry. let's come one by one.

Start Development

Case analysis

You can open your own small video and analyze its functions in a simple way?

  1. Basic video preview functions

  2. Long press and hold the video to record the video

  3. The progress bar decreases from both sides to the center during recording

  4. When the player or progress bar ends, the video is stopped and saved.

  5. Click "hold down" to cancel video recording.

  6. Double-click screen zoom

Based on the above analysis, we have completed step by step

Build layout

The layout interface can be implemented, making it difficult


 
   
    
      
       
         
            
             
           
        
     
  
 

Video Preview implementation

Step 1: Get the SufaceView control and set the basic attributes and corresponding listeners (the control is created asynchronously and can be called only after "preparation" is completed)


MSurfaceView = (SurfaceView) findViewById (R. id. main_surface_view); // sets the screen resolution mSurfaceHolder. setFixedSize (videoWidth, videoHeight); mSurfaceHolder. setType (SurfaceHolder. SURFACE_TYPE_PUSH_BUFFERS); mSurfaceHolder. addCallback (this );

Step 2: implement the interface. in the surfaceCreated method, enable video preview and destroy the video in surfaceDestroyed.


//////////////////////////////////////// /// // SurfaceView callback ////////////////////////////// ///// // @ Overridepublic void surfaceCreated (SurfaceHolder holder) {mSurfaceHolder = holder; startPreView (holder) ;}@ Overridepublic void surfaceChanged (SurfaceHolder holder, int format, int width, int height) {}@ Overridepublic void surfaceDestroyed (SurfaceHolder holder) {if (mCamera! = Null) {Log. d (TAG, "surfaceDestroyed:"); // stop previewing and release the camera resource mCamera. stopPreview (); mCamera. release (); mCamera = null;} if (mMediaRecorder! = Null) {mMediaRecorder. release (); mMediaRecorder = null ;}}

Step 3: video preview


/*** Enable preview ** @ param holder */private void startPreView (SurfaceHolder holder) {Log. d (TAG, "startPreView:"); if (mCamera = null) {mCamera = Camera. open (Camera. cameraInfo. CAMERA_FACING_BACK);} if (mMediaRecorder = null) {mMediaRecorder = new MediaRecorder ();} if (mCamera! = Null) {mCamera. setDisplayOrientation (90); try {mCamera. setPreviewDisplay (holder); Camera. Parameters parameters = mCamera. getParameters (); // implement the Camera auto focus List
 
  
FocusModes = parameters. getSupportedFocusModes (); if (focusModes! = Null) {for (String mode: focusModes) {mode. contains ("continuous-video"); parameters. setFocusMode ("continuous-video") ;}} mCamera. setParameters (parameters); mCamera. startPreview ();} catch (IOException e) {e. printStackTrace ();}}}
 

Note: The autofocus code is added above, but some mobile phones may not support it.

Custom two-way reduction progress bar

Some beginners, like me, may feel cool as soon as they see custom views. actually, Google has already written a lot of code for us, so we can use it. and we have no progress bars. it's not just a line. let's talk about it today.

Step 1: Inherit The View and complete initialization


Private static final String TAG = "BothWayProgressBar"; // The cancellation status is red bar, and the reverse is green barprivate boolean isCancel = false; private Context mContext; // specifies the Paint brush private Paint mRecordPaint that is being recorded. // specifies the Paint brush private Paint mCancelPaint when the video is scrubbed. // determines whether the Paint brush private int mVisibility is displayed. // The current progress is private int progress; // listener for the end of the progress bar: private OnProgressEndListener mOnProgressEndListener; public BothWayProgressBar (Context context) {super (context, null);} public BothWayProgressBar (Context context, AttributeSet attrs) {super (context, Context, attrs); mContext = context; init ();} private void init () {mVisibility = INVISIBLE; mRecordPaint = new Paint (); mRecordPaint. setColor (Color. GREEN); mCancelPaint = new Paint (); mCancelPaint. setColor (Color. RED );}

Note: OnProgressEndListener is mainly used to notify the camera to stop recording when the progress bar is in the middle. The interface is as follows:


Public interface listener {void listener ();}/*** listener after the progress bar ends * @ param OnProgressEndListener */public void listener (onProgressEndListener) {mOnProgressEndListener = OnProgressEndListener ;}

Step 2: Set the Setter method to notify us of Progress changes.


/*** Set progress ** @ param progress */public void setProgress (int progress) {this. progress = progress; invalidate ();}/*** sets whether the recording status is canceled * @ param isCancel */public void setCancel (boolean isCancel) {this. isCancel = isCancel; invalidate ();}/*** specifies whether to override the visible method * @ param visibility */@ Overridepublic void setVisibility (int visibility) {mVisibility = visibility; // redraw invalidate ();}

Step 3: draw the progress bar using the onDraw (Canvas canvas) method in the View.


@ Overrideprotected void onDraw (Canvas canvas) {super. onDraw (canvas); if (mVisibility = View. VISIBLE) {int height = getHeight (); int width = getWidth (); int mid = width/2; // draw a progress bar if (progress <mid) {canvas. drawRect (progress, 0, width-progress, height, isCancel? MCancelPaint: mRecordPaint);} else {if (mOnProgressEndListener! = Null) {mOnProgressEndListener. onProgressEndListener () ;}} else {canvas. drawColor (Color. argb (0, 0, 0, 0 ));}}

Recording event processing

There are four events triggered during recording:

  1. Long-pressed recording

  2. Lift and save

  3. Slide and cancel

  4. Double-click zoom in)

Now we analyze these four events one by one:
I put the first three events in an onTouch () callback method.
For 4th, we are waiting for talks
Let's first list the local variables in onTouch:


@ Overridepublic boolean onTouch (View v, MotionEvent event) {boolean ret = false; int action = event. getAction (); float ey = event. getY (); float ex = event. getX (); // only listen to the int vW = v in the middle of the button. getWidth (); int left = LISTENER_START; int right = vW-LISTENER_START; float downY = 0 ;//...}

Long-pressed recording

We need to listen to the ACTION_DOWN event and use the thread delay to send Handler to update the progress bar.


Switch (action) {case MotionEvent. ACTION_DOWN: if (ex> left & ex <right) {mProgressBar. setCancel (false); // Display slide to cancel mTvTip. setVisibility (View. VISIBLE); mTvTip. setText ("unlock slide cancel"); // record the pressed Y coordinate downY = ey; // TODO: 2016/10/20 start recording the video, and the progress bar begins to follow mProgressBar. setVisibility (View. VISIBLE); // starts recording Toast. makeText (this, "start recording", Toast. LENGTH_SHORT ). show (); startRecord (); mProgressThread = new Thread () {@ Override public void run () {super. run (); try {mProgress = 0; isRunning = true; while (isRunning) {mProgress ++; mHandler. obtainMessage (0 ). sendToTarget (); Thread. sleep (20) ;}} catch (InterruptedException e) {e. printStackTrace () ;}}; mProgressThread. start (); ret = true;} break ;//... return true ;}

Note: The method startRecord () can be recorded only after the Handler event is executed. it is only responsible for updating the progress of the progress bar.


//////////////////////////////////////// /// // Handler processing //////////////////////// /// // MyHandler extends Handler {private WeakReference
 
  
MReference; private MainActivity mActivity; public MyHandler (MainActivity activity) {mReference = new WeakReference
  
   
(Activity); mActivity = mReference. get () ;}@ Override public void handleMessage (Message msg) {switch (msg. what) {case 0: mActivity. mProgressBar. setProgress (mActivity. mProgress); break ;}}}
  
 

Lift and save

We also need to listen to the ACTION_UP event here, but we do not need to save it when the user raises too fast (the recording time is too short. in addition, this event contains the Cancelling status. it can be explained that the recording is canceled instantly when the video is removed. you can check the code.


Case MotionEvent. ACTION_UP: if (ex> left & ex <right) {mTvTip. setVisibility (View. INVISIBLE); mProgressBar. setVisibility (View. INVISIBLE); // determines whether the recording is completed or if (! IsCancel) {if (mProgress <50) {// do not save stopRecordUnSave (); Toast. makeText (this, "Time is too short", Toast. LENGTH_SHORT ). show (); break;} // stop recording stopRecordSave ();} else {// The current status is canceled. do not save stopRecordUnSave (); isCancel = false; Toast. makeText (this, "cancel recording", Toast. LENGTH_SHORT ). show (); mProgressBar. setCancel (false);} ret = false;} break;

Note: Similarly, the internal stopRecordUnSave () and stopRecordSave (); do not consider it. we will introduce it later. they can see from their names that the former is used to stop recording but not to save it, the latter stops recording and saves it.

Slide and cancel

In concert with the above part, the cancellation event can be lifted to achieve smooth cancellation.


case MotionEvent.ACTION_MOVE: if (ex > left && ex < right) {   float currentY = event.getY();   if (downY - currentY > 10) {     isCancel = true;     mProgressBar.setCancel(true);   } } break;

Note: The main principle is not difficult, as long as you press and move up a certain distance will trigger, when the hand is lifted, the video recording is canceled

Double-click zoom in)

This event is special. the GestureDetector gesture detection provided by Google is used to determine double-click events.

Step 1: perform a separate Touch event monitoring on SurfaceView, why? Because GestureDetector needs to fully host Touch events. if only some events are passed to it, some events will become invalid.


MDetector = new GestureDetector (this, new ZoomGestureListener ();/*** process the double-click event of mSurfaceView separately */mSurfaceView. setOnTouchListener (new View. onTouchListener () {@ Override public boolean onTouch (View v, MotionEvent event) {mDetector. onTouchEvent (event); return true ;}});

Step 2: rewrite GestureDetector. SimpleOnGestureListener to implement double-click event


//////////////////////////////////////// /////////////////////////////////// // Zoom gesture processing class /////////////////////////////////////// /// // class ZoomGestureListener extends GestureDetector. simpleOnGestureListener {// double-click the gesture event @ Override public boolean onDoubleTap (MotionEvent e) {super. onDoubleTap (e); Log. d (TAG, "onDoubleTap: Double-click event"); if (mMediaRecorder! = Null) {if (! IsZoomIn) {setZoom (20); isZoomIn = true;} else {setZoom (0); isZoomIn = false ;}} return true ;}}

Step 3: How to zoom in the camera


/*** Camera zoom ** @ param zoomValue */public void setZoom (int zoomValue) {if (mCamera! = Null) {Camera. parameters parameters = mCamera. getParameters (); if (parameters. isZoomSupported () {// determines whether int maxZoom = parameters is supported. getMaxZoom (); if (maxZoom = 0) {return;} if (zoomValue> maxZoom) {zoomValue = maxZoom;} parameters. setZoom (zoomValue); mCamera. setParameters (parameters );}}}

Note: Now we have listened to all events. we may be tired, but don't be discouraged. now we have completed our core part to achieve video recording.

Video recording

It is a core function, but we do not know some API methods. I have added a detailed comment in the code below, and remember it if I cannot understand it. ^ v ^


/*** Start recording */private void startRecord () {if (mMediaRecorder! = Null) {// no external storage, directly stop recording if (! Environment. getExternalStorageState (). equals (Environment. MEDIA_MOUNTED) {return;} try {// mMediaRecorder. reset (); mCamera. unlock (); mMediaRecorder. setCamera (mCamera); // capture the video mMediaRecorder from the camera. setVideoSource (MediaRecorder. videoSource. CAMERA); // collect audio information from the microphone mMediaRecorder. setAudioSource (MediaRecorder. audioSource. MIC); // TODO: 2016/10/20 sets the video format mMediaRecorder. setOutputFormat (MediaRecorder. outputFor Mat. MPEG_4); mMediaRecorder. setVideoSize (videoWidth, videoHeight); // number of frames per second (mMediaRecorder. setVideoFrameRate (24); // The encoding format is mMediaRecorder. setVideoEncoder (MediaRecorder. videoEncoder. DEFAULT); mMediaRecorder. setAudioEncoder (MediaRecorder. audioEncoder. AMR_NB); // set the frame frequency, and then the mMediaRecorder is clear. setVideoEncodingBitRate (1*1024*1024*100); // TODO: 2016/10/20 temporarily write a file address. please wait !!! File targetDir = Environment. getExternalStoragePublicDirectory (Environment. DIRECTORY_MOVIES); mTargetFile = new File (targetDir, SystemClock. currentThreadTimeMillis () + ". mp4 "); mMediaRecorder. setOutputFile (mTargetFile. getAbsolutePath (); mMediaRecorder. setPreviewDisplay (mSurfaceHolder. getSurface (); mMediaRecorder. prepare (); // formal recording of mMediaRecorder. start (); isRecording = true;} catch (Exception e) {e. printStackTrace ();}}}

Enable video stop

You may ask, why is the video stopped separately? When you carefully read the code above, you will see the two methods: stopRecordSave and stopRecordUnSave. one is to stop saving and the other is to stop saving. next we will fix this pitfall.

Stop and save


Private void stopRecordSave () {if (isRecording) {isRunning = false; mMediaRecorder. stop (); isRecording = false; Toast. makeText (this, "the video has been placed in" + mTargetFile. getAbsolutePath (), Toast. LENGTH_SHORT ). show ();}}

Stop not save


Private void stopRecordUnSave () {if (isRecording) {isRunning = false; mMediaRecorder. stop (); isRecording = false; if (mTargetFile. exists () {// delete mTargetFile without saving it. delete ();}}}

Note: it is my own idea to stop and not save it. if you have a better idea, I would like to thank you for your comments.

The above describes how to use Android to implement the small video recording function. For more information, see other related articles on php Chinese network!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.