本文主要是介绍用MediaRecorder实现简单的录像功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
思路:定义一个SurfaceView用来显示预览,在SurfaceHolder的回调中用Camera对象启动预览,然后调用MediaRecorder来录像。只是实现了简单的录像开始和停止功能,顶部能显示显示录像的时间,还有待完善。
代码如下:
在AndroidManifest.xml添加下面的权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 硬件支持 -->
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent" ><SurfaceViewandroid:id="@+id/camera_preview"android:layout_width="match_parent"android:layout_height="match_parent" /><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentTop="true"android:layout_centerHorizontal="true"android:orientation="horizontal"><TextViewandroid:id="@+id/timestamp_minute_prefix"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="#7F00FF"android:textSize="30sp"android:text="0"/><TextViewandroid:id="@+id/timestamp_minute_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="#7F00FF"android:textSize="30sp"android:text="0"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="#7F00FF"android:textSize="30sp"android:text=":"/><TextViewandroid:id="@+id/timestamp_second_prefix"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="#7F00FF"android:textSize="30sp"android:text="0"/><TextViewandroid:id="@+id/timestamp_second_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="#7F00FF"android:textSize="30sp"android:text="0"/></LinearLayout><ImageButtonandroid:id="@+id/record_shutter"android:layout_width="64dp"android:layout_height="64dp"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:layout_marginBottom="15dp"android:background="@android:color/transparent"android:scaleType="centerCrop"android:src="@drawable/recording_shutter" /></RelativeLayout>
MainActivity.java
package com.jackie.videorecorder;import java.io.File;import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.TextView;import org.w3c.dom.Text;public class MainActivity extends Activity implements OnClickListener {private SurfaceView mCameraPreview;private SurfaceHolder mSurfaceHolder;private ImageButton mShutter;private TextView mMinutePrefix;private TextView mMinuteText;private TextView mSecondPrefix;private TextView mSecondText;private Camera mCamera;private MediaRecorder mRecorder;private final static int CAMERA_ID = 0;private boolean mIsRecording = false;private boolean mIsSufaceCreated = false;private static final String TAG = "Jackie";private Handler mHandler = new Handler();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mCameraPreview = (SurfaceView) findViewById(R.id.camera_preview);mMinutePrefix = (TextView) findViewById(R.id.timestamp_minute_prefix);mMinuteText = (TextView) findViewById(R.id.timestamp_minute_text);mSecondPrefix = (TextView) findViewById(R.id.timestamp_second_prefix);mSecondText = (TextView) findViewById(R.id.timestamp_second_text);mSurfaceHolder = mCameraPreview.getHolder();mSurfaceHolder.addCallback(mSurfaceCallback);mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);mShutter = (ImageButton) findViewById(R.id.record_shutter);mShutter.setOnClickListener(this);}@Overrideprotected void onPause() {super.onPause();if (mIsRecording) {stopRecording();}stopPreview();}private SurfaceHolder.Callback mSurfaceCallback = new SurfaceHolder.Callback() {@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {mIsSufaceCreated = false;}@Overridepublic void surfaceCreated(SurfaceHolder holder) {mIsSufaceCreated = true;}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {startPreview();}};//启动预览private void startPreview() {//保证只有一个Camera对象if (mCamera != null || !mIsSufaceCreated) {Log.d(TAG, "startPreview will return");return;}mCamera = Camera.open(CAMERA_ID);Parameters parameters = mCamera.getParameters();Size size = getBestPreviewSize(CameraUtils.PREVIEW_WIDTH, CameraUtils.PREVIEW_HEIGHT, parameters);if (size != null) {parameters.setPreviewSize(size.width, size.height);}parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);parameters.setPreviewFrameRate(20);//设置相机预览方向mCamera.setDisplayOrientation(90);mCamera.setParameters(parameters);try {mCamera.setPreviewDisplay(mSurfaceHolder);
// mCamera.setPreviewCallback(mPreviewCallback);} catch (Exception e) {Log.d(TAG, e.getMessage());}mCamera.startPreview();}private void stopPreview() {//释放Camera对象if (mCamera != null) {try {mCamera.setPreviewDisplay(null);} catch (Exception e) {Log.e(TAG, e.getMessage());}mCamera.stopPreview();mCamera.release();mCamera = null;}}private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) {Camera.Size result = null;for (Camera.Size size : parameters.getSupportedPreviewSizes()) {if (size.width <= width && size.height <= height) {if (result == null) {result = size;} else {int resultArea = result.width * result.height;int newArea = size.width * size.height;if (newArea > resultArea) {result = size;}}}}return result;}@Overridepublic void onClick(View v) {if (mIsRecording) {stopRecording();} else {initMediaRecorder();startRecording();//开始录像后,每隔1s去更新录像的时间戳mHandler.postDelayed(mTimestampRunnable, 1000);}}private void initMediaRecorder() {mRecorder = new MediaRecorder();//实例化mCamera.unlock();//给Recorder设置Camera对象,保证录像跟预览的方向保持一致mRecorder.setCamera(mCamera);mRecorder.setOrientationHint(90); //改变保存后的视频文件播放时是否横屏(不加这句,视频文件播放的时候角度是反的)mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置从麦克风采集声音mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 设置从摄像头采集图像mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); // 设置视频的输出格式 为MP4mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); // 设置音频的编码格式mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); // 设置视频的编码格式mRecorder.setVideoSize(176, 144); // 设置视频大小mRecorder.setVideoFrameRate(20); // 设置帧率
// mRecorder.setMaxDuration(10000); //设置最大录像时间为10smRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());//设置视频存储路径File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + File.separator + "VideoRecorder");if (!file.exists()) {//多级文件夹的创建file.mkdirs();}mRecorder.setOutputFile(file.getPath() + File.separator + "VID_" + System.currentTimeMillis() + ".mp4");}private void startRecording() {if (mRecorder != null) {try {mRecorder.prepare();mRecorder.start();} catch (Exception e) {mIsRecording = false;Log.e(TAG, e.getMessage());}}mShutter.setImageDrawable(getResources().getDrawable(R.drawable.recording_shutter_hl));mIsRecording = true;}private void stopRecording() {if (mCamera != null) {mCamera.lock();}if (mRecorder != null) {mRecorder.stop();mRecorder.release();mRecorder = null;}mShutter.setImageDrawable(getResources().getDrawable(R.drawable.recording_shutter));mIsRecording = false;mHandler.removeCallbacks(mTimestampRunnable);//将录像时间还原mMinutePrefix.setVisibility(View.VISIBLE);mMinuteText.setText("0");mSecondPrefix.setVisibility(View.VISIBLE);mSecondText.setText("0");//重启预览startPreview();}private Runnable mTimestampRunnable = new Runnable() {@Overridepublic void run() {updateTimestamp();mHandler.postDelayed(this, 1000);}};private void updateTimestamp() {int second = Integer.parseInt(mSecondText.getText().toString());int minute = Integer.parseInt(mMinuteText.getText().toString());second++;Log.d(TAG, "second: " + second);if (second < 10) {mSecondText.setText(String.valueOf(second));} else if (second >= 10 && second < 60) {mSecondPrefix.setVisibility(View.GONE);mSecondText.setText(String.valueOf(second));} else if (second >= 60) {mSecondPrefix.setVisibility(View.VISIBLE);mSecondText.setText("0");minute++;mMinuteText.setText(String.valueOf(minute));} else if (minute >= 60) {mMinutePrefix.setVisibility(View.GONE);}}
}
效果如下:
这篇关于用MediaRecorder实现简单的录像功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!