zoukankan      html  css  js  c++  java
  • 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内的预览是另开线程做的,不知道是否会有改善?

  • 相关阅读:
    android开发学习4
    macOS login: Could not determine audit condition 问题解决
    java代码编程规范
    学习进度报告(二)
    学习进度报告(一)
    android开发笔记
    数组
    软件工程第二周开课博客
    第一周学习总结
    用户体验评价
  • 原文地址:https://www.cnblogs.com/HuiLove/p/4554277.html
Copyright © 2011-2022 走看看