kzen.dev
  • Вопросы
  • Метки
  • Пользователи
Оповещения
Вознаграждения
Регистрация
После регистрации, сможете получать уведомления об ответах и комментариях на Ваши вопросы.
Вход
Если у Вас уже есть аккаунт, войдите чтобы проверить новые уведомления.
Тут будут вознаграждения за добавленные вопросы, ответы и комментарий.
Дополнительно
Источник
Редактировать
 thepenguin77
thepenguin77
Вопрос

Включение вспышки камеры во время записи видео

Мне нужен способ управления вспышкой камеры на устройстве Android во время записи видео. Я создаю приложение для работы со стробоскопом, и съемка видео с мигающим стробоскопом позволила бы записывать объекты, движущиеся с высокой скоростью, например лопасти вентилятора.

Вспышку можно включить, только запустив предварительный просмотр видео и установив FLASH_MODE_TORCH в параметрах камеры. Это будет выглядеть следующим образом:

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

После разблокировки я больше не могу изменять параметры камеры и, следовательно, не имею возможности изменить состояние вспышки.

Я не знаю, возможно ли это сделать, поскольку я не лучший в java-хакерстве, но вот что я знаю:

  • Camera.unlock() - это нативный метод, поэтому я не могу понять, какой механизм стоит за тем, как он меня блокирует.
  • Camera.Parameter имеет HashMap, который содержит все его параметры
  • Camera.setParameters(Parameters) берет HashMap, преобразует его в строку и передает в родной метод.
  • Я могу удалить из HashMap все параметры, кроме TORCH-MODE, и камера все равно примет его.

Итак, я все еще могу получить доступ к камере, но она не будет слушать ничего из того, что я ей скажу. (В этом и заключается цель Camera.unlock()).

Edit:

После изучения родного кода я вижу, что в CameraService.cpp мои вызовы Camera.setParameters(Parameters) отклоняются, потому что мой ID процесса не совпадает с ID процесса, зарегистрированным в службе камеры. Так что, похоже, это и есть мое препятствие.

Edit2:

Похоже, что MediaPlayerService является основной службой, которая получает контроль над камерой во время записи видео. Я не знаю, возможно ли это, но если бы я мог как-то запустить эту службу в своем собственном процессе, я бы смог пропустить вызов Camera.unlock().

Edit3:

Последний вариант - это получить каким-то образом указатель на интерфейс CameraHardwareInterface. Судя по всему, это интерфейс для конкретного устройства и, вероятно, не включает проверку PID. Основная проблема с этим, однако, заключается в том, что единственное место, где я могу найти указатель на него, находится в CameraService, а CameraService не разговаривает.

Edit4: (несколько месяцев спустя).

На данный момент я не думаю, что можно сделать то, что я изначально хотел. Я не хочу удалять вопрос на случай, если кто-то на него ответит, но я не ищу ответа. (Хотя, получить правильный ответ было бы здорово).

28 2012-07-24T02:12:39+00:00 4
Jarett Millard
Jarett Millard
Редактировал вопрос 9-го июля 2015 в 7:32
Программирование
java
android
c++
process
android-camera
Решение / Ответ
 fje
fje
13-го февраля 2013 в 2:22
2013-02-13T14:22:21+00:00
Дополнительно
Источник
Редактировать
#16766205

Я столкнулся с аналогичной проблемой. Пользователь должен иметь возможность изменять режим вспышки во время записи, чтобы удовлетворить свои потребности в зависимости от ситуации с освещением. После некоторых исследований я пришел к следующему решению:

Я предполагаю, что вы уже установили соответствующий SurfaceView и SurfaceHolder с необходимыми обратными вызовами. Первое, что я сделал, это предоставил этот код (не объявленные переменные являются глобальными):

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

Важно отметить, что camera.unlock() должна быть вызвана ДО всего процесса инициализации медиа-рекордера. При этом также следует помнить о правильном порядке установки каждого свойства, иначе вы получите IllegalStateException при вызове prepare() или start(). Когда дело доходит до записи, я делаю следующее. Обычно это вызывается элементом представления:

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

Каждый раз, когда я вызываю этот метод через действие onClick, я могу изменить режим вспышки, даже во время записи. Просто позаботьтесь о правильной блокировке камеры. Как только блокировка будет получена медиарекордером во время записи, вам не придется снова блокировать/разблокировать камеру. Это даже не работает. Это было протестировано на Samsung Galaxy S3 с Android-версией 4.1.2. Надеюсь, этот подход поможет.

 fje
fje
Редактировал ответ 14-го февраля 2013 в 9:29
14
0
Ganesh Katikar
Ganesh Katikar
5-го марта 2015 в 11:18
2015-03-05T11:18:24+00:00
Дополнительно
Источник
Редактировать
#16766206

После подготовки медиа-рекордер, использовать камеру.блокировка(), а затем установить все параметры, которые вы хотите установить для камеры. Но перед началом записи вам нужно позвонить камеры.разблокировка(), и после остановки записи на носитель, вам нужно позвонить камеры.замок() для начала просмотра. Наслаждайтесь!!!

1
0
 anshika
anshika
28-го ноября 2012 в 6:49
2012-11-28T06:49:59+00:00
Дополнительно
Источник
Редактировать
#16766204

Попробуйте это. Надеюсь, получится... :)

 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");
      }
 anshika
anshika
Редактировал ответ 28-го ноября 2012 в 6:55
0
0
 Software_Designer
Software_Designer
3-го сентября 2012 в 5:49
2012-09-03T17:49:00+00:00
Дополнительно
Источник
Редактировать
#16766203

Чтобы получить доступ к камере устройства, вы должны объявить разрешение CAMERA в манифесте Android. Также не забудьте включить элемент манифеста <uses-feature> для объявления функций камеры, используемых вашим приложением. Например, если вы используете камеру и функцию автофокуса, ваш манифест должен содержать следующее:

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

Пример, проверяющий поддержку фонарика, может выглядеть следующим образом:

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

Чтобы включить фонарик, достаточно установить параметр камеры 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);

Чтобы выключить факел, установите параметр Camera.Parameters.FLASH_MODE_OFF.

 Software_Designer
Software_Designer
Редактировал ответ 3-го сентября 2012 в 6:15
-2
0
Похожие сообщества 36
Mobile Dev Jobs — вакансии и аналитика
Mobile Dev Jobs — вакансии и аналитика
19 674 пользователей
Публикуем вакансии и запросы на поиск работы по направлению iOS, Android, Xamarin и т.д. Размещение бесплатное. 📌 ВАЖНО: Правила публикации и правила канала: 📌 Ссылка – https://telegra.ph/Pravila-oformleniya-vakansij-i-rezyume-12-10
Открыть telegram
pro.cxx
pro.cxx
5 960 пользователей
C/C++ chat 0. Простые вопросы, лабы и о IDE — в чат новичков @supapro 1. No Ads, offtop, flood 2. Полные правила тут https://t.me/ProCxx/259155 Объявления о вакансиях,эвентах - в лс @AlexFails или @MasterZiV
Открыть telegram
pro.jvm
pro.jvm
5 817 пользователей
Сообщество разработчиков Java Scala Kotlin Groovy Clojure Чат для нач-их: @javastart Наш канал: @proJVM Вакансии: @jvmjobs @jvmjobschat ⚠️ Оффтоп -> @flood ❌Переход на личности ❌Троллинг ❌Реклама ❌HH (вакансии) ❌Варез
Открыть telegram
learn.java
learn.java
5 372 пользователей
Чат для начинающих и не только Статистика: https://combot.org/chat/-1001083535868 Основной чат - @jvmchat
Открыть telegram
supapro.cxx
supapro.cxx
4 991 пользователей
Чат для тех, кто немного знает C++, простые вопросы по C++, синтаксису и ide – сюда, а для другого есть: /Главный чат по серьезным вопросам — @ProCxx /Чат-флудилка — @fludpac /прогерские вопросы – @pro_prog 🚫flood, pron, spam; ✅УВАЖАЙТЕ ДРУГ ДРУГА!
Открыть telegram
Java & Co
Java & Co
4 434 пользователей
Можно обсуждать с матом и без всё, что касается жабы, вплоть до холиваров. НЕ ИМЕЕТ ОТНОШЕНИЯ К САЙТУ JAVARUSH.RU ПРАВИЛА - https://t.me/javarush/179171 Вакансии сюда - https://telegram.me/joinchat/B7IzvUCnfo6d8t3yIxKguQ По вопросам - @thedude
Открыть telegram
Добавить вопрос
Категории
Все
Технологий
Культура / Отдых
Жизнь / Искусство
Наука
Профессии
Бизнес
Пользователи
Все
Новые
Популярные
1
Ilya Smirnov
Зарегистрирован 2 дня назад
2
Денис Васьков
Зарегистрирован 4 дня назад
3
Dima Patrushev
Зарегистрирован 6 дней назад
4
sirojidddin otaboyev
Зарегистрирован 2 недели назад
5
Елена Гайдамамакинат
Зарегистрирован 2 недели назад
KO
RU
© kzen.dev 2023
Источник
stackoverflow.com
под лицензией cc by-sa 3.0 с атрибуцией