Android上实现视频录制

 

Android上实现视频录制

分类: Android

尽管Google的SDK文档写到了相关的,内容但是实在是太短小精悍了,因为需要写个简单的Demo,所以学习了一下。

现在,我们一起来看看,到底要怎么去写吧:

首先,我们肯定要用到摄像头,因此需要在Manifest文件中声明使用权限:

<uses-permission android:name="android.permission.CAMERA" />
如果还要使用一些硬件属性,那还要做额外的声明,例如:

<uses-feature android:name="android.hardware.camera"/>
<uses-feature:name="android.hardware.camera.autofocus"/>
当然,你还想要录制音频的话,还得加上:

<uses-permission android:name="android.permission.RECORD_AUDIO" />

当我们在录制的时候,通常都想要看到我们正在拍什么,这就需要预览,而预览需要在一个SurfaceView上实现,因此我们要添加一个控件:

<SurfaceView android:id="@+id/surface_camera" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:layout_weight="1">
</SurfaceView>
然后,我们来实现这个Activity:

public class CustomVideoCamera extends Activity implements SurfaceHolder.Callback{

private static final String TAG = "CAMERA_TUTORIAL";

private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private Camera camera;
private boolean previewRunning;

    @Override
    public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.camera_surface);
            surfaceView = (SurfaceView) findViewById(R.id.surface_camera);
            surfaceHolder = surfaceView.getHolder();
            surfaceHolder.addCallback(this);
            surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
         camera = Camera.open();
         if (camera != null){
             Camera.Parameters params = camera.getParameters();
             camera.setParameters(params);
         }
         else {
             Toast.makeText(getApplicationContext(), "Camera not available!", Toast.LENGTH_LONG).show();
             finish();
         }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    if (previewRunning){
         camera.stopPreview();
    }
    Camera.Parameters p = camera.getParameters();
    p.setPreviewSize(width, height);
    p.setPreviewFormat(PixelFormat.JPEG);
    camera.setParameters(p);

    try {
        camera.setPreviewDisplay(holder);
        camera.startPreview();
        previewRunning = true;
    }
    catch (IOException e) {
        Log.e(TAG,e.getMessage());
        e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
          camera.stopPreview();
          previewRunning = false;
          camera.release();
    }
}
接着,我们就可以录制了:

private MediaRecorder mediaRecorder;
private final int maxDurationInMs = 20000;
private final long maxFileSizeInBytes = 500000;
private final int videoFramesPerSecond = 20;

public boolean startRecording(){
     try {
          camera.unlock();

          mediaRecorder = new MediaRecorder();

          mediaRecorder.setCamera(camera);
          mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
          mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

          mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);

          mediaRecorder.setMaxDuration(maxDurationInMs);

          tempFile = new File(getCacheDir(),cacheFileName);
          mediaRecorder.setOutputFile(tempFile.getPath());

          mediaRecorder.setVideoFrameRate(videoFramesPerSecond);
          mediaRecorder.setVideoSize(surfaceView.getWidth(), surfaceView.getHeight());

          mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
          mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);

          mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());

          mediaRecorder.setMaxFileSize(maxFileSizeInBytes);

          mediaRecorder.prepare();

          mediaRecorder.start();

          return true;
     } catch (IllegalStateException e) {
          Log.e(TAG,e.getMessage());
          e.printStackTrace();
          return false;
     } catch (IOException e) {
          Log.e(TAG,e.getMessage());
          e.printStackTrace();
          return false;
     }
}
停止拍摄,则:

public void stopRecording(){
    mediaRecorder.stop();
    camera.lock();
}

这样的话,通过编译之后,在Android OS 2.1 和 2.2上都能实现了,但在部分机器上会有些小问题,主要是预览上,看到app内的预览是另开线程做的,不知道是否会有改善?

原文地址:https://www.cnblogs.com/HuiLove/p/4554277.html