如何在视频录制Android应用程序中设置FrameRate

时间:2012-10-27 11:41:34

标签: android camera android-camera frame-rate android-mediarecorder

以下是从相机前置摄像头和后置摄像头录制视频的完整代码。

我需要将重新编码的视频的帧速率设置为30 fps 。这是我尝试了很多事情的重大问题,但没有什么对我有用。这是大约2周,我陷入了这个问题,这是非常紧急

我在 Samsung Tablet GT-P1000上运行此应用程序,固件版本为2.3.3 GingerBread

代码工作得非常好,它正在录制视频。

主要问题在于代码 mrec.setVideoFrameRate(30);

这不应该像它应该的那样工作。帧速率在每个输出文件中都有所不同,有时是10,15或25等。

我需要30 fps的稳定帧速率,就像原生Android相机应用

代码:

package com.cameraApp.www;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class StartCamera extends Activity implements Callback, Runnable {

public ProgressDialog progressDialog;
public ProgressDialog progressDialogSave;
public SurfaceHolder surfaceHolder;
public SurfaceView surfaceView;
public Button startRecording = null;
public String SdCardPath = Environment.getExternalStorageDirectory().getPath(); 
public final static String Directory = "/cameraDirectory"; 
public static SimpleDateFormat sdf = null; 
public static String currentDateandTime = null;
public static String RecordFileName = null; 
public String FullFilePath = null;
public Camera mCamera;
boolean recording;
public MediaRecorder mrec = null;
public String cameraTypeString;
public int cameraType;
File video;
ImageView startVideo;
ImageView switchSurface;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    getWindow().getAttributes().windowAnimations = R.style.Fade;

    Intent intent = getIntent();
    cameraTypeString = intent.getStringExtra("cameraType");

    sdf = new SimpleDateFormat("yyyyMMdd_HHmmss"); 

    currentDateandTime = sdf.format(new Date());
    RecordFileName = "/" + currentDateandTime + ".mp4"; 

    FullFilePath = null;
    mrec = new MediaRecorder(); 

    recording = false;
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    WindowManager.LayoutParams lp = getWindow().getAttributes();
    lp.screenBrightness = 100 / 100.0f;
    getWindow().setAttributes(lp);

    if(mrec!=null){
    mrec.reset();   
    }

    setContentView(R.layout.activity_camera); 
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 

    initCameraBack();

    startVideo = (ImageView) findViewById(R.id.RecordStart_View);
    switchSurface = (ImageView) findViewById(R.id.SwitchCam_View);
}

public void doClick(View view) {

    switch (view.getId()) {
    case R.id.RecordStart_View:
        startORstopRecording();
        break;
    case R.id.SwitchCam_View:
        startFrontCamera();
        break;
    default:
        break;
    }

}

@SuppressWarnings("deprecation")
public void initCameraBack() {
    surfaceView = (SurfaceView) findViewById(R.id.BackCameraVideoView);
    surfaceHolder = surfaceView.getHolder();
    surfaceHolder.addCallback(this);
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void startFrontCamera() {
    progressDialog = ProgressDialog.show(StartCamera.this, "In progress","Changing Camera..."); 
    mCamera.setPreviewCallback(null); 
    mCamera.stopPreview(); 
    mCamera.release(); 
    mCamera = null;
    run();
}

public void startORstopRecording() {
    if (recording) {
        try {
            progressDialogSave = ProgressDialog.show(StartCamera.this,"In progress", "Saving Video...");
            mrec.stop();
        } catch (Exception e) {
            Log.i("StopRecordingError", e.toString());
        }
    } else {
        try {
            startRecording();
            recording = true;
            switchSurface.setEnabled(false);
            switchSurface.setVisibility(View.INVISIBLE);
            startVideo.setImageResource(R.drawable.record_stop);
        } catch (Exception e) {
            Log.i("StartRecordingError", e.toString());
        }
    }
}

@TargetApi(11)
public void startRecording() {      
    try{
    mCamera.unlock();
    }
    catch (Exception e){
    e.printStackTrace();
    }
    mrec.setCamera(mCamera);

    mrec.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
    mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    mrec.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mrec.setVideoSize(640, 480);
    mrec.setVideoEncodingBitRate(3000000);
    mrec.setVideoEncoder(MediaRecorder.VideoEncoder.H264);// MPEG_4_SP
    mrec.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

    File dir = new File(SdCardPath + Directory);
    if (!dir.exists()) {
        if (dir.mkdir()) {
            Log.v(STORAGE_SERVICE, "Created directory");
        } else {
            Log.v(STORAGE_SERVICE, "Failed to create Directory");
        }
    }

    FullFilePath = SdCardPath + Directory + RecordFileName;
    mrec.setOutputFile(FullFilePath);
    mrec.setVideoFrameRate(30);

    mrec.setPreviewDisplay(surfaceHolder.getSurface());
    try {
        mrec.prepare();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    mrec.start();
}


@TargetApi(9)
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    try {
        Parameters p = mCamera.getParameters();
          if (p != null) {
            p.setPreviewSize(640, 480);
            mCamera.setParameters(p);
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@TargetApi(9)
@Override
public void surfaceCreated(SurfaceHolder holder) {
    if (cameraTypeString.equals("back")) // For SDK version 9 and above
    {
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        int cameraCount = Camera.getNumberOfCameras();

        for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
            Camera.getCameraInfo(camIdx, cameraInfo);
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                try {
                    cameraType = camIdx;
                } catch (RuntimeException e) {
                    Toast.makeText(getApplicationContext(),
                            "CameraStart not available!", Toast.LENGTH_LONG)
                            .show();
                }
            }
        }
        mCamera = Camera.open(cameraType);
    } else if (cameraTypeString.equals("front")) {
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        int cameraCount = Camera.getNumberOfCameras();

        for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
            Camera.getCameraInfo(camIdx, cameraInfo);
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                try {
                    cameraType = camIdx;
                } catch (RuntimeException e) {
                    Toast.makeText(getApplicationContext(),
                            "CameraStart not available!", Toast.LENGTH_LONG)
                            .show();
                }
            }
        }
        mCamera = Camera.open(cameraType);
    }

    else { // For SDK 8 or below
        Intent WelcomeScreen = new Intent();
        WelcomeScreen.setClass(getBaseContext(), WelcomeScreen.class);
        startActivity(WelcomeScreen);
        Toast.makeText(getBaseContext(),
                "Application doesn't support firmware less than 2.3",
                Toast.LENGTH_LONG).show();
    }

    try {
        mCamera.setPreviewDisplay(holder);
    } catch (IOException e) {
        e.printStackTrace();
    }
    ;
    mCamera.startPreview();

    Parameters p = mCamera.getParameters();
    p.setPreviewSize(640, 480);      
    mCamera.setParameters(p);

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    try {
        if (mCamera != null) {
            try {
                mCamera.stopPreview();
            } catch (Exception ignore) {
                Log.i("SurfaceDestroyedCameraPreview", ignore.getMessage());
            }
            try {
                mCamera.release();
            } catch (Exception ignore) {
                Log.i("SurfaceDestroyedCameraReleased", ignore.getMessage());
            }
            mCamera = null;
        }
    } catch (Exception ex) {
        Log.i("SurfaceDestroyed", ex.getMessage());
        ex.printStackTrace();
    }
}

@Override
protected void onPause() {

    try {
        if (null != mCamera) {
            if (recording == true) {
                mrec.stop();
            }
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
            android.os.Process.killProcess(android.os.Process.myPid());
        }
    } catch (Exception e) {
        Log.i("OnPause", e.getMessage());
    }
    super.onPause();
}

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        if (recording == true) {
            mrec.stop();
        }
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
        Intent home = new Intent();
        home.setClass(getBaseContext(), WelcomeScreen.class);
        startActivity(home);
        StartCamera.this.finish();
        return false;
    }
    return super.onKeyDown(keyCode, event);
}

@Override
public void run() {
    String value;
    if (cameraTypeString.equals("back")) {
        value = "front";
    } else {
        value = "back";
    }
    Intent switchCamera = new Intent();
    switchCamera.setClass(getBaseContext(), StartCamera.class);
    switchCamera.putExtra("cameraType", value);
    startActivity(switchCamera);
    StartCamera.this.finish();
}

} 

0 个答案:

没有答案