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

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

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

Второй - это код:

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 (), который устанавливает Media Recorder.

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

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

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

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


person Madhava Jay    schedule 04.02.2013    source источник


Ответы (6)


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

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

<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#get(int,%20int). Первый параметр - это идентификатор камеры, которую вы открыли, а именно фронтальной камеры.

person spitzanator    schedule 04.03.2013
comment
Приносим извинения за такой подход, но может ли кто-нибудь поделиться своими мыслями по следующему вопросу о MediaRecorder. Был бы очень признателен. stackoverflow.com/q/32715573/1053097 - person muneikh; 23.09.2015

Итак, наконец-то все заработало.

Кажется, что проблема определенно относится к Profile Settings и, в частности, Frame Rate.

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

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

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

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

CamcorderProfile.QUALITY_HIGH
CamcorderProfile.QUALITY_LOW

QUALITY_LOW:

audioBitRate: 12200
audioChannels: 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
audioChannels: 1
audioCodec: AAC
audioSampleRate: 16000
продолжительность: 60
fileFormat: MPEG_4
качество: 1
videoBitRate: 3000000
videoCodec: H264
videoFrameRate: 30
videoFrameWidth: 720
videoFrameHeight: 480

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

А теперь .... Вот в чем странность:

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

-19 ошибка

mediaRecorder.setVideoFrameRate(fpsInt);

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

В любом случае, перейдем к передней камере.

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

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

Фактически работает любое значение от 1 до 15. Что кажется странным.

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

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

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

С Nexus 7 я не могу исследовать CamcorderProfile, я продолжаю получать нулевые указатели, что странно. В нем говорится, что он поддерживает 4 - 60 кадров в секунду. Если я выберу 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 - это просто случайные происшествия?

person Madhava Jay    schedule 06.02.2013
comment
Какой вызов вы используете для получения профиля видеокамеры для передней камеры? Вам следует использовать developer.android.com/reference/android/media /, int), который принимает в качестве аргумента идентификатор камеры. Функция с одним аргументом дает вам определения только для основной камеры. - person Eddy Talvala; 07.02.2013
comment
Кроме того, вы можете установить частоту кадров только с помощью разработчика. .android.com / reference / android / hardware / на одно из значений, перечисленных в developer.android.com/reference/android/hardware/. Если вы используете метод набора диапазонов (setPreviewFpsRange), вы должны использовать значения из getSupportedPreviewFpsRange. - person Eddy Talvala; 07.02.2013
comment
Camera.Parameters с идентификатором камеры имеет смысл, я попробую. Действительно ли setPreviewFpsRange () имеет какое-либо отношение к setVideoFrameRate () MediaRecorder? также Есть идеи, почему профили не существуют на Nexus 7? - person Madhava Jay; 07.02.2013
comment
У меня возникли некоторые проблемы, подобные описанным вами, и я просто хочу предупредить вас, что запроса камеры об оптимальной частоте кадров или разрешении недостаточно, если вы попытаетесь записать видео. Камера может быть способна на то, что сообщает, но медиа-рекордер может быть более глупым. Я видел, что 30 кадров в секунду не работают в большинстве случаев, о которых сообщает камера (пробовал на планшете sony xperia, google nexus s) - person Cynichniy Bandera; 23.04.2013
comment
@MadhavaJay Я любил читать эту ветку. Очень информативно. Я бы порекомендовал эту ветку всем, кто работает над приложением камеры. - person Adil Malik; 29.06.2013
comment
@MadhavaJay Отличный пост, но взгляните на это простое решение stackoverflow.com/a/18477029/624109 - person Muzikant; 05.02.2014
comment
Возможно, ключом к разгадке является слово Preview в имени метода getSupportedPreviewFpsRange (), а возвращаемые значения применяются ТОЛЬКО к поверхности предварительного просмотра. Возможно, OEM для этих телефонов слишком буквально воспринял это название метода и возвращал только значения Preview fps, оставляя разработчику угадывать частоту кадров видео; Я также на собственном горьком опыте выяснил, что, похоже, вообще нет никакого способа узнать, какие значения FPS поддерживаются для записи видео MediaRecorder. Как отмечает @Madhava Jay, я не вижу способа определить [частоту кадров], не догадываясь. Хороший пост! - person DDSports; 23.03.2015

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

person user2157737    schedule 26.08.2014

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

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

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

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

person Tim Smith    schedule 28.08.2014

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

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

я использовал второй пример кода отсюда Как я могу записывать видео на 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();
}
person Arkady    schedule 04.02.2013
comment
если это не помогает, попробуйте изменить качество на низкое mrec.setProfile (CamcorderProfile.get (CamcorderProfile.QUALITY_LOW)); - person Arkady; 04.02.2013
comment
Нет, это не работает. Вы действительно тестировали этот код с помощью: mCamera = Camera.open (1); Было бы неплохо, если бы кто-нибудь мог подтвердить набор кода, который работает для них с фронтальной камерой. Причина, по которой я не думаю, что это как-то связано с порядком заявлений Media Recorder, заключается в том, что обычная задняя камера работает каждый раз. Также передняя камера отлично работает в обычном приложении камеры на всех этих устройствах, поэтому она не сломана. Это действительно бессмысленно. - person Madhava Jay; 05.02.2013
comment
E / MediaRecorder (24557): сбой при запуске: -19 - person Madhava Jay; 05.02.2013

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

person Ankushkushal    schedule 24.10.2016