para instalar fashion descargar como chrome actualizar java android c++ process android-camera

java - instalar - Habilitar el flash de la cámara durante la grabación de vídeo



flash player chrome (4)

Necesito una forma de controlar el flash de la cámara en un dispositivo Android mientras se está grabando un video. Estoy creando una aplicación de luz estroboscópica, y grabar videos con una luz estroboscópica destellante resultaría en la capacidad de grabar objetos que se mueven a altas velocidades, como un ventilador.

El flash solo se puede activar iniciando una vista previa de video y configurando FLASH_MODE_TORCH en los parámetros de la cámara. Eso se vería así:

Camera c = Camera.open(); Camera.Parameters p = c.getParameters(); p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); c.setParameters(p); c.startPreview();

Una vez que la vista previa ha comenzado, puedo mover ese parámetro hacia adelante y hacia atrás para encender y apagar la luz. Esto funciona bien hasta que intento grabar un video. El problema es que para darle la cámara al MediaRecorder, primero tengo que desbloquearla.

MediaRecorder m = new MediaRecorder(); c.unlock(); // the killer m.setCamera(c);

Después de ese desbloqueo, ya no puedo cambiar los parámetros de la cámara y, por lo tanto, no tengo forma de cambiar el estado del flash.

No sé si es realmente posible hacerlo ya que no soy el mejor en java-hacking, pero esto es lo que sí sé:

  • Camera.unlock () es un método nativo, así que realmente no puedo ver el mecanismo detrás de la forma en que me bloquea.
  • Camera.Parameter tiene un HashMap que contiene todos sus parámetros
  • Camera.setParameters (Parámetros) toma el HashMap, lo convierte en una cadena y lo pasa a un método nativo
  • Puedo eliminar todos los parámetros, excepto TORCH-MODE, del HashMap y la cámara aún lo aceptará

Entonces, aún puedo acceder a la cámara, pero no escuchará nada de lo que le diga. (Que es el propósito de Camera.unlock ())

Editar:

Después de examinar el código nativo, puedo ver que en CameraService.cpp mis llamadas a Camera.setParameters (Parámetros) se rechazan porque mi Id. De proceso no coincide con la Id. De proceso que el servicio de cámara tiene registrado. Entonces parece que ese es mi obstáculo.

Edit2:

Parece que MediaPlayerService es el servicio principal que toma el control de la cámara cuando se graba un video. No sé si es posible, pero si pudiera iniciar ese servicio en mi propio proceso, debería poder omitir la llamada de Camera.unlock ().

Edit3:

Una última opción sería si pudiera obtener un puntero a CameraHardwareInterface. Por su aspecto, esta es una interfaz específica del dispositivo y probablemente no incluya las comprobaciones de PID. Sin embargo, el principal problema con esto es que el único lugar donde puedo encontrar un puntero es en CameraService, y CameraService no está hablando.

Edit4: (varios meses después)

En este punto, no creo que sea posible hacer lo que originalmente quería. No quiero eliminar la pregunta en caso de que alguien la responda, pero no busco una respuesta de forma activa. (Sin embargo, recibir una respuesta válida sería increíble.)


Después de preparar la grabadora de medios, use camera.lock () y luego configure los parámetros que desea configurar en la cámara. Pero antes de comenzar a grabar, debe llamar a camera.unlock (), y después de detener la grabadora de medios, debe llamar a camera.lock () para iniciar la vista previa. ¡¡¡Disfrutar!!!


Intenta esto ... espero que funcione ... :)

private static Torch torch; public Torch() { super(); torch = this; } public static Torch getTorch() { return torch; } private void getCamera() { if (mCamera == null) { try { mCamera = Camera.open(); } catch (RuntimeException e) { Log.e(TAG, "Camera.open() failed: " + e.getMessage()); } } } public void toggleLight(View view) { toggleLight(); } private void toggleLight() { if (lightOn) { turnLightOff(); } else { turnLightOn(); } } private void turnLightOn() { if (!eulaAgreed) { return; } if (mCamera == null) { Toast.makeText(this, "Camera not found", Toast.LENGTH_LONG); button.setBackgroundColor(COLOR_WHITE); return; } lightOn = true; Parameters parameters = mCamera.getParameters(); if (parameters == null) { button.setBackgroundColor(COLOR_WHITE); return; } List<String> flashModes = parameters.getSupportedFlashModes(); if (flashModes == null) { button.setBackgroundColor(COLOR_WHITE); return; } String flashMode = parameters.getFlashMode(); Log.i(TAG, "Flash mode: " + flashMode); Log.i(TAG, "Flash modes: " + flashModes); if (!Parameters.FLASH_MODE_TORCH.equals(flashMode)) { if (flashModes.contains(Parameters.FLASH_MODE_TORCH)) { parameters.setFlashMode(Parameters.FLASH_MODE_TORCH); mCamera.setParameters(parameters); button.setBackgroundColor(COLOR_LIGHT); startWakeLock(); } else { Toast.makeText(this, "Flash mode (torch) not supported", Toast.LENGTH_LONG); button.setBackgroundColor(COLOR_WHITE); Log.e(TAG, "FLASH_MODE_TORCH not supported"); } } } private void turnLightOff() { if (lightOn) { button.setBackgroundColor(COLOR_DARK); lightOn = false; if (mCamera == null) { return; } Parameters parameters = mCamera.getParameters(); if (parameters == null) { return; } List<String> flashModes = parameters.getSupportedFlashModes(); String flashMode = parameters.getFlashMode(); if (flashModes == null) { return; } Log.i(TAG, "Flash mode: " + flashMode); Log.i(TAG, "Flash modes: " + flashModes); if (!Parameters.FLASH_MODE_OFF.equals(flashMode)) { if (flashModes.contains(Parameters.FLASH_MODE_OFF)) { parameters.setFlashMode(Parameters.FLASH_MODE_OFF); mCamera.setParameters(parameters); stopWakeLock(); } else { Log.e(TAG, "FLASH_MODE_OFF not supported"); } } } } private void startPreview() { if (!previewOn && mCamera != null) { mCamera.startPreview(); previewOn = true; } } private void stopPreview() { if (previewOn && mCamera != null) { mCamera.stopPreview(); previewOn = false; } } private void startWakeLock() { if (wakeLock == null) { Log.d(TAG, "wakeLock is null, getting a new WakeLock"); PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); Log.d(TAG, "PowerManager acquired"); wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG); Log.d(TAG, "WakeLock set"); } wakeLock.acquire(); Log.d(TAG, "WakeLock acquired"); } private void stopWakeLock() { if (wakeLock != null) { wakeLock.release(); Log.d(TAG, "WakeLock released"); } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (Eula.show(this)) { eulaAgreed = true; } setContentView(R.layout.main); button = findViewById(R.id.button); surfaceView = (SurfaceView) this.findViewById(R.id.surfaceview); surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); disablePhoneSleep(); Log.i(TAG, "onCreate"); }


Me encontré con un problema similar. El usuario debe poder cambiar el modo de flash durante la grabación para satisfacer sus necesidades según la situación de la luz. Después de algunas investigaciones de investigación llegué a la siguiente solución:

Supongo que ya ha configurado un SurfaceView adecuado y un SurfaceHolder con sus devoluciones de llamada necesarias. Lo primero que hice fue proporcionar este código (las variables no declaradas son globales):

public void surfaceCreated(SurfaceHolder holder) { try { camera = Camera.open(); parameters = camera.getParameters(); parameters.setFlashMode(Parameters.FLASH_MODE_OFF); camera.setParameters(parameters); camera.setPreviewDisplay(holder); camera.startPreview(); recorder = new MediaRecorder(); } catch (IOException e) { e.printStackTrace(); } }

Mi siguiente paso fue inicializar y preparar la grabadora:

private void initialize() { camera.unlock(); recorder.setCamera(camera); recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); recorder.setVideoFrameRate(20); recorder.setOutputFile(filePath); try { recorder.prepare(); } catch (IllegalStateException e) { e.printStackTrace(); finish(); } catch (IOException e) { e.printStackTrace(); finish(); } }

Es importante tener en cuenta que se debe llamar a camera.unlock () ANTES de todo el proceso de inicialización de la grabadora de medios. Dicho esto, también tenga en cuenta el orden correcto de cada propiedad del conjunto, de lo contrario, obtendrá una excepción IllegalStateException cuando llame a prepare () o start (). Cuando se trata de grabar, hago esto. Esto usualmente será activado por un elemento de vista:

public void record(View view) { if (recording) { recorder.stop(); //TODO: do stuff.... recording = false; } else { recording = true; initialize(); recorder.start(); } }

Así que ahora, finalmente puedo grabar correctamente. Pero ¿qué pasa con ese flash? Por último, pero no menos importante, aquí viene la magia detrás de las escenas:

public void flash(View view) { if(!recording) { camera.lock(); } parameters.setFlashMode(parameters.getFlashMode().equals(Parameters.FLASH_MODE_TORCH) ? Parameters.FLASH_MODE_OFF : Parameters.FLASH_MODE_TORCH); camera.setParameters(parameters); if(!recording) { camera.unlock(); } }

Cada vez que llamo a ese método a través de una acción onClick puedo cambiar el modo de flash, incluso durante la grabación. Solo cuida de bloquear correctamente la cámara. Una vez que la grabadora de medios haya adquirido el bloqueo durante la grabación, no tendrá que bloquear / desbloquear la cámara nuevamente. Ni siquiera funciona. Esto fue probado en un Samsung Galaxy S3 con Android-Versión 4.1.2. Espero que este enfoque ayude.


Para acceder a la cámara del dispositivo, debe declarar el permiso de la CÁMARA en su Manifiesto de Android. También asegúrese de incluir el elemento de manifiesto <uses-feature> para declarar las características de la cámara utilizadas por su aplicación. Por ejemplo, si usa la cámara y la función de enfoque automático, su Manifiesto debe incluir lo siguiente:

<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />

Una muestra que comprueba el soporte de la antorcha podría verse algo como esto:

//Create camera and parameter objects private Camera mCamera; private Camera.Parameters mParameters; private boolean mbTorchEnabled = false; //... later in a click handler or other location, assuming that the mCamera object has already been instantiated with Camera.open() mParameters = mCamera.getParameters(); //Get supported flash modes List flashModes = mParameters.getSupportedFlashModes (); //Make sure that torch mode is supported //EDIT - wrong and dangerous to check for torch support this way //if(flashModes != null && flashModes.contains("torch")){ if(flashModes != null && flashModes.contains(Camera.Parameters.FLASH_MODE_TORCH)){ if(mbTorchEnabled){ //Set the flash parameter to off mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); } else{ //Set the flash parameter to use the torch mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); } //Commit the camera parameters mCamera.setParameters(mParameters); mbTorchEnabled = !mbTorchEnabled; }

Para encender la antorcha, simplemente configure el parámetro de la cámara Camera.Parameters.FLASH_MODE_TORCH

Camera mCamera; Camera.Parameters mParameters; //Get a reference to the camera/parameters mCamera = Camera.open(); mParameters = mCamera.getParameters(); //Set the torch parameter mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); //Comit camera parameters mCamera.setParameters(mParameters);

Para apagar la antorcha, configure Camera.Parameters.FLASH_MODE_OFF