Java 录制视频时启用照相机闪光灯

Java 录制视频时启用照相机闪光灯,java,android,c++,process,android-camera,Java,Android,C++,Process,Android Camera,我需要一种在Android设备录制视频时控制相机闪光灯的方法。我正在制作一个闪光灯应用程序,用闪光灯拍摄视频可以记录高速移动的物体,比如风扇叶片 只能通过启动视频预览并在相机参数中设置闪光灯模式来启用闪光灯。看起来是这样的: Camera c = Camera.open(); Camera.Parameters p = c.getParameters(); p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); c.setParameters(p)

我需要一种在Android设备录制视频时控制相机闪光灯的方法。我正在制作一个闪光灯应用程序,用闪光灯拍摄视频可以记录高速移动的物体,比如风扇叶片

只能通过启动视频预览并在相机参数中设置闪光灯模式来启用闪光灯。看起来是这样的:

Camera c = Camera.open();
Camera.Parameters p = c.getParameters();
p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
c.setParameters(p);
c.startPreview();
//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;
}
预览开始后,我可以前后翻转该参数以打开和关闭灯光。在我试着录制视频之前,这一切都很好。问题是,为了把相机交给MediaRecorder,我首先必须解锁它

MediaRecorder m = new MediaRecorder();
c.unlock();     // the killer
m.setCamera(c);
解锁后,我无法再更改相机参数,因此无法更改闪光灯状态

我不知道是否真的有可能做到这一点,因为我并不擅长java黑客,但以下是我所知道的:

  • Camera.unlock()是一个本机方法,因此我无法真正看到它将我锁定的机制
  • 参数有一个包含其所有参数的HashMap
  • setParameters(Parameters)获取HashMap,将其转换为字符串,并将其传递给本机方法
  • 我可以从HashMap中删除除TORCH-MODE之外的所有参数,相机仍然会接受它
所以,我仍然可以接近摄像机,但它不会听我说的任何话。(这是Camera.unlock()的用途之一)

编辑:

在检查本机代码之后,我可以在对Camera.setParameters(Parameters)的调用中看到,由于我的进程ID与Camera服务记录的进程ID不匹配,因此被拒绝。所以这似乎是我的障碍

Edit2:

似乎是在录制视频时控制摄像机的主要服务。我不知道这是否可能,但如果我能在自己的过程中启动该服务,我应该能够跳过Camera.unlock()调用

Edit3:

最后一个选择是,如果我能找到一个指向CameraHardwareInterface的指针。从外观上看,这是一个特定于设备的接口,可能不包括PID检查。但主要的问题是,我唯一能找到指向它的指针的地方是在CameraService中,CameraService没有说话

Edit4:(几个月后)


在这一点上,我认为不可能做我最初想要的事情。我不想删除这个问题,因为很可能有人会回答,但我并不是在积极寻找答案。(不过,收到一个有效的答案就太棒了。)

要访问设备摄像头,必须在Android清单中声明摄像头权限。还要确保包含
清单元素,以声明应用程序使用的相机功能。例如,如果使用相机和自动对焦功能,则清单应包括以下内容:

 <uses-permission android:name="android.permission.CAMERA" />
 <uses-feature android:name="android.hardware.camera" />
 <uses-feature android:name="android.hardware.camera.autofocus" />
要打开手电筒,只需设置摄像头参数
camera.Parameters.FLASH\u MODE\u 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);

要关闭手电筒,请设置摄像头.参数.闪光灯模式关闭。。希望它能起作用……)

专用静电火炬;
公共火炬(){
超级();
火炬=这个;
}
公共静态火炬getTorch(){
返回火炬;
}
专用照相机(){
if(mCamera==null){
试一试{
mCamera=Camera.open();
}捕获(运行时异常e){
Log.e(标记“Camera.open()失败:”+e.getMessage());
}
}
}
公共无效切换灯(视图){
切换灯光();
}
私有void toggleLight(){
如果(灯光){
关灯();
}否则{
转向灯();
}
}
私人无效指示灯(){
如果(!eulagreed){
返回;
}
if(mCamera==null){
Toast.makeText(此“相机未找到”,Toast.LENGTH\u LONG);
按钮。setBackgroundColor(颜色为白色);
返回;
}
莱顿=真;
Parameters=mCamera.getParameters();
if(参数==null){
按钮。setBackgroundColor(颜色为白色);
返回;
}
List flashModes=parameters.getSupportedFlashModes();
如果(flashModes==null){
按钮。setBackgroundColor(颜色为白色);
返回;
}
字符串flashMode=parameters.getFlashMode();
Log.i(标签“Flash mode:+flashMode”);
Log.i(标签,“闪光模式:”+闪光模式);
如果(!Parameters.FLASH_MODE_TORCH.equals(flashMode)){
if(flashModes.contains(Parameters.FLASH_MODE_TORCH)){
参数设置闪光模式(参数闪光模式);
mCamera.setParameters(参数);
按钮。设置背景颜色(颜色灯);
startwaklock();
}否则{
Toast.makeText(这是“不支持闪光模式(火炬)”,
吐司长度(长);
按钮。setBackgroundColor(颜色为白色);
Log.e(标签“不支持闪光灯模式”);
}
}
}
专用真空关闭灯(){
如果(灯光){
按钮。setBackgroundColor(颜色为深);
莱顿=假;
if(mCamera==null){
返回;
}
Parameters=mCamera.getParameters();
if(参数==null){
雷图
 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");
      }
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();
    }       
}
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();
    }
}
public void record(View view) {
    if (recording) {
        recorder.stop();

        //TODO: do stuff....

        recording = false;
    } else {
        recording = true;

        initialize();
        recorder.start();
    }
}
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();
    }
}