首页 > 系统 > Android > 正文

Android使用MediaRecorder实现录像功能

2019-12-12 02:39:46
字体:
来源:转载
供稿:网友

用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" > <SurfaceView android:id="@+id/camera_preview" android:layout_width="match_parent" android:layout_height="match_parent" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:orientation="horizontal"> <TextView  android:id="@+id/timestamp_minute_prefix"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:textColor="#7F00FF"  android:textSize="30sp"  android:text="0"/> <TextView  android:id="@+id/timestamp_minute_text"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:textColor="#7F00FF"  android:textSize="30sp"  android:text="0"/> <TextView  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:textColor="#7F00FF"  android:textSize="30sp"  android:text=":"/> <TextView  android:id="@+id/timestamp_second_prefix"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:textColor="#7F00FF"  android:textSize="30sp"  android:text="0"/> <TextView  android: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> <ImageButton android: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(); @Override protected 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); } @Override protected void onPause() { super.onPause(); if (mIsRecording) {  stopRecording(); } stopPreview(); } private SurfaceHolder.Callback mSurfaceCallback = new SurfaceHolder.Callback() { @Override public void surfaceDestroyed(SurfaceHolder holder) {  mIsSufaceCreated = false; } @Override public void surfaceCreated(SurfaceHolder holder) {  mIsSufaceCreated = true; } @Override public 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; } @Override public 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); // 设置视频的输出格式 为MP4 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); // 设置音频的编码格式 mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); // 设置视频的编码格式 mRecorder.setVideoSize(176, 144); // 设置视频大小 mRecorder.setVideoFrameRate(20); // 设置帧率// mRecorder.setMaxDuration(10000); //设置最大录像时间为10s mRecorder.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() { @Override public 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); } }}

效果例如以下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表