| | |
| | | import android.content.Context; |
| | | import android.content.Intent; |
| | | import android.graphics.ImageFormat; |
| | | import android.graphics.Rect; |
| | | import android.graphics.SurfaceTexture; |
| | | import android.hardware.camera2.CameraAccessException; |
| | | import android.hardware.camera2.CameraCaptureSession; |
| | | import android.hardware.camera2.CameraCharacteristics; |
| | | import android.hardware.camera2.CameraDevice; |
| | | import android.hardware.camera2.CameraManager; |
| | | import android.hardware.camera2.CameraMetadata; |
| | | import android.hardware.camera2.CaptureRequest; |
| | | import android.hardware.camera2.params.StreamConfigurationMap; |
| | | import android.media.Image; |
| | | import android.media.ImageReader; |
| | | import android.media.MediaRecorder; |
| | |
| | | import android.support.annotation.NonNull; |
| | | import android.util.AttributeSet; |
| | | import android.util.Log; |
| | | import android.util.Range; |
| | | import android.view.Surface; |
| | | import android.view.TextureView; |
| | | import android.view.View; |
| | | import android.widget.LinearLayout; |
| | | import android.widget.TextView; |
| | | import android.widget.Toast; |
| | | |
| | | import com.whyc.util.HttpRequestUtil; |
| | | import com.whyc.util.tool.HttpReqData; |
| | | import com.whyc.util.tool.HttpRespData; |
| | | |
| | | import java.io.File; |
| | | import java.io.FileOutputStream; |
| | |
| | | private Handler mainHandler = new Handler(Looper.getMainLooper()); |
| | | private HandlerThread mThreadHandler; |
| | | ScheduledExecutorService executorService; |
| | | ScheduledExecutorService scheduledExecutorService; |
| | | |
| | | //主页面的视图 |
| | | private LinearLayout llUpText; |
| | |
| | | |
| | | private int imageWeight = 1920; |
| | | private int imageHeight = 1080; |
| | | Range<Integer> rangeMin; |
| | | |
| | | public Camera2TextureView2(Context context) { |
| | | super(context,null); |
| | |
| | | |
| | | public Camera2TextureView2(Context context, AttributeSet attrs) { |
| | | super(context, attrs); |
| | | executorService = Executors.newScheduledThreadPool(2); |
| | | executorService = Executors.newScheduledThreadPool(4); |
| | | /*String url = "http://192.168.10.79:8919/fg/server/timestamp"; |
| | | executorService.execute(()-> { |
| | | HttpReqData httpReqData = new HttpReqData(url); |
| | |
| | | CameraManager cm = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE); |
| | | try { |
| | | String cameraId = cm.getCameraIdList()[0]; |
| | | CameraCharacteristics cameraCharacteristics = cm.getCameraCharacteristics(cameraId); |
| | | StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); |
| | | Range<Integer>[] availableFpsRanges = cameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES); |
| | | rangeMin = availableFpsRanges[0]; |
| | | cm.openCamera(cameraId,mDeviceStateCallback,null); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | |
| | | captureBuilder.addTarget(previewSurface); |
| | | |
| | | /*设置预览的界面*/ |
| | | //设置自动对焦模式 |
| | | //设置帧率 |
| | | captureBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, |
| | | rangeMin); |
| | | /*//设置自动对焦模式 |
| | | captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, |
| | | CaptureRequest.CONTROL_AF_MODE_AUTO); |
| | | // 设置自动曝光模式 |
| | |
| | | CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); |
| | | // 开始对焦 |
| | | captureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, |
| | | CameraMetadata.CONTROL_AF_TRIGGER_START); |
| | | CameraMetadata.CONTROL_AF_TRIGGER_START);*/ |
| | | captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, 90); |
| | | |
| | | mCaptureSession.setRepeatingRequest(captureBuilder.build(), null, mHandler); |
| | |
| | | } |
| | | |
| | | public void createRecorderSession(){ |
| | | //关闭预览,启动录像相关 |
| | | //关闭预览请求,启动录像相关 |
| | | try { |
| | | mCaptureSession.stopRepeating(); |
| | | }catch (Exception e){ |
| | |
| | | initRecorder(); |
| | | try{ |
| | | mMediaRecorder.prepare(); |
| | | mMediaRecorder.start(); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | |
| | | recordRequest = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); |
| | | |
| | | recordRequest.addTarget(previewSurface); |
| | | // recordRequest.addTarget(mImageReader.getSurface()); |
| | | recordRequest.addTarget(mMediaRecorder.getSurface()); |
| | | |
| | | mCaptureSession.setRepeatingRequest(recordRequest.build(), null, mHandler); // 开始录制视频 |
| | | mMediaRecorder.start(); |
| | | |
| | | //camera2 捕捉视频快照,1秒钟1次的定时任务 |
| | | CaptureRequest.Builder snapshotBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_VIDEO_SNAPSHOT); |
| | | snapshotBuilder.addTarget(surfaceForStream); |
| | | |
| | | executorService.scheduleAtFixedRate(() -> { |
| | | scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); |
| | | scheduledExecutorService.scheduleAtFixedRate(() -> { |
| | | try { |
| | | session.capture(snapshotBuilder.build(), null, mHandler); |
| | | session.capture(snapshotBuilder.build(), null, null); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | |
| | | //这里只是演示test |
| | | llUpText.setVisibility(View.VISIBLE); |
| | | tvDevice.setText("这是测试的动态赋值"); |
| | | // 获取图片的字节数组 |
| | | ByteBuffer buffer = image.getPlanes()[0].getBuffer(); |
| | | byte[] data = new byte[buffer.remaining()]; |
| | | buffer.get(data); |
| | | // 保存图片到相册 |
| | | saveImageToGallery(data); |
| | | // 释放图像资源 |
| | | image.close(); |
| | | executorService.execute(() -> { |
| | | saveImageToGallery(image); |
| | | }); |
| | | |
| | | }; |
| | | |
| | | private void saveImageToGallery(byte[] data) { |
| | | private void saveImageToGallery(Image image) { |
| | | // 定义图片的保存路径和文件名 |
| | | String fileName = "IMG_" + System.currentTimeMillis() + ".jpg"; |
| | | String filePath = Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS).getAbsolutePath() + "/yc_test"+ File.separator + fileName; |
| | | |
| | | // 获取图片的字节数组 |
| | | ByteBuffer buffer = image.getPlanes()[0].getBuffer(); |
| | | byte[] data = new byte[buffer.remaining()]; |
| | | buffer.get(data); |
| | | // 创建文件输出流 |
| | | try { |
| | | FileOutputStream fos = new FileOutputStream(filePath); |
| | | fos.write(data); |
| | | fos.close(); |
| | | |
| | | image.close(); |
| | | // 通知图库更新 |
| | | MediaScannerConnection.scanFile(mContext, new String[]{filePath}, null, null); |
| | | |
| | |
| | | } |
| | | |
| | | public void stopRecording() { |
| | | //这里只是演示test |
| | | llUpText.setVisibility(View.GONE); |
| | | try { |
| | | // 停止录制视频,关闭录像请求 |
| | | mMediaRecorder.stop(); |
| | | //关闭定时视频快照 |
| | | scheduledExecutorService.shutdownNow(); |
| | | mCaptureSession.stopRepeating(); |
| | | //停止画面图片监听 |
| | | mImageReader.close(); |
| | | // 停止录制视频 |
| | | try { |
| | | executorService.shutdownNow(); |
| | | mMediaRecorder.stop(); |
| | | //这里只是演示test |
| | | llUpText.setVisibility(View.GONE); |
| | | //启动预览 |
| | | createPreviewSession(); |
| | | } catch (IllegalStateException e) { |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } finally { |
| | | // mMediaRecorder.reset(); |
| | | mMediaRecorder.reset(); |
| | | // mMediaRecorder.release(); |
| | | // mMediaRecorder = null; |
| | | } |
| | | isRecording = false; |
| | | |
| | | // 关闭相机预览会话 |
| | | // if (captureSession != null) { |
| | | // captureSession.close(); |
| | | // captureSession = null; |
| | | // } |
| | | |
| | | //图库更新 |
| | | addToGallery(recorderPath); |
| | | isRecording = false; |
| | | } |
| | | |
| | | } |
| | | |
| | | private void addToGallery(String videoFilePath) { |