您当前的位置: 首页 >  音视频

命运之手

暂无认证

  • 1浏览

    0关注

    747博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【Android音视频开发】【006】使用Camera2框架预览视频,拍摄照片

命运之手 发布时间:2019-11-14 18:04:14 ,浏览量:1

工作流程和原理 在这里插入图片描述 实现代码

AspectRatioTextureView是一个封装过的TextureView,提供了控制宽高比,快捷获取Surface的功能

ChainLinkList是一个封装过的LinkedList,使用了链式调用风格,方便使用

LoginActivity是核心逻辑代码,上面两个文件只是简单的辅助文件


	//LoginActivity.java
	
	@SuppressWarnings("all")
	public class LoginActivity extends CommonActivity {
	
	    @BindView(R.id.v_texture_view)
	    AspectRatioTextureView textureView;
	
	    @BindView(R.id.bt1)
	    View bt1;
	    @BindView(R.id.bt2)
	    View bt2;
	
	    HandlerThread backgroundThread;
	    Handler backgroundHandler;
	
	    CameraManager cameraManager;
	    CameraDevice cameraDevice;
	    CameraCaptureSession session;
	
	    ImageReader imageReader;
	
	    String cameraId;
	    Size previewSize;
	
	    long lastPictureCaptureTime;
	
	    protected void create() {
	        setContentView(R.layout.activity_main);
	        ButterKnife.bind(this, ctx);
	        requestAllPermissionWithCallback();
	    }
	
	    @Override
	    protected void onPermissionOk() {
	        init();
	    }
	
	    @SneakyThrows
	    private void init() {
	        //获取相机管理器
	        cameraManager = (CameraManager) ctx.getSystemService(Context.CAMERA_SERVICE);
	
	        //获取后置摄像机
	        for (String cameraId : cameraManager.getCameraIdList()) {
	            CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
	            Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
	            if (facing == CameraCharacteristics.LENS_FACING_BACK) {
	                ctx.cameraId = cameraId;
	                //获取最大支持的图片大小
	                StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
	                previewSize = Collections.max(Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)), (l, r) -> {
	                    return l.getWidth() * l.getHeight() - r.getWidth() * r.getHeight();
	                });
	            }
	        }
	
	        //创建一个HandlerThread,用来处理后台任务,如写出图片等
	        backgroundThread = new HandlerThread("CameraBackgroundThread");
	        backgroundThread.start();
	        backgroundHandler = new Handler(backgroundThread.getLooper());
	
	        //创建ImageReader,用于缓存和抓取帧图像
	        imageReader = ImageReader.newInstance(previewSize.getWidth(), previewSize.getHeight(), ImageFormat.JPEG, 1);
	        imageReader.setOnImageAvailableListener(ctx::writeOutImage, backgroundHandler);
	
	        //监听TextureView初始化完成
	        textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
	            @Override
	            @SneakyThrows
	            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
	                cameraManager.openCamera(cameraId, new CameraDevice.StateCallback() {
	                    @Override
	                    @SneakyThrows
	                    public void onOpened(CameraDevice cameraDevice) {
	                        ctx.cameraDevice = cameraDevice;
	                        //创建关联TextureView和ImageReader的Surface
	                        Surface textureSurface = textureView.getSurface(previewSize.getWidth(), previewSize.getHeight());
	                        Surface imageSurface = imageReader.getSurface();
	                        //开启CaptureSession
	                        ChainLinkList surfaceList = ChainLinkList.create(Surface.class).add(textureSurface, imageSurface);
	                        cameraDevice.createCaptureSession(surfaceList.baseList, new CameraCaptureSession.StateCallback() {
	                            @Override
	                            public void onConfigured(CameraCaptureSession session) {
	                                ctx.session = session;
	                                startVideoPreview();
	                            }
	
	                            @Override
	                            public void onConfigureFailed(CameraCaptureSession session) {}
	                        }, backgroundHandler);
	                    }
	
	                    @Override
	                    public void onDisconnected(CameraDevice cameraDevice) {
	                        ctx.session = null;
	                        ctx.cameraDevice = null;
	                    }
	
	                    @Override
	                    public void onError(CameraDevice camera, int errorCode) {}
	                }, backgroundHandler);
	            }
	
	            @Override
	            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {}
	
	            @Override
	            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { return false; }
	
	            @Override
	            public void onSurfaceTextureUpdated(SurfaceTexture surface) {}
	        });
	
	        //截取图片
	        bt1.setOnClickListener(v -> {
	            startImageCapture();
	        });
	    }
	
	    //视频预览
	    @SneakyThrows
	    void startVideoPreview() {
	        //发起CaptureRequest
	        CaptureRequest.Builder captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
	        captureRequestBuilder.addTarget(textureView.getSurface(previewSize.getWidth(), previewSize.getHeight()));
	        CaptureRequest captureRequest = captureRequestBuilder.build();
	        session.setRepeatingRequest(captureRequest, null, backgroundHandler);
	    }
	
	    //抓拍图片
	    @SneakyThrows
	    void startImageCapture() {
	        //发起CaptureRequest
	        CaptureRequest.Builder captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
	        captureRequestBuilder.addTarget(textureView.getSurface(previewSize.getWidth(), previewSize.getHeight()));
	        captureRequestBuilder.addTarget(imageReader.getSurface());
	        CaptureRequest captureRequest = captureRequestBuilder.build();
	        lastPictureCaptureTime = 0;
	        session.stopRepeating();
	        session.abortCaptures();
	        session.capture(captureRequest, null, backgroundHandler);
	    }
	
	    //写出图片
	    @SneakyThrows
	    void writeOutImage(ImageReader reader) {
	        //每5秒保存一次图片
	        long now = Times.millisOfNow();
	        if (now - lastPictureCaptureTime             
关注
打赏
1654938663
查看更多评论
0.0417s