Как начать захват видео автоматически при запуске приложения ⇐ Android
-
Anonymous
Как начать захват видео автоматически при запуске приложения
Я хочу показать предварительный просмотр камеры и начать съемку сразу же, как только предварительный просмотр будет готов (на основе API камеры2)
Чтобы сделать это просто, я создаю пример приложения, которое должно автоматически начинать захват видео, когда предварительный просмотр готов, на основе примера Google camera2Video, и модифицировать его в соответствии с моими потребностями.
Вот мой код для метода OnCreate:
if (null == saveInstanceState) { getFragmentManager().beginTransaction() .replace(R.id.container, camera2VideoFragment) .совершить(); } Runnable runnable = новый Runnable() { @Override общественный недействительный запуск () { while (!camera2VideoFragment.isCameraReady) { пытаться { Log.d("статус камеры", String.valueOf(camera2VideoFragment.isCameraReady)); Thread.sleep(500); } catch (InterruptedException e) { е.printStackTrace(); } } camera2VideoFragment.captureVideo(); } }; Runnable.run(); В классе Camera2VideoFragment я добавляю общедоступную статическую логическую переменную initlize в значение false и изменяю ее на true, когда камера готова, используя CameraDevice.StateCallback, например:< /п> private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice cameraDevice) { mCameraDevice = cameraDevice; НачатьПредварительный просмотр(); mCameraOpenCloseLock.release(); isCameraReady = правда; // Устанавливаем здесь логическое значение true если (нуль!= mTextureView) { configureTransform(mTextureView.getWidth(), mTextureView.getHeight()); } } Проблема: isCameraReady остается ложным навсегда, когда я использую проверку while (* Если я начинаю захват после события кнопки, значение истинно, и все работает нормально)
Вопрос: Как я могу узнать, когда предварительный просмотр готов, и начать захват видео автоматически, не нажимая ни на одну кнопку? (нажав кнопка будет останавливать запись, а не запускать ее)
Изменить
Ниже приведен соответствующий код Camera2VideoFragment. Полный код можно найти здесь.
публичный класс Camera2VideoFragment расширяет фрагмент реализует FragmentCompat.OnRequestPermissionsResultCallback { частный статический окончательный SparseIntArray ОРИЕНТАЦИИ = новый SparseIntArray(); частная статическая окончательная строка TAG = "Camera2VideoFragment"; частный статический финал int REQUEST_VIDEO_PERMISSIONS = 1; частная статическая окончательная строка FRAGMENT_DIALOG = «диалог»; статический { ОРИЕНТАЦИИ.append(Surface.ROTATION_0, 90); ОРИЕНТАЦИИ.append(Surface.ROTATION_90, 0); ОРИЕНТАЦИИ.append(Surface.ROTATION_180, 270); ОРИЕНТАЦИИ.append(Surface.ROTATION_270, 180); } частный AutoFitTextureView mTextureView; частный CameraDevice mCameraDevice; частный CameraCaptureSession mPreviewSession; частный TextureView.SurfaceTextureListener mSurfaceTextureListener = новый TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable (SurfaceTexture SurfaceTexture, int ширина, int высота) { openCamera (ширина, высота); } @Override общественная пустота onSurfaceTextureSizeChanged (SurfaceTexture SurfaceTexture, int ширина, int высота) { configureTransform (ширина, высота); } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture SurfaceTexture) { вернуть истину; } @Override public void onSurfaceTextureUpdated (SurfaceTexture SurfaceTexture) { } }; частный размер mPreviewSize; частный размер mVideoSize; частный CaptureRequest.Builder mPreviewBuilder; частный MediaRecorder mMediaRecorder; частное статическое логическое значение mIsRecordingVideo; частный HandlerThread mBackgroundThread; частный обработчик mBackgroundHandler; частный семафор mCameraOpenCloseLock = новый семафор (1); public static Boolean isCameraReady = false; // Я добавляю эту переменную, чтобы узнать, когда я смогу начать запись частный CameraDevice.StateCallback mStateCallback = новый CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice cameraDevice) { mCameraDevice = cameraDevice; НачатьПредварительный просмотр(); mCameraOpenCloseLock.release(); isCameraReady = правда; // Здесь я устанавливаю логическое значение в true если (нуль!= mTextureView) { configureTransform(mTextureView.getWidth(), mTextureView.getHeight()); } } @Override public void onDisconnected (CameraDevice cameraDevice) { mCameraOpenCloseLock.release(); cameraDevice.close(); mCameraDevice = ноль; isCameraReady = ложь; } @Override public void onError (CameraDevice cameraDevice, ошибка int) { mCameraOpenCloseLock.release(); cameraDevice.close(); mCameraDevice = ноль; Активность активности = getActivity(); if (null != активность) { активность.окончание(); } isCameraReady = ложь; } }; публичный захват пустотыVideo() { если (mIsRecordingVideo) { остановитьЗаписьВидео(); } еще { начатьЗаписьВидео(); } } частный недействительный startBackgroundThread () { mBackgroundThread = новый HandlerThread («CameraBackground»); mBackgroundThread.start(); mBackgroundHandler = новый обработчик (mBackgroundThread.getLooper()); } частный недействительный stopBackgroundThread () { mBackgroundThread.quitSafely(); пытаться { mBackgroundThread.join(); mBackgroundThread = ноль; mBackgroundHandler = ноль; } catch (InterruptedException e) { е.printStackTrace(); } } Private void openCamera(int width, int height) { если (!hasPermissionsGranted(VIDEO_PERMISSIONS)) { запросвидеоразрешения(); возвращаться; } окончательная активность активности = getActivity(); if (null == Activity || Activity.isFinishing()) { возвращаться; } Менеджер CameraManager = (CameraManager) Activity.getSystemService(Context.CAMERA_SERVICE); пытаться { Log.d(TAG, "tryAcquire"); if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISCONDS)) { throw new RuntimeException("Время ожидания блокировки открытия камеры истекло."); } Строка cameraId = Manager.getCameraIdList()[0]; // Выбор размеров для предварительного просмотра камеры и записи видео Характеристики CameraCharacteristics = Manager.getCameraCharacteristics(cameraId); Карта StreamConfigurationMap = характеристики .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); mVideoSize = ChooseVideoSize(map.getOutputSizes(MediaRecorder.class)); mPreviewSize = ChooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), ширина, высота, mVideoSize); int ориентация = getResources().getConfiguration().orientation; если (ориентация == Configuration.ORIENTATION_LANDSCAPE) { mTextureView.setAspectRatio(mPreviewSize.getWidth(), mPreviewSize.getHeight()); } еще { mTextureView.setAspectRatio(mPreviewSize.getHeight(), mPreviewSize.getWidth()); } configureTransform (ширина, высота); mMediaRecorder = новый MediaRecorder (); Manager.openCamera(cameraId, mStateCallback, null); } catch (CameraAccessException e) { Toast.makeText(activity, «Невозможно получить доступ к камере», Toast.LENGTH_SHORT).show(); активность.окончание(); } catch (NullPointerException e) { // В настоящее время NPE генерируется, когда Camera2API используется, но не поддерживается на // устройство, на котором работает этот код. ErrorDialog.newInstance(getString(R.string.camera_error)) .show(getChildFragmentManager(), FRAGMENT_DIALOG); } catch (InterruptedException e) { throw new RuntimeException("Прервано при попытке заблокировать открытие камеры."); } } частный недействительный startPreview() { if (null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) { возвращаться; } пытаться { setUpMediaRecorder(); Текстура SurfaceTexture = mTextureView.getSurfaceTexture(); утвердить текстуру != null; текстура.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); Список поверхности = новый ArrayList(); Предварительный просмотр поверхностиSurface = новая поверхность (текстура); Surfaces.add(previewSurface); mPreviewBuilder.addTarget(previewSurface); Surface RecorderSurface = mMediaRecorder.getSurface(); Surfaces.add(recorderSurface); mPreviewBuilder.addTarget(recorderSurface); mCameraDevice.createCaptureSession(поверхности, новый CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession cameraCaptureSession) { mPreviewSession = cameraCaptureSession; обновить предпросмотр(); } @Override public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { Активность активности = getActivity(); if (null != активность) { Toast.makeText(активность, «Ошибка», Toast.LENGTH_SHORT).show(); } } }, mBackgroundHandler); isCameraReady = правда; } catch (CameraAccessException e) { е.printStackTrace(); } catch (IOException e) { е.printStackTrace(); } } частный недействительный updatePreview() { если (нуль == mCameraDevice) { возвращаться; } пытаться { setUpCaptureRequestBuilder (mPreviewBuilder); Поток HandlerThread = новый HandlerThread("CameraPreview"); поток.start(); mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, mBackgroundHandler); } catch (CameraAccessException e) { е.printStackTrace(); } } частный недействительный setUpCaptureRequestBuilder (CaptureRequest.Builder builder) { builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); } Private void configureTransform(int viewWidth, int viewHeight) { Активность активности = getActivity(); if (null == mTextureView || null == mPreviewSize || null == активность) { возвращаться; } int Rotation = Activity.getWindowManager().getDefaultDisplay().getRotation(); Матрица матрица = новая матрица(); RectF viewRect = новый RectF (0, 0, viewWidth, viewHeight); RectFufferRect = новый RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth()); float centerX = viewRect.centerX(); float centerY = viewRect.centerY(); if (Surface.ROTATION_90 == вращение || Surface.ROTATION_270 == вращение) { ufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY()); матрица.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL); масштаб с плавающей запятой = Math.max( (с плавающей запятой) viewHeight/mPreviewSize.getHeight(), (float) viewWidth/mPreviewSize.getWidth()); матрица.postScale(масштаб, масштаб, центрX, центрY); матрица.postRotate(90 * (поворот — 2), centerX, centerY); } mTextureView.setTransform(матрица); } Private void setUpMediaRecorder() выдает IOException { окончательная активность активности = getActivity(); если (нуль == активность) { возвращаться; } mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mMediaRecorder.setOutputFile(getVideoFile(activity).getAbsolutePath()); mMediaRecorder.setVideoEncodingBitRate(10000000); mMediaRecorder.setVideoFrameRate(30); mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight()); mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); int Rotation = Activity.getWindowManager().getDefaultDisplay().getRotation(); int ориентация = ORIENTATIONS.get(вращение); mMediaRecorder.setOrientationHint(ориентация); mMediaRecorder.prepare(); } частная пустота startRecordingVideo() { пытаться { mIsRecordingVideo = правда; mMediaRecorder.start(); } catch (IllegalStateException e) { е.printStackTrace(); } } частная пустота stopRecordingVideo() { mIsRecordingVideo = ложь; mMediaRecorder.stop(); mMediaRecorder.reset(); Активность активности = getActivity(); if (null != активность) { Toast.makeText(activity, "Видео сохранено: " + getVideoFile(activity), Toast.LENGTH_SHORT).show(); } НачатьПредварительный просмотр(); } }
Я хочу показать предварительный просмотр камеры и начать съемку сразу же, как только предварительный просмотр будет готов (на основе API камеры2)
Чтобы сделать это просто, я создаю пример приложения, которое должно автоматически начинать захват видео, когда предварительный просмотр готов, на основе примера Google camera2Video, и модифицировать его в соответствии с моими потребностями.
Вот мой код для метода OnCreate:
if (null == saveInstanceState) { getFragmentManager().beginTransaction() .replace(R.id.container, camera2VideoFragment) .совершить(); } Runnable runnable = новый Runnable() { @Override общественный недействительный запуск () { while (!camera2VideoFragment.isCameraReady) { пытаться { Log.d("статус камеры", String.valueOf(camera2VideoFragment.isCameraReady)); Thread.sleep(500); } catch (InterruptedException e) { е.printStackTrace(); } } camera2VideoFragment.captureVideo(); } }; Runnable.run(); В классе Camera2VideoFragment я добавляю общедоступную статическую логическую переменную initlize в значение false и изменяю ее на true, когда камера готова, используя CameraDevice.StateCallback, например:< /п> private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice cameraDevice) { mCameraDevice = cameraDevice; НачатьПредварительный просмотр(); mCameraOpenCloseLock.release(); isCameraReady = правда; // Устанавливаем здесь логическое значение true если (нуль!= mTextureView) { configureTransform(mTextureView.getWidth(), mTextureView.getHeight()); } } Проблема: isCameraReady остается ложным навсегда, когда я использую проверку while (* Если я начинаю захват после события кнопки, значение истинно, и все работает нормально)
Вопрос: Как я могу узнать, когда предварительный просмотр готов, и начать захват видео автоматически, не нажимая ни на одну кнопку? (нажав кнопка будет останавливать запись, а не запускать ее)
Изменить
Ниже приведен соответствующий код Camera2VideoFragment. Полный код можно найти здесь.
публичный класс Camera2VideoFragment расширяет фрагмент реализует FragmentCompat.OnRequestPermissionsResultCallback { частный статический окончательный SparseIntArray ОРИЕНТАЦИИ = новый SparseIntArray(); частная статическая окончательная строка TAG = "Camera2VideoFragment"; частный статический финал int REQUEST_VIDEO_PERMISSIONS = 1; частная статическая окончательная строка FRAGMENT_DIALOG = «диалог»; статический { ОРИЕНТАЦИИ.append(Surface.ROTATION_0, 90); ОРИЕНТАЦИИ.append(Surface.ROTATION_90, 0); ОРИЕНТАЦИИ.append(Surface.ROTATION_180, 270); ОРИЕНТАЦИИ.append(Surface.ROTATION_270, 180); } частный AutoFitTextureView mTextureView; частный CameraDevice mCameraDevice; частный CameraCaptureSession mPreviewSession; частный TextureView.SurfaceTextureListener mSurfaceTextureListener = новый TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable (SurfaceTexture SurfaceTexture, int ширина, int высота) { openCamera (ширина, высота); } @Override общественная пустота onSurfaceTextureSizeChanged (SurfaceTexture SurfaceTexture, int ширина, int высота) { configureTransform (ширина, высота); } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture SurfaceTexture) { вернуть истину; } @Override public void onSurfaceTextureUpdated (SurfaceTexture SurfaceTexture) { } }; частный размер mPreviewSize; частный размер mVideoSize; частный CaptureRequest.Builder mPreviewBuilder; частный MediaRecorder mMediaRecorder; частное статическое логическое значение mIsRecordingVideo; частный HandlerThread mBackgroundThread; частный обработчик mBackgroundHandler; частный семафор mCameraOpenCloseLock = новый семафор (1); public static Boolean isCameraReady = false; // Я добавляю эту переменную, чтобы узнать, когда я смогу начать запись частный CameraDevice.StateCallback mStateCallback = новый CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice cameraDevice) { mCameraDevice = cameraDevice; НачатьПредварительный просмотр(); mCameraOpenCloseLock.release(); isCameraReady = правда; // Здесь я устанавливаю логическое значение в true если (нуль!= mTextureView) { configureTransform(mTextureView.getWidth(), mTextureView.getHeight()); } } @Override public void onDisconnected (CameraDevice cameraDevice) { mCameraOpenCloseLock.release(); cameraDevice.close(); mCameraDevice = ноль; isCameraReady = ложь; } @Override public void onError (CameraDevice cameraDevice, ошибка int) { mCameraOpenCloseLock.release(); cameraDevice.close(); mCameraDevice = ноль; Активность активности = getActivity(); if (null != активность) { активность.окончание(); } isCameraReady = ложь; } }; публичный захват пустотыVideo() { если (mIsRecordingVideo) { остановитьЗаписьВидео(); } еще { начатьЗаписьВидео(); } } частный недействительный startBackgroundThread () { mBackgroundThread = новый HandlerThread («CameraBackground»); mBackgroundThread.start(); mBackgroundHandler = новый обработчик (mBackgroundThread.getLooper()); } частный недействительный stopBackgroundThread () { mBackgroundThread.quitSafely(); пытаться { mBackgroundThread.join(); mBackgroundThread = ноль; mBackgroundHandler = ноль; } catch (InterruptedException e) { е.printStackTrace(); } } Private void openCamera(int width, int height) { если (!hasPermissionsGranted(VIDEO_PERMISSIONS)) { запросвидеоразрешения(); возвращаться; } окончательная активность активности = getActivity(); if (null == Activity || Activity.isFinishing()) { возвращаться; } Менеджер CameraManager = (CameraManager) Activity.getSystemService(Context.CAMERA_SERVICE); пытаться { Log.d(TAG, "tryAcquire"); if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISCONDS)) { throw new RuntimeException("Время ожидания блокировки открытия камеры истекло."); } Строка cameraId = Manager.getCameraIdList()[0]; // Выбор размеров для предварительного просмотра камеры и записи видео Характеристики CameraCharacteristics = Manager.getCameraCharacteristics(cameraId); Карта StreamConfigurationMap = характеристики .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); mVideoSize = ChooseVideoSize(map.getOutputSizes(MediaRecorder.class)); mPreviewSize = ChooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), ширина, высота, mVideoSize); int ориентация = getResources().getConfiguration().orientation; если (ориентация == Configuration.ORIENTATION_LANDSCAPE) { mTextureView.setAspectRatio(mPreviewSize.getWidth(), mPreviewSize.getHeight()); } еще { mTextureView.setAspectRatio(mPreviewSize.getHeight(), mPreviewSize.getWidth()); } configureTransform (ширина, высота); mMediaRecorder = новый MediaRecorder (); Manager.openCamera(cameraId, mStateCallback, null); } catch (CameraAccessException e) { Toast.makeText(activity, «Невозможно получить доступ к камере», Toast.LENGTH_SHORT).show(); активность.окончание(); } catch (NullPointerException e) { // В настоящее время NPE генерируется, когда Camera2API используется, но не поддерживается на // устройство, на котором работает этот код. ErrorDialog.newInstance(getString(R.string.camera_error)) .show(getChildFragmentManager(), FRAGMENT_DIALOG); } catch (InterruptedException e) { throw new RuntimeException("Прервано при попытке заблокировать открытие камеры."); } } частный недействительный startPreview() { if (null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) { возвращаться; } пытаться { setUpMediaRecorder(); Текстура SurfaceTexture = mTextureView.getSurfaceTexture(); утвердить текстуру != null; текстура.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); Список поверхности = новый ArrayList(); Предварительный просмотр поверхностиSurface = новая поверхность (текстура); Surfaces.add(previewSurface); mPreviewBuilder.addTarget(previewSurface); Surface RecorderSurface = mMediaRecorder.getSurface(); Surfaces.add(recorderSurface); mPreviewBuilder.addTarget(recorderSurface); mCameraDevice.createCaptureSession(поверхности, новый CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession cameraCaptureSession) { mPreviewSession = cameraCaptureSession; обновить предпросмотр(); } @Override public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { Активность активности = getActivity(); if (null != активность) { Toast.makeText(активность, «Ошибка», Toast.LENGTH_SHORT).show(); } } }, mBackgroundHandler); isCameraReady = правда; } catch (CameraAccessException e) { е.printStackTrace(); } catch (IOException e) { е.printStackTrace(); } } частный недействительный updatePreview() { если (нуль == mCameraDevice) { возвращаться; } пытаться { setUpCaptureRequestBuilder (mPreviewBuilder); Поток HandlerThread = новый HandlerThread("CameraPreview"); поток.start(); mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, mBackgroundHandler); } catch (CameraAccessException e) { е.printStackTrace(); } } частный недействительный setUpCaptureRequestBuilder (CaptureRequest.Builder builder) { builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); } Private void configureTransform(int viewWidth, int viewHeight) { Активность активности = getActivity(); if (null == mTextureView || null == mPreviewSize || null == активность) { возвращаться; } int Rotation = Activity.getWindowManager().getDefaultDisplay().getRotation(); Матрица матрица = новая матрица(); RectF viewRect = новый RectF (0, 0, viewWidth, viewHeight); RectFufferRect = новый RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth()); float centerX = viewRect.centerX(); float centerY = viewRect.centerY(); if (Surface.ROTATION_90 == вращение || Surface.ROTATION_270 == вращение) { ufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY()); матрица.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL); масштаб с плавающей запятой = Math.max( (с плавающей запятой) viewHeight/mPreviewSize.getHeight(), (float) viewWidth/mPreviewSize.getWidth()); матрица.postScale(масштаб, масштаб, центрX, центрY); матрица.postRotate(90 * (поворот — 2), centerX, centerY); } mTextureView.setTransform(матрица); } Private void setUpMediaRecorder() выдает IOException { окончательная активность активности = getActivity(); если (нуль == активность) { возвращаться; } mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mMediaRecorder.setOutputFile(getVideoFile(activity).getAbsolutePath()); mMediaRecorder.setVideoEncodingBitRate(10000000); mMediaRecorder.setVideoFrameRate(30); mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight()); mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); int Rotation = Activity.getWindowManager().getDefaultDisplay().getRotation(); int ориентация = ORIENTATIONS.get(вращение); mMediaRecorder.setOrientationHint(ориентация); mMediaRecorder.prepare(); } частная пустота startRecordingVideo() { пытаться { mIsRecordingVideo = правда; mMediaRecorder.start(); } catch (IllegalStateException e) { е.printStackTrace(); } } частная пустота stopRecordingVideo() { mIsRecordingVideo = ложь; mMediaRecorder.stop(); mMediaRecorder.reset(); Активность активности = getActivity(); if (null != активность) { Toast.makeText(activity, "Видео сохранено: " + getVideoFile(activity), Toast.LENGTH_SHORT).show(); } НачатьПредварительный просмотр(); } }
Мобильная версия