Android-音视频(5):用 Camera API 采集视频数据并用SurfaceView显示

0.权限设置


之前的文章都忘记说明了权限的设置,一起需要的权限如下:

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

1.使用SurfaceView预览 Camera 数据


使用方法如下:

camera.setPreviewDisplay(surfaceHolder);

其实还可以用TextureView预览,如下:

camera.setPreviewTexture(surfaceTexture);

这里我们只用到了SurfaceView,至于TextureView的用法及区别,请另外查阅。

预览的全部代码如下:

surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
        surfaceHolder = surfaceView.getHolder();
        surfaceBtn = (Button) findViewById(R.id.surfaceviewBtn);
        //打开摄像头,并且旋转90度
        camera = Camera.open();
        camera.setDisplayOrientation(90);
        camera.setPreviewCallback(new Camera.PreviewCallback() {
            @Override
            public void onPreviewFrame(byte[] bytes, Camera camera) {

            }
        });

        surfaceHolder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {
                try {
                    camera.setPreviewDisplay(surfaceHolder);
                    camera.startPreview();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {}
            @Override
            public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
                camera.release();
            }
        });

2.Camera预览的数据回调


camera.setPreviewCallback(new Camera.PreviewCallback() {
            @Override
            public void onPreviewFrame(byte[] bytes, Camera camera) {

            }
});

这里的bytes的数据就是回调的视频数据,我们之后会使用这个数据 。

我们可以在回调这个数据之前,对这个数据做一点设置。

Camera.Parameters parameters = camera.getParameters();
//Camera Preview Callback的YUV420常用数据格式有两种:一个是NV21,一个是YV12。Android一般默认使用YUV_420_SP的格式(NV21)
        parameters.setPreviewFormat(ImageFormat.NV21);//设置回调数据的格式
        parameters.setPreviewSize(width,height); //对应手机的height和width

            camera.setParameters(parameters);//传入参数
            camera.setPreviewDisplay(surfaceHolder);
            camera.setPreviewCallback(this);
            camera.startPreview();

当然我们也可以设置其它的回调数据格式,不一定是NV21,这里只是为了和后面的代码匹配,所以用了NV21格式。

因为到时候使用MediaCodec编码直接将NV21格式的数据,写入文件,播放出来的视频可能颜色有偏差或者播放不出来,因为MediaCodec编码格式里没有NV21,但是有NV12和其它的等。我们之后代码里录制视频的时候会先将NV21的格式转换成NV12的格式,然后再编码存入文件。

之后也会对这些格式做一个统一的说明。

猜你喜欢

转载自blog.csdn.net/qq_38261174/article/details/82916050