Включение вспышки камеры во время записи видео
Мне нужен способ управления вспышкой камеры на устройстве 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: (несколько месяцев спустя).
На данный момент я не думаю, что можно сделать то, что я изначально хотел. Я не хочу удалять вопрос на случай, если кто-то на него ответит, но я не ищу ответа. (Хотя, получить правильный ответ было бы здорово).
Я столкнулся с аналогичной проблемой. Пользователь должен иметь возможность изменять режим вспышки во время записи, чтобы удовлетворить свои потребности в зависимости от ситуации с освещением. После некоторых исследований я пришел к следующему решению:
Я предполагаю, что вы уже установили соответствующий SurfaceView и SurfaceHolder с необходимыми обратными вызовами. Первое, что я сделал, это предоставил этот код (не объявленные переменные являются глобальными):
Следующим моим шагом была инициализация и подготовка рекордера:
Важно отметить, что camera.unlock() должна быть вызвана ДО всего процесса инициализации медиа-рекордера. При этом также следует помнить о правильном порядке установки каждого свойства, иначе вы получите IllegalStateException при вызове prepare() или start(). Когда дело доходит до записи, я делаю следующее. Обычно это вызывается элементом представления:
Итак, теперь я наконец-то могу нормально записывать. Но что это за вспышка? И последнее, но не менее важное: волшебство за кадром:
Каждый раз, когда я вызываю этот метод через действие onClick, я могу изменить режим вспышки, даже во время записи. Просто позаботьтесь о правильной блокировке камеры. Как только блокировка будет получена медиарекордером во время записи, вам не придется снова блокировать/разблокировать камеру. Это даже не работает. Это было протестировано на Samsung Galaxy S3 с Android-версией 4.1.2. Надеюсь, этот подход поможет.
После подготовки медиа-рекордер, использовать камеру.блокировка(), а затем установить все параметры, которые вы хотите установить для камеры. Но перед началом записи вам нужно позвонить камеры.разблокировка(), и после остановки записи на носитель, вам нужно позвонить камеры.замок() для начала просмотра. Наслаждайтесь!!!
Попробуйте это. Надеюсь, получится... :)
Чтобы получить доступ к камере устройства, вы должны объявить разрешение CAMERA в манифесте Android. Также не забудьте включить элемент манифеста `` для объявления функций камеры, используемых вашим приложением. Например, если вы используете камеру и функцию автофокуса, ваш манифест должен содержать следующее:
Пример, проверяющий поддержку фонарика, может выглядеть следующим образом:
Чтобы включить фонарик, достаточно установить параметр камеры
Camera.Parameters.FLASH_MODE_TORCH
.Чтобы выключить факел, установите параметр
Camera.Parameters.FLASH_MODE_OFF
.