Запись видео - невозможно запустить предварительный просмотр камеры

Я работаю над пользовательским классом записи видео, и у меня возникают проблемы с отображением предварительного просмотра камеры при первом появлении действия. Я вызываю эту функцию внутри обратного вызова surfaceCreated:

private void initRecorder(Surface surface) throws IOException {
// It is very important to unlock the camera before doing setCamera
// or it will results in a black preview
if(camera == null) {
    camera = Camera.open();
    camera.unlock();
}

if(recorder == null)
    recorder = new MediaRecorder();

recorder.setPreviewDisplay(surface);
recorder.setCamera(camera);

camera.startPreview();

recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setOutputFile("/sdcard/test.mp4");
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
recorder.setVideoEncodingBitRate(15000000);
recorder.setMaxDuration(10000); // length of video in MS
recorder.setVideoSize(720, 480);
recorder.setVideoFrameRate(30);


try {
    recorder.prepare();
} catch (IllegalStateException e) {
    // This is thrown if the previous calls are not called with the 
    // proper order
    e.printStackTrace();
}
}

Когда начинается действие, мое приложение вылетает со словами:

java.lang.RuntimeException: startPreview failed

Над этой ошибкой я заметил строку:

attempt to use a locked camera from a different process (old pid 4894, new pid 6405)

Когда я просматриваю код, эта ошибка возникает в строке camera.startPreview(). Если я удалю эту строку из своего кода, предварительный просмотр будет отображаться нормально после того, как я вызову recorder.start(), а до этого у меня был просто черный экран с моей кнопкой записи. Как только я останавливаю запись, предварительный просмотр продолжает отображаться нормально (я звоню camera.startPreview() после остановки записи).

Поскольку я вызываю camera.unlock() всего за несколько строк до запуска предварительного просмотра, и два вызова происходят в одной и той же функции, как может возникнуть эта ошибка?

Редактировать: я протестировал тот же код без вызова startPreview() на Droid X2 и Droid 1, и он работает нормально. Похоже, проблема в EVO 4G. Я продолжу расследование.


person BigFwoosh    schedule 10.10.2011    source источник
comment
У меня такая же проблема, так как тестовое приложение рухнуло, когда камера была заблокирована :( Вы узнали, как разблокировать, так как вопрос был последним активным?   -  person Fildor    schedule 21.06.2012
comment
К сожалению нет. В конце концов, я не стал создавать собственный рекордер после того, как все было сказано и сделано.   -  person BigFwoosh    schedule 21.06.2012


Ответы (3)



camera.unlock() должен вызываться из того же потока, в котором раньше была заблокирована камера. Проверьте свои журналы на наличие сообщений типа Unlock call from pid 19322; currently locked to pid 17652.

Обратите внимание, что блокировку можно установить, вызвав Camera.lock() или MediaRecorder.start().

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

person Alexander Ushakov    schedule 22.12.2018

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

private void initRecorder(Surface surface) throws IOException {
    // It is very important to unlock the camera before doing setCamera
    // or it will results in a black preview
    if (camera == null) {
        camera = Camera.open();
        camera.unlock();
    }

    if (recorder == null)
        recorder = new MediaRecorder();

    recorder.setCamera(camera);

    camera.startPreview();

    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
    recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    recorder.setVideoEncodingBitRate(2048000);
    recorder.setMaxDuration(10000); // length of video in MS
    recorder.setVideoSize(720, 480);
    recorder.setVideoFrameRate(30);
    recorder.setOutputFile("/sdcard/test.mp4");
    recorder.setPreviewDisplay(surface);
    try {
        recorder.prepare();
    } catch (IllegalStateException e) {
        // This is thrown if the previous calls are not called with the
        // proper order
        e.printStackTrace();
    }
}
person Amrendra    schedule 27.06.2013