Разрешение CamcorderProfile.QUALITY_HIGH обеспечивает зеленое мерцающее видео

Я пока не нашел объяснений. В основном у меня есть класс видеозаписи, который отлично работает, когда setVideoSize() установлен на 720 x 480 на моей Samsung Galaxy S2.

Я хочу, чтобы он записывался с максимально возможным разрешением, поэтому с помощью CamcorderProfile.QUALITY_HIGH. Я могу получить различные свойства записи самого высокого качества и установить их в своем классе. Это работает для формата файла, частоты кадров видео, кодеров и скорости передачи данных, однако, когда я пытаюсь установить размер видео на ширину и высоту, возвращаемые CamcorderProfile (1920 x 1080), записанное видео просто зеленое мерцание.

Я заметил, что если я сменил 720 x 480 на 720 x 481, он сделал то же самое. Поэтому я могу только предположить, что это происходит, когда разрешение не поддерживается телефоном. Тем не менее, видеокамера, к которой пришел телефон, может записываться в 1920 x 1080 и обеспечивает отличную запись.

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

У кого-нибудь еще была эта проблема?

Заранее благодарим за любые ответы.

Ответ 1

Я столкнулся с этим вопросом, пытаясь решить ту же проблему.

Решение дано над разработчиком xda http://forum.xda-developers.com/showthread.php?t=1104970&page=8. Кажется, вам нужно установить неясный параметр "cam_mode" для записи высокой четкости:

camera = Camera.open();
Camera.Parameters param = camera.getParameters();
param.set( "cam_mode", 1 );     
camera.setParameters( param );

В mediarecorder вы можете использовать

mediarecorder.setVideoSize(1920, 1080);

хотя это также будет работать:

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

(У последнего, похоже, есть битрейт видео со скоростью 20 Мбит/с, поэтому вам может потребоваться немного уменьшить это!) Я обнаружил, что мне не нужно было устанавливать размер предварительного просмотра до 1920x1080.

(редактировать) Вам также нужно установить

parame.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);

или

param.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);

в противном случае вы получите задержку за несколько секунд до запуска камеры!

Что касается того, почему Samsung внедрил Camera таким образом, я понятия не имею. Это, конечно, не разработчик дружелюбный!

Ответ 2

Вот как мне удалось сделать эту работу на Samsung Galaxy S2. Критическая точка здесь - установить такое же разрешение как в параметрах камеры, так и в размере видеорекордера. Кроме того, уже упоминался взлом "cam_mode". Итак, я разрешил пользователю выбирать один из трех режимов качества: низкий (800x480), средний (1280x720) и высокий (1920x1080):

enum InternalCameraQuality {
    LOW, MEDIUM, HIGH
}

и при создании/заполнении камеры и рекордера я сделал

// signature types are irrelevant here
File start(DeviceHandler handler, FileHelper fh) throws IOException {
    file = fh.createTempFile(".mp4");

    camera = Camera.open();
    setCameraParameters(camera);
    camera.setPreviewDisplay(getHolder());
    camera.unlock();

    recorder = new MediaRecorder();
    recorder.setCamera(camera);
    setRecorderParameters(recorder);

    recorder.prepare();
    recorder.start();

    return file;
}

void setCameraParameters(Camera camera) {
    Camera.Parameters param = camera.getParameters();

    // getParams() simply returns some field holding configuration parameters
    // only the 'quality' parameter is relevant here
    if (getParams().quality != InternalCameraQuality.LOW) {
        // Samsung Galaxy hack for HD video
        param.set("cam_mode", 1);
    }

    Pair<Integer, Integer> resolution = getResolution(getParams().quality);
    param.setPreviewSize(resolution.first, resolution.second);
    param.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);

    camera.setParameters(param);
}

void setRecorderParameters(MediaRecorder recorder) {
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    Pair<Integer, Integer> resolution = getResolution(getParams().quality);

    CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
    profile.videoFrameWidth = resolution.first;
    profile.videoFrameHeight = resolution.second;
    recorder.setProfile(profile);

    recorder.setOutputFile(file.getAbsolutePath());
    recorder.setPreviewDisplay(getHolder().getSurface());
}

Pair<Integer, Integer> getResolution(InternalCameraQuality quality) {
    final int width, height;
    switch (quality) {
        case LOW:
            width = 800;
            height = 480;
            break;
        case MEDIUM:
            width = 1280;
            height = 720;
            break;
        case HIGH:
            width = 1920;
            height = 1080;
            break;
        default:
            throw new IllegalArgumentException("Unknown quality: " + quality.name());
    }
    return Pair.create(width, height);
}

Обратите внимание, что вы должны использовать взломы "cam_mode" только для среднего и высокого качества, иначе зеленое мерцание появится в режиме низкого качества. Также вы можете настроить другие параметры профиля, если вам нужно.

Надеюсь, это помогло.

Ответ 3

Хорошо, я проверил множество вариантов и единственная версия, которая хорошо работает на реальных устройствах:

CamcorderProfile camcorderProfile    = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);

// THREE_GPP works well but only on Phones            
//  camcorderProfile.fileFormat = MediaRecorder.OutputFormat.THREE_GPP;

// so better you use MPEG_4 for most Devices and PC
camcorderProfile.fileFormat = MediaRecorder.OutputFormat.MPEG_4;
camcorderProfile.videoCodec = MediaRecorder.VideoEncoder.MPEG_4_SP;

mrec.setProfile(camcorderProfile);

Ответ 4

У меня были аналогичные проблемы, подобные этому в прошлом. Что вы делаете, кажется, все в порядке, но вот несколько советов, которые могут помочь отладить проблему:

Убедитесь, что вы выбрали поддерживаемое разрешение

int cameraId = 0; // using back facing camera
Camera camera = Camera.open(cameraId);
Camera.Parameters cameraParams = camera.getParameters();
List<Camera.Size> supportedPreviewSizes = cameraParams.getSupportedPreviewSizez();

// find suitable Camera preview size from list and set your CamcorderProfile to use that new size

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

API MediaRecorder использует SurfaceView, поэтому, если ваш поверхностный вид не настроен правильно, это приведет к появлению зеленого фликкера, который вы видите

Убедитесь, что вы используете скорость передачи видео, которая может поддерживать новое разрешение, - попробуйте бить скорость передачи видео, чтобы удвоить то, что было изначально установлено (* обратите внимание, что это резко влияет на размер вашего выходного файла)

CamcorderProfile.QUALITY_HIGH возвращает максимально возможное разрешение камеры. Убедитесь, что вы используете правильный идентификатор камеры (спереди или сзади) - возможно, камера заднего вида поддерживает 1080p, но камера переднего обзора не работает?

Надеюсь, что советы помогут!

Ответ 5

        List<Size> ls = parameters.getSupportedPreviewSizes();
        Size size = ls.get(1);
        sizes 1 ----------960 720
        sizes 2 ----------800 480
        sizes 3 ----------720 480
        sizes 5 -----------640 384
        sizes 6 ----------576 432
        sizes 7 ----------480 320

это список размеров и многое другое в android.