CamcorderProfile.QUALITY_HIGH resolution produces green flickering video

前端 未结 5 1926
无人及你
无人及你 2020-12-01 09:12

I haven\'t found any explanation for this so far. Basically I have a video recording class which works splendidly when setVideoSize() is set to 720 x 480 on my Samsung Galax

5条回答
  •  渐次进展
    2020-12-01 09:38

    Here is how I managed to make this work on Samsung Galaxy S2. The critical point here is to set the same resolution both in camera parameters and recorder video size. Also, already mentioned 'cam_mode' hack is required. So, I allowed a user to select from three quality modes: low (800x480), medium(1280x720), and high(1920x1080):

    enum InternalCameraQuality {
        LOW, MEDIUM, HIGH
    }
    

    and when creating/populating camera and recorder I did

    // 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 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 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 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);
    }
    

    Note that you must use the 'cam_mode' hack only for medium and high quality, otherwise green flickering will appear in low quality mode. Also you may wish to customize some other profile settings if you need.

    Hope, that helped.

提交回复
热议问题