Android не может записывать видео с передней камерой, запуск MediaRecorder не выполнен: -19

У меня есть две разные базы кода с одной и той же проблемой.

Первый код скопирован прямо с developer.android.com здесь: http://developer.android.com/guide/topics/media/camera.html

Второй код:

http://android-er.blogspot.com.au/2011/10/simple-exercise-of-video-capture-using.html

Оба работают нормально с обычной задней камерой, но как только я пытаюсь использовать фронтальную камеру, я получаю ошибку.

Это происходит на следующих устройствах:

  • Nexus S 4.1.2

  • Galaxy Nexus 4.1.2

  • Nexus 7 4.2.1 (он имеет только фронтальную камеру)

Я также попробовал то, что похоже на параметры камеры эпохи 2.2, что, как утверждают некоторые, требуется для некоторых устройств Samsung и HTC, хотя в нескольких разных статьях упоминаются разные строковые ключи:

c = Camera.open(frontFacingCameraID); // attempt to get a Camera instance
Camera.Parameters params = c.getParameters();
params.set("cam-mode", 1);
params.set("cam_mode", 1);
params.set("camera-id", 1);
c.setParameters(params);

Ничего из этого не работает, также обратите внимание, что я обнаруживаю правильный идентификатор передней камеры, который на Nexus 7, конечно, равен: 0. Но результаты одинаковы на всех устройствах.

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

То, что заставляет меня думать, что с большинством кода нет ничего плохого, это то, что обычная камера работает нормально. Так что я думаю, что это связано с методом prepareVideoRecorder() / prepareMediaRecorder(), который устанавливает медиа-рекордер.

Возможно, ручные настройки кодирования медиа-рекордера, которые, как известно, работают на фронтальной камере?

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

Предполагая, что я могу заставить его работать на моих устройствах JB, кто-нибудь знает из опыта, если большинство этих проблем решаются с помощью API 15 ICS?

Я бы посоветовал не поддерживать API 10 Gingerbread, если его будет слишком сложно поддерживать.

6 ответов

Решение

Ладно, у меня наконец-то все заработало.

Эта проблема, похоже, определенно связана с настройками профиля и, в частности, частотой кадров.

На Nexus S, моем основном тестовом устройстве, если я прощупываю камеру. Параметры, которые я получаю:

Для задней камеры:
15 FPS до 30 FPS, достаточно справедливо.

Для передней камеры:
7,5 FPS до 30 FPS, хорошо.

Затем я проверяю профили, которые пытаюсь использовать:

CamcorderProfile.QUALITY_HIGH
CamcorderProfile.QUALITY_LOW

QUALITY_LOW:
audioBitRate: 12200
аудиоКаналы: 1
audioCodec: AMR_NB audioSampleRate: 8000
продолжительность: 30
fileFormat: THREE_GPP
качество: 0
videoBitRate: 256000
videoCodec: H264
videoFrameRate: 30
videoFrameWidth: 176
videoFrameHeight: 144

QUALITY_HIGH:
audioBitRate: 24000
аудиоКаналы: 1
audioCodec: AAC
audioSampleRate: 16000
продолжительность: 60
fileFormat: MPEG_4
качество: 1
videoBitRate: 3000000
videoCodec: H264
videoFrameRate: 30
videoFrameWidth: 720
ВидеокадрВысота: 480

Понятно, что профиль высокого качества предназначен для задней камеры, поскольку фронтальная поверхность составляет всего 640x480. Но они оба заявляют 30 FPS.

Сейчас....

Вот странность.

Если я установлю ЛЮБУЮ частоту кадров для камеры, обращенной назад, независимо от профиля, она вылетает с ужасной ошибкой: -19

mediaRecorder.setVideoFrameRate(fpsInt);

Это не имеет большого значения, потому что я не забочусь о задней камере, но это странно, учитывая, что профили по умолчанию равны 30, а параметры говорят, что они принимают 15-30. Но никакое значение int, которое я пробовал, сработало. Если я опущу setVideoFrameRate, это нормально.

Во всяком случае, переходя на фронтальную камеру.

Итак, если я использую профиль QUALITY_LOW И устанавливаю частоту кадров 15 или ниже, это волшебным образом работает.

mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
mediaRecorder.setVideoFrameRate(15);

Infact любой стоимости, 1 - 15 работ. Что кажется странным.

Итак, вот загадка, я, вероятно, могу исследовать разрешение и выбрать подходящий разрешение для большинства камер, хотя я также довольно уверен, что почти все фронтальные камеры имеют минимальный VGA 640x480.

Но как насчет частоты кадров? В случае с Nexus S я не вижу способа определить значение 15 или ниже, не угадав? Должен ли я стремиться всегда использовать НИЗКУЮ частоту кадров, возвращаемую камерой?

Я взглянул на Galaxy Nexus, и у него есть 3 диапазона частоты кадров, первый 15 - 15, а второй 15-30. Его низкокачественный профиль аналогичен более высокому разрешению. Если я использую низкопрофильный на Galaxy Nexus, кажется, работает нормально.

С Nexus 7 я не могу исследовать CamcorderProfile, я продолжаю получать нулевые указатели, что странно. Он говорит, что поддерживает 4 FPS - 60 FPS. Если я выберу QUALITY_LOW, который, как вы думаете, должен работать, он падает, и я не могу найти частоту кадров, с которой он будет работать. Хотя ошибка связана с setProfile, я думаю, что проблема связана со встроенным профилем. Конечно, смысл Android API заключается в том, что он совместим, это флагманское устройство, и камера FF предназначена для видеоконференций, не так ли?

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

Кажется, что Nexus S не ведет себя так, как он обещает в отношении установки FPS в соответствии с его Camera.getParameters(). GetSupportedPreviewFpsRange()

Я рад, что он использует настройки Auto FPS, но, видимо, он не подходит для камеры FF, так что мне делать? Я должен явно установить FPS на Nexus S и, в этом случае, установить значение от 1 до 15 FPS, несмотря на то, что камера говорит мне, что он обрабатывает 7,5 - 30 FPS.

Похоже, обещание setProfile исправить все проблемы в 2.x не совсем верно.

Я могу понять, что, когда вы пишете приложение для камеры для определенного ПЗУ, вы просто настраиваете его на это конкретное оборудование, что может объяснить, почему люди, кажется, всегда имеют глючные приложения для камеры на пользовательских дисках. НО..... как работают загружаемые приложения для записи видео? Они кастомны для каждого устройства?

Вот почему на Android пока нет Facebook Poke и Twitter Vine????:П

Дерьмо гугл, что с твоей камерой API?

Знает ли кто-нибудь передовой метод определения разрешения и частоты кадров для ВСЕХ API 15+-совместимых устройств?

Это вообще возможно, или я собираюсь писать собственный код на каждом тестируемом устройстве, а затем просто бросать кости на остальных?

Или Nexus S и Nexus 7 просто чудовищные аварии?

Сегодня я тоже немного боролся с этой проблемой.

Во-первых, убедитесь, что ваши разрешения настроены правильно. В частности, для записи видео вам понадобится:

<uses-feature android:name="android.hardware.camera.front" />
<uses-feature android:name="android.hardware.microphone"/>

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Во-вторых, и это сложная часть, эта строка из учебника не работает с фронтальной камерой!

mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

Эта подпись для CamcorderProfile.get() по умолчанию имеет профиль для камеры, обращенной назад:

Возвращает профиль видеокамеры для первой камеры на задней панели устройства с заданным уровнем качества. Если на устройстве нет камеры, обращенной назад, возвращается значение null.

Вместо этого используйте http://developer.android.com/reference/android/media/CamcorderProfile.html. Первый параметр - это идентификатор камеры, которую вы открыли, в частности, фронтальная камера.

Попробуйте с QUALITY_LOW, потому что QUALITY_HIGH не поддерживается в передней камере.

Я боролся с ошибкой -19 уже несколько часов. Ответ для меня в ответе Мадхавы и, в частности, mCamera.unlock();

т.е. в сочетании с первым ответом о заданном профиле этот код

        Camera cam = Camera.open(frontCamID);
        cam.unlock();
        recorder.setCamera(cam);

Позволяет мне выбирать и записывать с фронтальной камеры.

У меня такая же проблема. После того, как я исправил причину, я нашел только 1 виновника, разрешение 720×480, которое по умолчанию в камере. Я изменил это на что-нибудь, и да, я могу записать это хорошо

Вы должны посмотреть здесь http://developer.android.com/guide/topics/media/camera.html

порядок перечисленных здесь команд очень важен.

я использовал второй пример кода отсюда Как я могу захватить видеозапись на Android?

и изменили функции начала записи

protected void startRecording() throws IOException 
{
    mrec = new MediaRecorder();  // Works well

    mCamera.setPreviewDisplay(surfaceHolder);
    mCamera.startPreview();

    mCamera.unlock();
    mrec.setCamera(mCamera);

    mrec.setPreviewDisplay(surfaceHolder.getSurface());
    mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    mrec.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); 

    mrec.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

    mrec.setOutputFile("/sdcard/zzzz.3gp");
    mrec.setPreviewDisplay(surfaceHolder.getSurface());

    mrec.prepare();
    mrec.start();
}
Другие вопросы по тегам