용 카메라 플래시 동안 비디오 녹화

나는 방법이 필요를 제어하는 카메라의 플래시에 안드로이드 장치는 동안 그것을 기록한 비디오입니다. 나는'm 기 스트로브 빛 응용 프로그램,고 비디오 스트로브 빛이 번쩍이는 것이 결과에 기록하는 기능을 이동하는 물체 높은 속도에서,다음과 같 팬 블레이드입니다.

플래시해야만 사용할 수 있습을 시작하는 동영상 미리보기 설정 FLASH_MODE_TORCH 에서 카메라를's parameters. 는 다음과 같이 보일 것입니다.

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

미리보기 시작했다,내가 할 수 있습 튀는 매개변수를 앞뒤로 돌에서 빛이 꺼집니다. 이 때까지도를 기록한 비디오입니다. 문제는 그를 제공하기 위해 카메라 MediaRecorder,내가 먼저 있어 잠금을 해제합니다.

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

후에는 잠금,나는 더 이상 변경할 카메라를 매개 변수에 따라서는 방법이 없을 변경하는 플래시 상태입니다.

나는 알지 못한다면 그것은 실제로 이렇게 할 수 있기 때문에 나는'm 지에서 자바-해킹,하지만 여기에 내가 무엇을 알고 있:

-카메라가 있습니다.금()는 기본 방법,그래서 내가 할 수 있't 조 메커니즘 뒤에 이 방법은 잠금 나 -카메라가 있습니다.매개 변수는 HashMap 포함하는 모든 그것의 매개변수 -카메라가 있습니다.setParameters(매개 변수)취 HashMap,로 변환하는 문자열을 전달하는 기본방법 -I 삭제할 수 있는 모든 매개변수나 토치 모드에서 HashMap 고 카메라의 것입니다 여전히 그것을 받아들일

그래서 나는 아직도 카메라에 액세스할 수 있지만,그't 을 듣고 아무것도 나는 그것을 말해 준다. (는 종류의 목적이 있습니다.금())

편집:

를 조사한 후 기본 코드,나는 것을 볼 수 있습니다CameraService.cpp내 전화를 카메라가 있습니다.setParameters(매개 변수)을 거부하기 때문에 나의 프로세스 ID 와 일치하지 않는 프로세스 ID 카메라 서비스에 기록합니다. 그래서 나타나는 것은 내 장애물이다.

Edit2:

그것은 것으로 나타납[MediaPlayerService](http://androidxref.com/2.3.6/xref/frameworks/base/media/libmediaplayerservice/MediaPlayerService.cpp 는)주요 서비스를 제어하는 카메라의 경우 비디오 녹음이 있습니다. 나는 알지 못한다면 그것은 가능하지만 내가 할 수있는 경우게 시작하는 서비스에는 내 자신의 프로세스,이어야 한다 건너 뛸 수 있습니다.금()호출합니다.

Edit3:

하나 마지막 선택이 될 수 있다면 나는 어떻게든 포인터 CameraHardwareInterface. 의 모습에서,이것은 특정 장치 인터페이스와 아마도 포함되지 않은 PID 확인합니다. 주요한 문제이지만 그는 유일한 장소는 찾을 수 있습니다 포인터에서 CameraService 및 CameraService 아't 얘기합니다.

Edit4:(몇 개월 이상)

이 시점에서,나는't 생각을 내가 무엇을 원하고 싶다. I don't 삭제하려는 질문에는 누군가가 그것을 대답하지만,나는'm 지 않을 적극적으로 추구하는 대답이다. (그러나,수신한 유효한 대답으로 인해 발생하는 것으로 나타났다)

질문에 대한 의견 (2)
해결책

가 발생한 유사한 문제입니다. 사용자를 변경할 수 있는 플래시 모드를 기록하는 동안 그들의 요구를 충족하도록 빛에 따라 상황이다. 후에 몇몇 조사 연구에 왔을 다음과 같은 솔루션:

나는 가정,는've 이미 설정되어 적절한 서피스 뷰 surfaceview 및 SurfaceHolder 과 필요한 콜백이 있습니다. 첫 번째 일이었을 제공하이드(변수를 선언하지 않은 globals):

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();
    }
}

It's important to note,카메라가 있습니다.금()가 호출되기 전에 초기화 프로세스는 미디어의 레코더입니다. 는 말이 있는지 여부에 대하여 알고 있는 적절한 순서의 각 설정 시설,그렇지 않으면 당신이'll get an IllegalStateException 를 호출할 때 준비를()또는 start(). 때를 기록,요. 이것은 일반적으로에 의해 트리거 될 보기 요소:

public void record(View view) {
    if (recording) {
        recorder.stop();

        //TODO: do stuff....

        recording = false;
    } else {
        recording = true;

        initialize();
        recorder.start();
    }
}

그래서 지금,나는 마지막으로 기록할 수 있습니다. 하지만 무엇's 로는 플래시? 마지막으로,여기에 마법의 뒤에서:

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();
    }
}

마다 호출되는 메소드를 통해 onClick 행동을 변경할 수 있습의 플래시 모드로도 기록하는 동안. 그냥 알아서 제대로 잠그는 카메라가 있습니다. 면 잠금을 인수하여 미디어 레코더 기록하는 동안,당신이하지 않는't/잠금 해제 다시 켜 주십시오. 그't 도 작동합니다. 이 테스트에서 삼성의 갤럭시 S3 안드로이드 버전 4.1.2. 희망하는 데 도움이 됩니다.

해설 (6)

을 준비한 후 미디어 레코더 카메라를 사용.잠금(),그리고 다음 설정한 최상 매개 변수를 설정할 카메라가 있습니다. 그러나 녹화를 시작하기 전에 전화해야 하는 카메라가 있습니다.금(),및을 중지한 후에는 미디어 레코더는 당신을 호출 할 필요가 카메라가 있습니다.잠금()을 시작합니다. 즐길 수 있습니다!

해설 (0)

이라 작동합니다..:)

 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 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 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");
      }
해설 (1)

장치에 액세스하기 위해 카메라,선언해야 합 카메라의 권한에서 당신의 안드로이드 Manifest. 또한 반드시 포함해<사용 기능이>매니페스트의 요소를 선언하는 카메라 기능을 사용하여 응용 프로그램입니다. 예를 들어 사용하는 경우,카메라 자동 초점 기능이 매니페스트에는 다음이 포함되어야 합니다:



는 샘플 검사에 대한 토치 지원할 수 있습은 다음과 같이 보일 것입니다:

//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;
}

을 설정하 토치,당신은 단순히 설정할 카메라를 매개 변수는카메라가 있습니다.매개 변수입니다.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);

을 설정하 토치 해제 설정 카메라가 있습니다.매개 변수입니다.FLASH_MODE_OFF`

해설 (2)