Разрешение CamcorderProfile.QUALITY_HIGH обеспечивает мерцающее зеленое видео - PullRequest
32 голосов
/ 29 августа 2011

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

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

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

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

Кто-нибудь еще имел эту проблему?

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

Ответы [ 5 ]

19 голосов
/ 06 марта 2012

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

Решение предоставлено на xda developer 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.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 реализовал камеру таким образом, я понятия не имею. Это, конечно, не для разработчиков!

8 голосов
/ 12 июня 2012

Вот как мне удалось заставить это работать на 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' только для среднего и высокого качества, в противном случае мерцание зеленого цвета появится в режиме низкого качества.Также вы можете настроить другие параметры профиля, если вам нужно.

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

1 голос
/ 27 ноября 2013

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

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);
1 голос
/ 06 августа 2013
        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.

0 голосов
/ 24 октября 2011

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

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

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

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

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

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

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

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

...