Grabación MediaRecorder sólo en 15 FPS

Estoy haciendo una aplicación de cámara y tengo un problema, no puedo establecer la velocidad de fotogramas del vídeo, mi código se ve como este estoy fijando la velocidad de fotogramas a 30, pero lo ignora y registra en 15, i Sabemos que en algunos dispositivos no se está fijando la velocidad de fotogramas real, sino la frecuencia de fotogramas sugerida, y el teléfono decide basado en la iluminación, pero he grabado fuera en la luz y todavía estaba grabando en un fps bajo, probablemente estoy haciendo algo mal

MediaRecorder recorder; Camera camera; SurfaceView preview; SurfaceHolder holder; boolean isRecording = false; String TAG = "Evolution Camera"; int frameRate = 30; public static final int MEDIA_TYPE_IMAGE = 1; public static final int MEDIA_TYPE_VIDEO = 2; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); setContentView(R.layout.camera_view); preview = (SurfaceView) findViewById(R.id.camera_preview); // Add a listener to the Capture button ImageButton captureButton = (ImageButton) findViewById(R.id.btn_capture); captureButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { record(); } } ); } private boolean prepareVideoRecorder(){ camera = getCameraInstance(); recorder = new MediaRecorder(); // Step 1: Unlock and set camera to MediaRecorder camera.unlock(); recorder.setCamera(camera); // Step 2: Set sources recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // Step 3: Set a CamcorderProfile (requires API Level 8 or higher) recorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); recorder.setVideoFrameRate(frameRate); // Step 4: Set output file recorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()); // Step 5: Set the preview output recorder.setPreviewDisplay(preview .getHolder().getSurface()); // Step 6: Prepare configured MediaRecorder try { recorder.prepare(); } catch (IllegalStateException e) { Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } catch (IOException e) { Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } return true; } void record() { if (isRecording) { // stop recording and release camera recorder.stop(); // stop the recording releaseMediaRecorder(); // release the MediaRecorder object camera.lock(); // take camera access back from MediaRecorder // inform the user that recording has stopped //setCaptureButtonText("Capture"); isRecording = false; } else { // initialize video camera if (prepareVideoRecorder()) { // Camera is available and unlocked, MediaRecorder is prepared, // now you can start recording recorder.start(); setParameters(); // inform the user that recording has started //setCaptureButtonText("Stop"); isRecording = true; } else { // prepare didn't work, release the camera releaseMediaRecorder(); // inform user } } } void setParameters() { // set Camera parameters Camera.Parameters params = camera.getParameters(); if (params.getMaxNumMeteringAreas() > 0){ // check that metering areas are supported List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>(); Rect areaRect1 = new Rect(-100, -100, 100, 100); // specify an area in center of image meteringAreas.add(new Camera.Area(areaRect1, 600)); // set weight to 60% Rect areaRect2 = new Rect(800, -1000, 1000, -800); // specify an area in upper right of image meteringAreas.add(new Camera.Area(areaRect2, 400)); // set weight to 40% params.setMeteringAreas(meteringAreas); } params.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY); camera.setParameters(params); } @Override protected void onPause() { super.onPause(); if (isRecording) { recorder.stop(); // stop the recording releaseMediaRecorder(); // release the MediaRecorder object camera.lock(); isRecording = false; } else { releaseMediaRecorder(); } releaseCamera(); } private void releaseMediaRecorder(){ if (recorder != null) { recorder.reset(); // clear recorder configuration recorder.release(); // release the recorder object recorder = null; camera.lock(); // lock camera for later use } } private void releaseCamera(){ if (camera != null){ camera.release(); // release the camera for other applications camera = null; } } /** Create a file Uri for saving an image or video */ private static Uri getOutputMediaFileUri(int type){ return Uri.fromFile(getOutputMediaFile(type)); } /** Create a File for saving an image or video */ private static File getOutputMediaFile(int type){ // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_DCIM), "Evolution"); // This location works best if you want the created images to be shared // between applications and persist after your app has been uninstalled. // Create the storage directory if it does not exist if (! mediaStorageDir.exists()){ if (! mediaStorageDir.mkdirs()){ Log.d("MyCameraApp", "failed to create directory"); return null; } } // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); File mediaFile; if (type == MEDIA_TYPE_IMAGE){ mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg"); } else if(type == MEDIA_TYPE_VIDEO) { mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_"+ timeStamp + ".mp4"); Log.d("MyCameraApp", "File created "+ mediaStorageDir.getPath().toString()); } else { return null; } return mediaFile; } public static Camera getCameraInstance(){ Camera c = null; try { c = Camera.open(); // attempt to get a Camera instance } catch (Exception e){ // Camera is not available (in use or does not exist) } return c; // returns null if camera is unavailable } @Override public void onPreviewFrame(byte[] data, Camera camera) { // TODO Auto-generated method stub } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub if (isRecording) { recorder.stop(); isRecording = false; } recorder.release(); } 

La aplicación de cámara por defecto registra a 24 fps en las mismas condiciones

Lo solucioné con esto

 Camera.Parameters params = camera.getParameters(); params.setPreviewFpsRange(24000, 30000); camera.setParameters(params); 

Ahora estoy recibiendo 22-23 fps (supongo que es porque es de noche)

Depende del parámetro AutoExposure. Para trabajar con velocidad de fotogramas fija en todas las condiciones de iluminación (API 14, Android 4.0):

 Camera.Parameters p = camera.getParameters(); p.setPreviewFpsRange( 30000, 30000 ); // 30 fps if ( p.isAutoExposureLockSupported() ) p.setAutoExposureLock( true ); camera.setParameters( p ); 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.