From efa5fe48ebc866ec07a597ef551cf7e13c3b7aba Mon Sep 17 00:00:00 2001 From: whycxzp <glperry@163.com> Date: 星期六, 27 七月 2024 17:27:02 +0800 Subject: [PATCH] 更新单摄像头的AR方案 --- app/src/main/java/com/whyc/widget/Camera2TextureView4.java | 461 +++++++++++++++++++-------------------------------------- 1 files changed, 153 insertions(+), 308 deletions(-) diff --git a/app/src/main/java/com/whyc/widget/Camera2TextureView4.java b/app/src/main/java/com/whyc/widget/Camera2TextureView4.java index e6d2661..f7c46cc 100644 --- a/app/src/main/java/com/whyc/widget/Camera2TextureView4.java +++ b/app/src/main/java/com/whyc/widget/Camera2TextureView4.java @@ -2,19 +2,14 @@ import android.annotation.SuppressLint; import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.graphics.ImageFormat; -import android.graphics.Rect; import android.graphics.SurfaceTexture; -import android.graphics.YuvImage; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCaptureSession; import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CameraManager; -import android.hardware.camera2.CameraMetadata; import android.hardware.camera2.CaptureRequest; import android.media.Image; import android.media.ImageReader; @@ -24,7 +19,6 @@ import android.media.MediaFormat; import android.media.MediaMuxer; import android.media.MediaScannerConnection; -import android.net.Uri; import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; @@ -32,16 +26,15 @@ import android.util.AttributeSet; 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 java.io.ByteArrayOutputStream; +import com.whyc.util.BitmapUtil; +import com.whyc.util.YUVUtil; + import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; -import java.nio.BufferOverflowException; import java.nio.ByteBuffer; import java.util.Arrays; @@ -49,23 +42,34 @@ /** * 杩欎釜閲囩敤ImageReader瑙嗛甯ф潵鑾峰彇瑙嗛鍜屽鐞嗗浘鐗� + * TODO 鍏抽棴褰曞儚鍑虹幇mMediaMuxer 寮傚父 * */ public class Camera2TextureView4 extends TextureView { private Context mContext; private CameraDevice mCameraDevice; - private CaptureRequest.Builder captureBuilder = null; + private CaptureRequest.Builder previewCaptureBuilder = null; + private CaptureRequest.Builder videoCaptureBuilder = null; private CameraCaptureSession mCaptureSession; private ImageReader mImageReader; private Surface previewSurface; private MediaCodec mMediaCodec; private MediaMuxer mMediaMuxer; - private Handler mBackgroundHandler; - private HandlerThread mBackgroundThread; + private int videoWidth = 1920; private int videoHeight = 1080; + /** 绾跨▼澶勭悊鍣�*/ + private HandlerThread videoThread; + private HandlerThread previewThread; + private HandlerThread imageThread; + private HandlerThread cameraThread; + + private Handler videoThreadHandler; + private Handler previewThreadHandler; + private Handler imageThreadHandler; + private Handler cameraThreadHandler; //瑙嗛鍜屽浘鐗囩殑鏂囦欢澶硅矾寰� File fileDir = new File(Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS).getAbsolutePath() + "/yc_test/"); String recorderPath = fileDir.getAbsolutePath() + File.separator + System.currentTimeMillis() + ".mp4"; @@ -81,20 +85,6 @@ public Camera2TextureView4(Context context, AttributeSet attrs) throws IOException { super(context, attrs); mContext = context; - mBackgroundThread = new HandlerThread("Camera2VideoRecorder"); - mBackgroundThread.start(); - mBackgroundHandler = new Handler(mBackgroundThread.getLooper()); - mImageReader = ImageReader.newInstance(videoWidth, videoHeight, ImageFormat.YUV_420_888, 2); - - mMediaCodec = createAndConfigureEncoder(videoWidth, videoHeight); -// mMediaCodec.start(); -// String recorderPath = fileDir.getAbsolutePath()+File.separator + System.currentTimeMillis() + ".mp4"; - /*try { - this.mMediaMuxer = new MediaMuxer(recorderPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); - this.mMediaMuxer.setOrientationHint(90); - }catch (Exception e){ - e.printStackTrace(); - }*/ } public void init(LinearLayout llUpText, TextView tvDevice) { @@ -129,6 +119,13 @@ CameraManager cm = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE); try { String cameraId = cm.getCameraIdList()[0]; + //鍒濆鍖栭瑙堢嚎绋� + initPreviewThreadHandler(); + cameraThread = new HandlerThread("Camera2Video"); + cameraThread.start(); + cameraThreadHandler = new Handler(cameraThread.getLooper()); +// cm.openCamera(cameraId,mDeviceStateCallback,previewThreadHandler); +// cm.openCamera(cameraId,mDeviceStateCallback,cameraThreadHandler); cm.openCamera(cameraId,mDeviceStateCallback,null); }catch (Exception e){ e.printStackTrace(); @@ -138,11 +135,13 @@ private CameraDevice.StateCallback mDeviceStateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice cameraDevice) { + //棰勮鍜屽浘鍍忕洃娴� mCameraDevice = cameraDevice; SurfaceTexture surfaceTexture = getSurfaceTexture(); surfaceTexture.setDefaultBufferSize(1920, 1080); previewSurface = new Surface(surfaceTexture); - + //鍥惧儚鐩戞祴 + mImageReader = ImageReader.newInstance(videoWidth, videoHeight, ImageFormat.YUV_420_888, 2); try { createPreviewSession(); }catch (Exception e){ @@ -163,41 +162,39 @@ private void createPreviewSession() { try { - mCameraDevice.createCaptureSession(Arrays.asList(previewSurface), new CameraCaptureSession.StateCallback() { + mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, mImageReader.getSurface()), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession session) { - mCaptureSession = session; - startPreview(mCameraDevice); + try { + mCaptureSession = session; + previewCaptureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); + previewCaptureBuilder.addTarget(previewSurface); + + /*璁剧疆棰勮鐨勭晫闈�*/ + //璁剧疆鑷姩瀵圭劍妯″紡 + previewCaptureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO); + // 璁剧疆鑷姩鏇濆厜妯″紡 + previewCaptureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); + // captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, 90); + startPreview(); + }catch (Exception e){ + e.printStackTrace(); + } } @Override public void onConfigureFailed(@NonNull CameraCaptureSession session) { } - }, null); + }, previewThreadHandler); }catch (Exception e){ e.printStackTrace(); } } - private void startPreview(CameraDevice cameraDevice) { + private void startPreview() { //鍚姩棰勮 try { - captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); - captureBuilder.addTarget(previewSurface); - - /*璁剧疆棰勮鐨勭晫闈�*/ - //璁剧疆鑷姩瀵圭劍妯″紡 - captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, - CaptureRequest.CONTROL_AF_MODE_AUTO); - // 璁剧疆鑷姩鏇濆厜妯″紡 - captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, - CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); - // 寮�濮嬪鐒� - captureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, - CameraMetadata.CONTROL_AF_TRIGGER_START); - captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, 90); - - mCaptureSession.setRepeatingRequest(captureBuilder.build(), null, mBackgroundHandler); + mCaptureSession.setRepeatingRequest(previewCaptureBuilder.build(), null, previewThreadHandler); } catch (CameraAccessException e) { e.printStackTrace(); } @@ -225,27 +222,41 @@ e.printStackTrace(); } }*/ + /**瑙嗛褰曞埗*/ public void createRecorderSession() throws IOException { + try { + //鍏抽棴棰勮 + mCaptureSession.stopRepeating(); + } catch (CameraAccessException e) { + e.printStackTrace(); + } + //鍏抽棴棰勮绾跨▼ + stopPreviewThreadHandler(); + //鍒濆鍖栧綍鍒剁嚎绋� + initThreadHandlerForRecording(); + mImageReader.setOnImageAvailableListener(mImageReaderListener, imageThreadHandler); + String recorderPath = fileDir.getAbsolutePath()+File.separator + System.currentTimeMillis() + ".mp4"; try { - this.mMediaMuxer = new MediaMuxer(recorderPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); - this.mMediaMuxer.setOrientationHint(90); + mMediaCodec = createAndConfigureEncoder(videoWidth, videoHeight); + mMediaMuxer = new MediaMuxer(recorderPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); +// mMediaMuxer.setOrientationHint(90); - mImageReader.setOnImageAvailableListener(mImageReaderListener, null); - captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); - captureBuilder.addTarget(previewSurface); - captureBuilder.addTarget(mImageReader.getSurface()); + videoCaptureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); + videoCaptureBuilder.addTarget(previewSurface); + videoCaptureBuilder.addTarget(mImageReader.getSurface()); + mCaptureSession.setRepeatingRequest(videoCaptureBuilder.build(), null, videoThreadHandler); } catch (Exception e) { e.printStackTrace(); } - try { + /*try { mCameraDevice.createCaptureSession(Arrays.asList(previewSurface,mImageReader.getSurface()), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession session) { mCaptureSession = session; try { //camera2 瑙嗛褰曞埗妯″紡 - captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE); +// captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE); mCaptureSession.setRepeatingRequest(captureBuilder.build(), null, mBackgroundHandler); } catch (Exception e) { @@ -261,7 +272,7 @@ } catch (Exception e) { e.printStackTrace(); - } + }*/ } private int mVideoTrackIndex = -1; @@ -269,18 +280,23 @@ private ImageReader.OnImageAvailableListener mImageReaderListener = reader -> { Image image = reader.acquireNextImage(); + // Image imageCopy = ImageReader.newInstance(videoWidth, videoHeight, ImageFormat.YUV_420_888, 1).acquireLatestImage(); byte[] nv12 = new byte[I420size]; - YUVToNV21_NV12(image,nv12,videoWidth,videoHeight,"NV12"); + byte[] nv21 = new byte[I420size]; + + YUVUtil.YUVToNV21_NV12(image,nv12,videoWidth,videoHeight,"NV12"); long now = image.getTimestamp(); image.close(); //鍥剧墖鎴浘 SharedPreferences camera2Time = mContext.getSharedPreferences("camera2Time", Context.MODE_PRIVATE); long lastTime = camera2Time.getLong("time", 0); - - if (lastTime == 0 || now-lastTime > 1000000000) { + long secondsGap = (now - lastTime) / 1000000000; + if (lastTime == 0 || secondsGap > 2) { camera2Time.edit().putLong("time", now).apply(); - Bitmap bitmap = nv21ToBitmap(nv12, videoWidth, videoHeight); - saveBitmapToFile(bitmap); + //闇�瑕佸皢nv12杞寲涓簄v21鍚庤繘琛屽浘鐗囧瓨鍌� + nv21 = convertNV12toNV21(nv12); + Bitmap bitmap = BitmapUtil.nv21ToBitmap(nv21, videoWidth, videoHeight); + BitmapUtil.saveBitmapToFile(bitmap); } // 鎻愪氦鏁版嵁缁橫ediaCodec @@ -314,259 +330,42 @@ } } - /*ByteBuffer encodedData = mMediaCodec.getOutputBuffer(outputBufferIndex); - if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) { - // 濡傛灉MediaMuxer杩樻病鏈夊噯澶囧ソ锛屾坊鍔犺棰戣建閬� - - // 鍐欏叆鏁版嵁鍒癕ediaMuxer - MediaFormat format = mMediaCodec.getOutputFormat(); - int trackIndex = mMediaMuxer.addTrack(format); - if(trackIndex) - mMediaMuxer.start(); - - encodedData.position(bufferInfo.offset); - encodedData.limit(bufferInfo.offset + bufferInfo.size); - mMediaMuxer.writeSampleData(trackIndex, encodedData, bufferInfo); - } - - mMediaCodec.releaseOutputBuffer(outputBufferIndex, false);*/ - }; - - private static void YUVToNV21_NV12(Image image, byte[] nv21, int w, int h,String type) { - Image.Plane[] planes = image.getPlanes(); - int remaining0 = planes[0].getBuffer().remaining(); - int remaining1 = planes[1].getBuffer().remaining(); - int remaining2 = planes[2].getBuffer().remaining(); - //鍒嗗埆鍑嗗涓変釜鏁扮粍鎺ユ敹YUV鍒嗛噺銆� - byte[] yRawSrcBytes = new byte[remaining0]; - byte[] uRawSrcBytes = new byte[remaining1]; - byte[] vRawSrcBytes = new byte[remaining2]; - planes[0].getBuffer().get(yRawSrcBytes); - planes[1].getBuffer().get(uRawSrcBytes); - planes[2].getBuffer().get(vRawSrcBytes); - int j = 0, k = 0; - boolean flag = type.equals("NV21"); - for (int i = 0; i < nv21.length; i++) { - if (i < w * h) { - //棣栧厛濉厖w*h涓猋鍒嗛噺 - nv21[i] = yRawSrcBytes[i]; - } else { - if (flag) { - //鑻V21绫诲瀷 鍒橸鍒嗛噺鍒嗛厤瀹屽悗绗竴涓皢鏄疺鍒嗛噺 - nv21[i] = vRawSrcBytes[j]; - //PixelStride鏈夌敤鏁版嵁姝ラ暱 = 1绱у噾鎸夐『搴忓~鍏咃紝=2姣忛棿闅斾竴涓~鍏呮暟鎹� - j += planes[1].getPixelStride(); - } else { - //鑻V12绫诲瀷 鍒橸鍒嗛噺鍒嗛厤瀹屽悗绗竴涓皢鏄疷鍒嗛噺 - nv21[i] = uRawSrcBytes[k]; - //PixelStride鏈夌敤鏁版嵁姝ラ暱 = 1绱у噾鎸夐『搴忓~鍏咃紝=2姣忛棿闅斾竴涓~鍏呮暟鎹� - k += planes[2].getPixelStride(); - } - //绱ф帴鐫�鍙互浜ら敊UV鎴栬�匳U鎺掑垪涓嶅仠鐨勬敼鍙榝lag鏍囧織鍗冲彲浜ら敊鎺掑垪 - flag = !flag; - } + public byte[] convertNV12toNV21(byte[] nv12) { + int length = nv12.length; + byte[] nv21 = new byte[length]; + // Copy Y component + System.arraycopy(nv12, 0, nv21, 0, length - (length / 4)); + // Copy and swap U/V components + for (int i = length - (length / 4), j = length - (length / 4); i < length; i += 2, j += 2) { + nv21[j] = nv12[i + 1]; + nv21[j + 1] = nv12[i]; } - } - - public static byte[] imageToNV12(Image image) { - final int width = image.getWidth(); - final int height = image.getHeight(); - - Image.Plane[] planes = image.getPlanes(); - byte[] yuv = new byte[width * height *2]; - - // Y component - ByteBuffer yBuffer = planes[0].getBuffer(); - int ySize = yBuffer.remaining(); - yBuffer.get(yuv, 0, ySize); - - // U and V components - ByteBuffer uBuffer = planes[1].getBuffer(); - ByteBuffer vBuffer = planes[2].getBuffer(); - int uSize = uBuffer.remaining(); - int vSize = vBuffer.remaining(); - - uBuffer.get(yuv, ySize, uSize); - vBuffer.get(yuv, ySize + uSize, vSize); - - // Swap U and V for NV21 format - byte[] swapped = new byte[yuv.length]; - System.arraycopy(yuv, 0, swapped, 0, ySize); - System.arraycopy(yuv, ySize + uSize, swapped, ySize + uSize, vSize); - System.arraycopy(yuv, ySize, swapped, ySize, uSize); - - return swapped; - } - - /*private void encodeFrame(Image image) { - MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); - int inputBufferId = mMediaCodec.dequeueInputBuffer(100); - if (inputBufferId >= 0) { - ByteBuffer inputBuffer = mMediaCodec.getInputBuffers()[inputBufferId]; - inputBuffer.clear(); - - //杩欓噷鏄噸鐐�! - Image.Plane[] planes = image.getPlanes(); - ByteBuffer[] yuvPlanes = new ByteBuffer[planes.length]; - int[] offsets = new int[planes.length]; - int[] strides = new int[planes.length]; - - for (int i = 0; i < planes.length; i++) { - yuvPlanes[i] = planes[i].getBuffer(); - offsets[i] = yuvPlanes[i].position(); - strides[i] = planes[i].getRowStride(); - } - - int height = image.getHeight(); - int ySize = calculateSize(strides[0], image.getHeight()); - int uSize = calculateSize(strides[1], image.getHeight() / 2); - int vSize = calculateSize(strides[2], image.getHeight() / 2); - - if (ySize + uSize + vSize > inputBuffer.capacity()) { - throw new BufferOverflowException(); - } - // Copy Y plane - copyPlaneData(yuvPlanes[0], inputBuffer, ySize, strides[0],height); - - // Copy U plane - copyPlaneData(yuvPlanes[1], inputBuffer, uSize, strides[1],height/2); - - // Copy V plane - copyPlaneData(yuvPlanes[2], inputBuffer, vSize, strides[2],height/2); - - mMediaCodec.queueInputBuffer( - inputBufferId, - 0, - ySize + uSize + vSize, - image.getTimestamp(), - 0 - ); - *//*int ySize = planes[0].getBuffer().remaining(); - int uvSize = planes[1].getBuffer().remaining(); - - // Copy Y plane - planes[0].getBuffer().rewind(); - inputBuffer.put(planes[0].getBuffer()); - - // Copy U and V planes - planes[1].getBuffer().rewind(); - inputBuffer.put(planes[1].getBuffer()); - planes[2].getBuffer().rewind(); - inputBuffer.put(planes[2].getBuffer()); - - mMediaCodec.queueInputBuffer( - inputBufferId, - 0, - ySize + 2 * uvSize, // Size of YUV data - image.getTimestamp(), - 0 - );*//* - - } - int encoderStatus = mMediaCodec.dequeueOutputBuffer(bufferInfo, 1000); - MediaFormat format = mMediaCodec.getOutputFormat(); - int track = mMediaMuxer.addTrack(format); - if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { - mMediaMuxer.start(); - } else if (encoderStatus >= 0) { - ByteBuffer encodedData = mMediaCodec.getOutputBuffers()[encoderStatus]; - if (encodedData != null && encodedData.position() < encodedData.limit()) { - mMediaMuxer.writeSampleData(track, encodedData, bufferInfo); - } - mMediaCodec.releaseOutputBuffer(encoderStatus, false); - } - } - - private int calculateSize(int stride, int height) { - return stride * height; - } - - private void copyPlaneData(ByteBuffer src, ByteBuffer dst, int size, int stride,int height) { - int rowPadding = stride - (size / height); - int shift = 0; - while (src.hasRemaining()) { - dst.put(src.get()); - shift++; - if (shift == stride) { - shift = 0; - dst.position(dst.position() + rowPadding); - } - } - }*/ - - private static Bitmap nv21ToBitmap(byte[] nv21, int width, int height) { - Bitmap bitmap = null; - try { - YuvImage image = new YuvImage(nv21, ImageFormat.NV21, width, height, null); - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - //杈撳嚭鍒板搴旀祦 - image.compressToJpeg(new Rect(0, 0, width, height), 100, stream); - //瀵瑰簲瀛楄妭娴佺敓鎴恇itmap - bitmap = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size()); - stream.close(); - } catch (IOException e) { - e.printStackTrace(); - } - return bitmap; - } - - private void saveBitmapToFile(Bitmap bitmap) { - // 瀹氫箟鍥剧墖鐨勪繚瀛樿矾寰勫拰鏂囦欢鍚� - String fileName = "IMG_" + System.currentTimeMillis() + ".jpg"; - String filePath = Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS).getAbsolutePath() + "/yc_test"+ File.separator + fileName; - try{ - FileOutputStream fos = new FileOutputStream(filePath); - bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); - fos.flush(); - }catch (Exception e){ - e.printStackTrace(); - } - } - private void saveImageToGallery(byte[] data) { - // 瀹氫箟鍥剧墖鐨勪繚瀛樿矾寰勫拰鏂囦欢鍚� - String fileName = "IMG_" + System.currentTimeMillis() + ".jpg"; - String filePath = Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS).getAbsolutePath() + "/yc_test"+ File.separator + fileName; - - // 鍒涘缓鏂囦欢杈撳嚭娴� - try { - FileOutputStream fos = new FileOutputStream(filePath); - fos.write(data); - fos.close(); - - // 閫氱煡鍥惧簱鏇存柊 - MediaScannerConnection.scanFile(mContext, new String[]{filePath}, null, null); - - // 鍦ㄦ煇浜涜澶囦笂锛屽彲鑳介渶瑕佸彂閫佸箍鎾�氱煡鎵嶈兘浣垮浘鐗囩珛鍗冲嚭鐜板湪鐩稿唽涓� - mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(filePath)))); - - // 鏄剧ず淇濆瓨鎴愬姛鐨勬彁绀� - // Toast.makeText(this, "鍥剧墖淇濆瓨鎴愬姛", Toast.LENGTH_SHORT).show(); - } catch (IOException e) { - e.printStackTrace(); - // 鏄剧ず淇濆瓨澶辫触鐨勬彁绀� - // Toast.makeText(this, "鍥剧墖淇濆瓨澶辫触", Toast.LENGTH_SHORT).show(); - } + return nv21; } public void stopRecording() { - //杩欓噷鍙槸婕旂ずtest - llUpText.setVisibility(View.GONE); - //鍋滄鐢婚潰鍥剧墖鐩戝惉 - mImageReader.close(); - this.mMediaCodec.stop(); - this.mMediaCodec.release(); - this.mMediaMuxer.stop(); - this.mMediaMuxer.release(); - // 鍋滄褰曞埗瑙嗛 try { -// createPreviewSession(); - } catch (IllegalStateException e) { + //鍋滄褰曞埗瑙嗛,鍋滄鐢婚潰鍥剧墖鐩戝惉 + mMediaMuxer.stop(); + mMediaCodec.stop(); + + //鍋滄褰曞儚Repeating + mCaptureSession.stopRepeating(); + //绾跨▼鐩戞帶鍋滄 + mImageReader.setOnImageAvailableListener(null, null); + //鍋滄褰曞埗瑙嗛绾跨▼ + stopThreadHandlerForRecording(); + //杩欓噷鍙槸婕旂ずtest +// llUpText.setVisibility(View.GONE); + + + startPreview(); + } catch (IllegalStateException | CameraAccessException e) { e.printStackTrace(); } finally { -// mMediaRecorder.reset(); -// mMediaRecorder.release(); -// mMediaRecorder = null; + mMediaCodec.release(); + mMediaMuxer.release(); } // 鍏抽棴鐩告満棰勮浼氳瘽 @@ -623,4 +422,50 @@ return null; } + private void initPreviewThreadHandler(){ + //棰勮鐨勫鐞嗙嚎绋� + previewThread = new HandlerThread("camera2Preview"); + previewThread.start(); + previewThreadHandler = new Handler(previewThread.getLooper()); + } + + private void stopPreviewThreadHandler(){ + //棰勮鐨勫鐞嗙嚎绋� + try { + previewThread.quitSafely(); + previewThread.join(); + previewThread = null; + previewThreadHandler = null; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + private void initThreadHandlerForRecording() { + //褰曞儚鐨勫鐞嗙嚎绋� + videoThread = new HandlerThread("Camera2Video"); + videoThread.start(); + videoThreadHandler = new Handler(videoThread.getLooper()); + + //鍥惧儚鐩戞祴鐨勫鐞嗙嚎绋� + imageThread = new HandlerThread("camera2Image"); + imageThread.start(); + imageThreadHandler = new Handler(imageThread.getLooper()); + } + + private void stopThreadHandlerForRecording() { + try { + videoThread.quitSafely(); + videoThread.join(); + videoThread = null; + videoThreadHandler = null; + + imageThread.quitSafely(); + imageThread.join(); + imageThread = null; + imageThreadHandler = null; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } } -- Gitblit v1.9.1