• Android上实现视频录制


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

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

    如果还要使用一些硬件属性,那还要做额外的声明,例如:

    <uses-feature android:name="android.hardware.camera"/>
    <uses-feature:name="android.hardware.camera.autofocus"/>

    当我们在录制的时候,通常都想要看到我们正在拍什么,这就需要预览,而预览需要在一个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内的预览是另开线程做的,不知道是否会有改善?

  • 相关阅读:
    OpenCV 2.4.11 VS2012 Configuration
    [LeetCode] 11. Container With Most Water 装最多水的容器
    Android rxjava2的disposable
    Android在应用设置里关闭权限,返回生命周期处理
    Android 使用greenDAO 3.2.2 操作外部数据库
    Android中intent相关,setFlag(xx);
    Android 关于Acitivity 的setFlag以及launchmode的总结
    GreenDao3.0新特性解析(配置、注解、加密)
    Android RecycleView实现混合Item布局
    Android各大手机系统打开权限管理页面
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/4182995.html
Copyright © 2020-2023  润新知