admin管理员组文章数量:1516870
安卓Camera2悬浮窗录像
1.添加权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.RECORD_VIDEO"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
录像要用到的权限,动态申请一下
2.WindowManager添加一个窗口
private WindowManager mWindowManager;private WindowManager.LayoutParams mLayoutParams;private View mView;private void initFloatWindow() {mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);mLayoutParams = new WindowManager.LayoutParams();if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;} else {mLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;}mLayoutParams.format = PixelFormat.RGBA_8888;mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;mLayoutParams.flags =WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;//窗口大小mLayoutParams.width = 400;mLayoutParams.height = 500;//窗口出现位置mLayoutParams.x = 0;mLayoutParams.y = 0;LayoutInflater layoutInflater = LayoutInflater.from(this);//布局文件中需要一个SurfaceViewmView = layoutInflater.inflate(R.layout.float_recorder_window, null);mView.setOnTouchListener(new FloatingOnTouchListener());//触摸移动窗口mWindowManager.addView(mView, mLayoutParams);//添加悬浮窗口prepareCamera2();}private class FloatingOnTouchListener implements View.OnTouchListener {private int x;private int y;@Overridepublic boolean onTouch(View view, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:x = (int) event.getRawX();y = (int) event.getRawY();break;case MotionEvent.ACTION_MOVE:int nowX = (int) event.getRawX();int nowY = (int) event.getRawY();int movedX = nowX - x;int movedY = nowY - y;x = nowX;y = nowY;mLayoutParams.x = mLayoutParams.x + movedX;mLayoutParams.y = mLayoutParams.y + movedY;mWindowManager.updateViewLayout(view, mLayoutParams);break;default:break;}return true;}}
3.初始化SurfaceView
private CameraManager mCameraManager;private CameraCharacteristics mCameraCharacteristics;private SurfaceView mSurfaceView;private SurfaceHolder mSurfaceHolder;private Handler childHandler, mainHandler;private String mCameraID;//摄像头 0 为后 1 为前private ImageReader mImageReader;private CameraCaptureSession mCameraCaptureSession;private CameraDevice mCameraDevice;private MediaRecorder mMediaRecorder;private void prepareCamera2() {mSurfaceView = mView.findViewById(R.id.recorder_window);mSurfaceHolder = mSurfaceView.getHolder();mSurfaceHolder.setKeepScreenOn(true);mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {@RequiresApi(api = Build.VERSION_CODES.KITKAT)@Overridepublic void surfaceCreated(@NonNull SurfaceHolder holder) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {openCamera2();}}@Overridepublic void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width,int height) {}@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)@Overridepublic void surfaceDestroyed(@NonNull SurfaceHolder holder) {if (null != mCameraDevice) {mCameraDevice.close();mCameraDevice = null;}}});}
4.打开摄像头
@SuppressLint("MissingPermission")private void openCamera2() {mMediaRecorder = new MediaRecorder();HandlerThread handlerThread = new HandlerThread("Camera2");handlerThread.start();childHandler = new Handler(handlerThread.getLooper());mainHandler = new Handler(Looper.getMainLooper());//拍照回调if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {mImageReader = ImageReader.newInstance(400, 500, ImageFormat.JPEG, 1);mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {@Overridepublic void onImageAvailable(ImageReader reader) {Image image = reader.acquireNextImage();ByteBuffer byteBuffer = image.getPlanes()[0].getBuffer();byte[] bytes = new byte[byteBuffer.remaining()];byteBuffer.get(bytes);final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);//处理照片//image.close();}}, mainHandler);}//打开摄像头try {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);CameraDevice.StateCallback deviceCallBack = new CameraDevice.StateCallback() {@Overridepublic void onOpened(@NonNull CameraDevice camera) {Log.i(TAG, "onOpened: ");mCameraDevice = camera;startRecorder();}@Overridepublic void onDisconnected(@NonNull CameraDevice camera) {}@Overridepublic void onError(@NonNull CameraDevice camera, int error) {}};mCameraManager.openCamera("0", deviceCallBack, mainHandler);}} catch (Exception e) {e.printStackTrace();}}
这里的两个Handler我也没搞懂干嘛用的,好兄弟可以研究下
5.开始录像
private void startRecorder() {File path = new File(Environment.getExternalStorageDirectory());//视频存储位置if (!path.exists()) {path.mkdir();}String fileName = "test.mp4"; //文件名File video = new File(path, fileName);//配置录像mMediaRecorder.reset();CamcorderProfile mProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_480P);mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//使用麦克风mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);//使用摄像头获取对象mMediaRecorder.setOutputFormat(mProfile.fileFormat);mMediaRecorder.setAudioEncoder(mProfile.audioCodec);mMediaRecorder.setVideoEncoder(mProfile.videoCodec);mMediaRecorder.setOutputFile(video.getAbsolutePath());mMediaRecorder.setVideoSize(mProfile.videoFrameWidth, mProfile.videoFrameHeight);mMediaRecorder.setVideoFrameRate(30);mMediaRecorder.setVideoEncodingBitRate(mProfile.videoBitRate);mMediaRecorder.setAudioEncodingBitRate(mProfile.audioBitRate);mMediaRecorder.setAudioChannels(mProfile.audioChannels);mMediaRecorder.setAudioSamplingRate(mProfile.audioSampleRate);mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());mMediaRecorder.setOrientationHint(90);try {mMediaRecorder.prepare();} catch (IOException e) {e.printStackTrace();}//打开预览try {final CaptureRequest.Builder previewBuilder =mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);//第一Target不添加视频无法播放,第二Target不添加无法预览previewBuilder.addTarget(mMediaRecorder.getSurface());previewBuilder.addTarget(mSurfaceHolder.getSurface());mCameraDevice.createCaptureSession(Arrays.asList(mMediaRecorder.getSurface(),mSurfaceHolder.getSurface(), mImageReader.getSurface()),new CameraCaptureSession.StateCallback() {@Overridepublic void onConfigured(@NonNull CameraCaptureSession session) {mCameraCaptureSession = session;CaptureRequest previewRequest = previewBuilder.build();try {mCameraCaptureSession.setRepeatingRequest(previewRequest, null,childHandler);} catch (CameraAccessException e) {e.printStackTrace();}}@Overridepublic void onConfigureFailed(@NonNull CameraCaptureSession session) {}}, childHandler);mMediaRecorder.start();} catch (CameraAccessException e) {e.printStackTrace();}}
6.拍照方法
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();static {ORIENTATIONS.append(Surface.ROTATION_0, 90);ORIENTATIONS.append(Surface.ROTATION_90, 0);ORIENTATIONS.append(Surface.ROTATION_180, 270);ORIENTATIONS.append(Surface.ROTATION_270, 180);}
public void takePhoto() {if (mCameraDevice == null) return;final CaptureRequest.Builder captureBuilder;try {captureBuilder =mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);captureBuilder.addTarget(mImageReader.getSurface());captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);//获取手机方向int rotation = getWindowManager().getDefaultDisplay().getRotation();captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));mCameraCaptureSession.capture(captureBuilder.build(), null, childHandler);} catch (CameraAccessException e) {e.printStackTrace();}}
7.结束录制
private void stopRecorder() {if (mView!=null)mWindowManager.removeView(mView);if (mMediaRecorder != null) {mMediaRecorder.setOnErrorListener(null);mMediaRecorder.setOnInfoListener(null);mMediaRecorder.setPreviewDisplay(null);} try {mMediaRecorder.stop();} catch (Exception e) {e.printStackTrace();}mMediaRecorder.release();}
查了好久才做出来 太麻烦了T T
本文标签: 安卓Camera2悬浮窗录像
版权声明:本文标题:安卓Camera2悬浮窗录像 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.betaflare.com/biancheng/1706423598a692957.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。


发表评论