我正面临着Android摄像头录制的问题,问题是每当我录制视频并进入videoPlayer活动观看视频时,我完成videoPlayer活动并回到我的videoRecrding活动,如果我再次开始捕获视频使用后置摄像头,它给了我这个帖子标题中提到的例外,如果摄像机在进入videoPlayer活动之前处于FRONT模式,它表现正常并且正常再次记录,但唯一的问题是使用BACK CAMERA。
这是我的videoRecorder
活动
public class VideoRecorder extends Activity implements OnClickListener, OnErrorListener
{
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
private static int CURRENT_CAMERA_ID;
public static int VIDEO_QUALITY = CamcorderProfile.QUALITY_HIGH;
public static boolean CAMERA_FLASH_AVAILABLE = false;
public static boolean FRONT_CAMERA_AVAILABLE = false;
public static boolean EXTERNAL_STORAGE_AVAILABLE = false;
private CountDownTimer mCountDownTimer;
private int VIDEO_RECORDING_LIMIT = 60;
private boolean isRecording = false;
private String TAG = "CustmoizedCamera Application";
private Camera mCamera = null;
private Parameters cameraParams;
private CameraPreview mCameraPreview;
private MediaRecorder mMediaRecorder;
private TextView TextViewRecordingPercentage;
private ProgressBar ProgressBarVideoRecording;
private StorageHelper mStorageHelper;
public File VideoPath;
ImageButton ImageButtonVideoRecordingCapture, ImageButtonVideoRecordingFlash, ImageButtonVideoRecordingSwapCamera, ImageButtonVideoRecordingClose, ImageButtonVideoRecordingUpload, ImageButtonVideoRecordingThumbnail;
private PictureCallback mPicture = new PictureCallback()
{
@Override
public void onPictureTaken(byte[] data, Camera camera)
{
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null)
{
Log.d(TAG, "Error creating media file, check storage permissions: ");
return;
}
try
{
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
ImageButtonVideoRecordingThumbnail.setImageDrawable(Drawable.createFromPath(pictureFile.getAbsolutePath()));
}
catch (FileNotFoundException e)
{
Log.d(TAG, "File not found: " + e.getMessage());
}
catch (IOException e)
{
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState)
{
Log.d("inside onCreate", "of VideoRecorder");
super.onCreate(savedInstanceState);
setContentView(R.layout.video_recording_layout);
mStorageHelper = new StorageHelper();
CAMERA_FLASH_AVAILABLE = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
FRONT_CAMERA_AVAILABLE = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT);
EXTERNAL_STORAGE_AVAILABLE = mStorageHelper.isExternalStorageAvailable();
// mCamera = getCameraInstance();
ImageButtonVideoRecordingFlash = (ImageButton) findViewById(R.id.image_button_video_recording_flash);
ImageButtonVideoRecordingSwapCamera = (ImageButton) findViewById(R.id.image_button_video_recording_swap_camera);
ImageButtonVideoRecordingClose = (ImageButton) findViewById(R.id.image_button_video_recording_close);
ImageButtonVideoRecordingUpload = (ImageButton) findViewById(R.id.image_button_video_recording_upload);
ImageButtonVideoRecordingCapture = (ImageButton) findViewById(R.id.image_button_video_recording_capture);
ImageButtonVideoRecordingThumbnail = (ImageButton) findViewById(R.id.image_button_video_recording_thumbnail);
CURRENT_CAMERA_ID = getIntent().getExtras().getInt("cam_id");
if(CURRENT_CAMERA_ID == CameraInfo.CAMERA_FACING_FRONT)
{
ImageButtonVideoRecordingFlash.setClickable(false);
VIDEO_QUALITY = CamcorderProfile.QUALITY_LOW;
}
ProgressBarVideoRecording = (ProgressBar) findViewById(R.id.progress_bar_video_recording);
TextViewRecordingPercentage = (TextView) findViewById(R.id.text_view_video_recording_percentage);
// mCamera = getCameraInstance(CURRENT_CAMERA_ID);
//
// if(mCamera != null)
// {
// mCameraPreview = new CameraPreview(getApplicationContext(), mCamera);
// ImageButtonVideoRecordingThumbnail.setOnClickListener(null);
// ProgressBarVideoRecording.setProgress(0);
// TextViewRecordingPercentage.setText("60");
// FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
// preview.addView(mCameraPreview);
// }
// else
// {
// Log.d("inside onCreate", "Camera = null");
// }
// mCameraPreview = new CameraPreview(getApplicationContext(), mCamera);
//
// FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
// preview.addView(mCameraPreview);
ImageButtonVideoRecordingCapture.setOnClickListener(this);
ImageButtonVideoRecordingFlash.setOnClickListener(this);
ImageButtonVideoRecordingSwapCamera.setOnClickListener(this);
ImageButtonVideoRecordingClose.setOnClickListener(this);
ImageButtonVideoRecordingUpload.setOnClickListener(this);
// ImageButtonVideoRecordingThumbnail.setOnClickListener(this);
}
/** A safe way to get an instance of the Camera object. */
public Camera getCameraInstance(int camId)
{
Camera c = null;
CURRENT_CAMERA_ID = camId;
if(CURRENT_CAMERA_ID == CameraInfo.CAMERA_FACING_FRONT)
{
VIDEO_QUALITY = CamcorderProfile.QUALITY_LOW;
ImageButtonVideoRecordingFlash.setEnabled(false);
}
else
{
VIDEO_QUALITY = CamcorderProfile.QUALITY_HIGH;
ImageButtonVideoRecordingFlash.setEnabled(true);
}
try
{
c = Camera.open(camId); // attempt to get a Camera instance
// c = openFrontFacingCameraGingerbread();
}
catch (Exception e)
{
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
private void releaseMediaRecorder()
{
if (mMediaRecorder != null)
{
mMediaRecorder.reset(); // clear recorder configuration
mMediaRecorder.release(); // release the recorder object
mMediaRecorder = null;
mCamera.lock(); // lock camera for later use
}
}
private void releaseCamera()
{
if (mCamera != null)
{
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
private static Camera openFrontFacingCameraGingerbread() {
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for ( int camIdx = 0; camIdx < cameraCount; camIdx++ )
{
Camera.getCameraInfo( camIdx, cameraInfo );
if ( cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT )
{
try
{
cam = Camera.open( camIdx );
}
catch (RuntimeException e)
{
// Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage());
}
}
}
return cam;
}
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_PICTURES),"MyCameraApp");
// 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");
}
else
{
return null;
}
return mediaFile;
}
private boolean prepareVideoRecorder()
{
mMediaRecorder = new MediaRecorder();
// Step 1: Unlock and set camera to MediaRecorder
mCamera.lock();
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setOnErrorListener(this);
// Step 2: Set sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
// mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
mMediaRecorder.setProfile(CamcorderProfile.get(VIDEO_QUALITY));
// Step 4: Set output file
VideoPath = getOutputMediaFile(MEDIA_TYPE_VIDEO);
mMediaRecorder.setOutputFile(VideoPath.toString());
// Step 5: Set the preview output
mMediaRecorder.setPreviewDisplay(mCameraPreview.getHolder().getSurface());
// Step 6: Prepare configured MediaRecorder
try
{
mMediaRecorder.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;
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.image_button_video_recording_capture:
if(EXTERNAL_STORAGE_AVAILABLE)
{
if (isRecording)
{
// stop recording and release camera
try
{
mMediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); // take camera access back from
// MediaRecorder
}
catch(Exception ex)
{
ex.printStackTrace();
}
// inform the user that recording has stopped
isRecording = false;
mCountDownTimer.cancel();
ImageButtonVideoRecordingCapture.setImageResource(R.drawable.img_video_recording_unselected);
ImageButtonVideoRecordingSwapCamera.setClickable(true);
ImageButtonVideoRecordingThumbnail.setOnClickListener(VideoRecorder.this);
Toast.makeText(getApplicationContext(),"Video saved to SD Card\\Pictures\\MyCameraApp ",Toast.LENGTH_SHORT).show();
}
else
{
// initialize video camera
mCountDownTimer = new CountDownTimer(VIDEO_RECORDING_LIMIT * 1000, 1000)
{
@Override
public void onTick(long millisUntilFinished)
{
updateRecordingPercentage((int) millisUntilFinished/1000);
}
@Override
public void onFinish()
{
try
{
mMediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); // take camera access back from
// MediaRecorder
updateRecordingPercentage(0);
}
catch(Exception ex)
{
ex.printStackTrace();
}
// inform the user that recording has stopped
isRecording = false;
ImageButtonVideoRecordingCapture.setImageResource(R.drawable.img_video_recording_unselected);
ImageButtonVideoRecordingSwapCamera.setClickable(true);
Toast.makeText(getApplicationContext(),"Video saved to SD Card\\Pictures\\MyCameraApp ",Toast.LENGTH_SHORT).show();
}
};
// mCamera.takePicture(null, null, mPicture);
if (prepareVideoRecorder())
{
// Camera is available and unlocked, MediaRecorder is
// prepared,
// now you can start recording
mMediaRecorder.start();
// inform the user that recording has started
isRecording = true;
mCountDownTimer.start();
ImageButtonVideoRecordingSwapCamera.setClickable(false);
ImageButtonVideoRecordingCapture.setImageResource(R.drawable.img_video_recording_selected);
}
else
{
// prepare didn't work, release the camera
releaseMediaRecorder();
// inform user
}
}
}
else
{
Toast.makeText(getApplicationContext(), "SD card not available.....", Toast.LENGTH_SHORT).show();
}
break;
case R.id.image_button_video_recording_close:
releaseMediaRecorder();
releaseCamera();
setResult(RESULT_OK);
finish();
break;
case R.id.image_button_video_recording_flash:
if(!isRecording)
{
if (CAMERA_FLASH_AVAILABLE)
{
cameraParams = mCamera.getParameters();
if (cameraParams.getFlashMode().equalsIgnoreCase(Parameters.FLASH_MODE_OFF))
{
cameraParams.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(cameraParams);
ImageButtonVideoRecordingFlash.setImageResource(R.drawable.img_video_recording_flash_selected);
}
else
{
cameraParams.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(cameraParams);
ImageButtonVideoRecordingFlash.setImageResource(R.drawable.img_video_recording_flash_unselected);
}
}
else
{
Toast.makeText(getApplicationContext(), "Camera flash not available.....", Toast.LENGTH_SHORT).show();
}
}
break;
case R.id.image_button_video_recording_swap_camera:
Intent intent = getIntent();
finish();
if(FRONT_CAMERA_AVAILABLE)
{
if(CURRENT_CAMERA_ID == CameraInfo.CAMERA_FACING_BACK)
{
startActivity(intent.putExtra("cam_id", CameraInfo.CAMERA_FACING_FRONT));
}
else
{
startActivity(intent.putExtra("cam_id", CameraInfo.CAMERA_FACING_BACK));
}
}
break;
case R.id.image_button_video_recording_upload:
break;
case R.id.image_button_video_recording_thumbnail:
startActivity(new Intent(this, VideoPlayer.class).putExtra("video_path", VideoPath.getAbsolutePath()));
break;
default:
break;
}
}
@Override
public void onBackPressed()
{
// super.onBackPressed();
releaseMediaRecorder();
releaseCamera();
setResult(RESULT_OK);
finish();
}
private void updateRecordingPercentage(int orgPerc)
{
TextViewRecordingPercentage.setText(orgPerc+"");
ProgressBarVideoRecording.setProgress(VIDEO_RECORDING_LIMIT- orgPerc);
}
@Override
protected void onPause()
{
Log.d("inside", "onPause() of Video recorder");
super.onPause();
if(mCamera != null)
{
mCamera.stopPreview();
mCameraPreview.getHolder().removeCallback(mCameraPreview);
releaseMediaRecorder(); // if you are using MediaRecorder, release it
// first
releaseCamera(); // release the camera immediately on pause event
}
}
// @Override
// protected void onActivityResult(int requestCode, int resultCode, Intent data)
// {
// super.onActivityResult(requestCode, resultCode, data);
// Log.d("inside", "onActivityResult of video recorder");
// Intent mIntent = getIntent();
// finish();
// startActivity(mIntent);
// }
@Override
public void onError(MediaRecorder mr, int what, int extra) {
Log.d("MediaRecorderError " + what, "" + extra);
}
/* (non-Javadoc)
* @see android.app.Activity#onResume()
*/
@Override
protected void onResume() {
super.onResume();
mCamera = getCameraInstance(CURRENT_CAMERA_ID);
if(mCamera != null)
{
mCameraPreview = new CameraPreview(getApplicationContext(), mCamera);
ImageButtonVideoRecordingThumbnail.setOnClickListener(null);
ProgressBarVideoRecording.setProgress(0);
TextViewRecordingPercentage.setText("60");
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
}
else
{
Log.d("inside onCreate", "Camera = null");
}
}
}
这是我的CameraPreview
班级
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
{
private final String TAG = "Customized Camera Application";
private SurfaceHolder mHolder;
private Camera mCamera;
private Parameters mParameters;
public CameraPreview(Context context, Camera camera)
{
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder)
{
// The Surface has been created, now tell the camera where to draw the preview.
try
{
CamcorderProfile mProfile = CamcorderProfile.get(VideoRecorder.VIDEO_QUALITY);
mParameters = mCamera.getParameters();
mParameters.setPreviewSize(mProfile.videoFrameWidth, mProfile.videoFrameHeight);
mCamera.setParameters(mParameters);
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
catch (IOException e)
{
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
mCamera.release();
}
}
public void surfaceDestroyed(SurfaceHolder holder)
{
// empty. Take care of releasing the Camera preview in your activity.
try
{
mCamera.stopPreview();
}
catch (Exception e)
{
// ignore: tried to stop a non-existent preview
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
{
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null)
{
// preview surface does not exist
return;
}
// stop preview before making changes
try
{
mCamera.stopPreview();
}
catch (Exception e)
{
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try
{
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
}
catch (Exception e)
{
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
这是我的stacktrace
01-22 15:01:52.328: I/MediaRecorderJNI(1045): prepare: surface=0x5e7736e0
01-22 15:01:52.383: E/MediaRecorder(1045): start failed: -2147483648
01-22 15:01:52.383: D/AndroidRuntime(1045): Shutting down VM
01-22 15:01:52.383: W/dalvikvm(1045): threadid=1: thread exiting with uncaught exception (group=0x4201a700)
01-22 15:01:52.406: E/AndroidRuntime(1045): FATAL EXCEPTION: main
01-22 15:01:52.406: E/AndroidRuntime(1045): java.lang.RuntimeException: start failed.
01-22 15:01:52.406: E/AndroidRuntime(1045): at android.media.MediaRecorder.start(Native Method)
01-22 15:01:52.406: E/AndroidRuntime(1045): at com.galaxonic.jmtv.VideoRecorder.onClick(VideoRecorder.java:385)
01-22 15:01:52.406: E/AndroidRuntime(1045): at android.view.View.performClick(View.java:4240)
01-22 15:01:52.406: E/AndroidRuntime(1045): at android.view.View$PerformClick.run(View.java:17721)
01-22 15:01:52.406: E/AndroidRuntime(1045): at android.os.Handler.handleCallback(Handler.java:730)
01-22 15:01:52.406: E/AndroidRuntime(1045): at android.os.Handler.dispatchMessage(Handler.java:92)
01-22 15:01:52.406: E/AndroidRuntime(1045): at android.os.Looper.loop(Looper.java:137)
01-22 15:01:52.406: E/AndroidRuntime(1045): at android.app.ActivityThread.main(ActivityThread.java:5103)
01-22 15:01:52.406: E/AndroidRuntime(1045): at java.lang.reflect.Method.invokeNative(Native Method)
01-22 15:01:52.406: E/AndroidRuntime(1045): at java.lang.reflect.Method.invoke(Method.java:525)
01-22 15:01:52.406: E/AndroidRuntime(1045): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
01-22 15:01:52.406: E/AndroidRuntime(1045): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-22 15:01:52.406: E/AndroidRuntime(1045): at dalvik.system.NativeStart.main(Native Method)
01-22 15:02:02.477: I/Process(1045): Sending signal. PID: 1045 SIG: 9
我被困在这里。