i publish my app in google play.
this activity record video by front camera and if it not avaliable so it use in back camera
in crash section i received this output :
java.lang.RuntimeException: stop failed.
at android.media.MediaRecorder.stop(Native Method)
at com.example.uploadvideo.MainActivity.onStopped(MainActivity.java:192)
at com.google.android.youtube.player.internal.s$4.c(Unknown Source)
at com.google.android.youtube.player.internal.f$a.onTransact(Unknown Source)
at android.os.Binder.transact(Binder.java:326)
at com.google.android.youtube.player.internal.n.c(SourceFile:144)
at com.google.android.youtube.api.jar.client.e.run(SourceFile:797)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4921)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
at dalvik.system.NativeStart.main(Native Method)
I have no idea what this caused and no search did help...
but i belive this couse by surfaceCreated methood
i think this couse from this section :
/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private String TAG = "CameraPreview";
private SurfaceHolder mHolder;
private Camera mCamera ;
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.
Log.d(TAG, "surfaceCreated camera id" + mCamera);
try {
CamcorderProfile profile ;
int numCameras = Camera.getNumberOfCameras();
if (numCameras > 1) {
profile = (CamcorderProfile
.get(Camera.CameraInfo.CAMERA_FACING_FRONT,CamcorderProfile.QUALITY_HIGH));
}
else{
profile = (CamcorderProfile
.get(Camera.CameraInfo.CAMERA_FACING_BACK,CamcorderProfile.QUALITY_HIGH));
}
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
mCamera.setParameters(parameters);
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
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.
Log.d(TAG, "surfaceChanged to " + "," + w + "," + h);
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());
}
}
}
private boolean prepareVideoRecorder() {
mMediaRecorder = new MediaRecorder();
// Step 1: Unlock and set camera to MediaRecorder
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
// Step 2: Set sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
int numCameras = Camera.getNumberOfCameras();
if (numCameras > 1) {
mMediaRecorder.setProfile(CamcorderProfile
.get(Camera.CameraInfo.CAMERA_FACING_FRONT,CamcorderProfile.QUALITY_HIGH));
}
else{
mMediaRecorder.setProfile(CamcorderProfile
.get(Camera.CameraInfo.CAMERA_FACING_BACK,CamcorderProfile.QUALITY_HIGH));
}
// Step 4: Set output file
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO)
.toString());
outputFileName = getOutputMediaFile(MEDIA_TYPE_VIDEO).toString();
Log.d(TAG,"idan outputFileName" + outputFileName);
// Step 5: Set the preview output
// mMediaRecorder.setVideoSize(640, 480); //try
mMediaRecorder.setPreviewDisplay(mPreview.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;
}
/** Create a file Uri for saving an image or video */
private Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
U can use this code for your video record plz check
public class VideoCaptureActivity extends Activity {
private static final String TAG = "VideoCaptureActivity";
///////////////--------------------------
CountDownTimer ctimer;
//private static final int H264 = 0;
TextView timerText;
Camera camera;
ImageButton recordButton;
ImageButton stopButton;
FrameLayout cameraPreviewFrame;
CameraPreview cameraPreview;
MediaRecorder mediaRecorder;
File file;
public String holdVideoName = new String();
////////////////----------------------------
private String vpath;
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
super.setContentView(R.layout.video_capture);
this.cameraPreviewFrame = (FrameLayout)super.findViewById(R.id.camera_preview);
this.recordButton = (ImageButton)super.findViewById(R.id.recordButton);
this.stopButton = (ImageButton)super.findViewById(R.id.stopButton);
this.timerText=(TextView)super.findViewById(R.id.textViewtimer);
this.toggleButtons(false);
//------------- we'll enable this button once the camera is ready
this.recordButton.setEnabled(false);
}
#Override
protected void onResume() {
super.onResume();
// initialize the camera in background, as this may take a while
new AsyncTask<Void, Void, Camera>() {
#Override
protected Camera doInBackground(Void... params) {
Camera camera=null;
try {
int numCameras = Camera.getNumberOfCameras();
System.out.println("number of cameara is"+numCameras );
if (numCameras ==1) {
System.out.println("camera 1");
camera = Camera.open(CameraInfo.CAMERA_FACING_BACK);
}
else{
camera = Camera.open(CameraInfo.CAMERA_FACING_FRONT);
}
return camera == null ? Camera.open() : camera;
} catch (RuntimeException e) {
return null;
}
}
#Override
protected void onPostExecute(Camera camera) {
if (camera == null) {
Toast.makeText(VideoCaptureActivity.this, R.string.cannot_record,
Toast.LENGTH_SHORT);
} else {
VideoCaptureActivity.this.initCamera(camera);
}
}
}.execute();
}
void initCamera(Camera camera) {
// we now have the camera
this.camera = camera;
// create a preview for our camera
this.cameraPreview = new CameraPreview(VideoCaptureActivity.this, this.camera);
// add the preview to our preview frame
this.cameraPreviewFrame.addView(this.cameraPreview, 0);
// enable just the record button
this.recordButton.setEnabled(true);
}
void releaseCamera() {
if (this.camera != null) {
this.camera.lock(); // unnecessary in API >= 14
this.camera.stopPreview();
this.camera.release();
this.camera = null;
this.cameraPreviewFrame.removeView(this.cameraPreview);
}
}
void releaseMediaRecorder() {
if (this.mediaRecorder != null) {
this.mediaRecorder.reset(); // clear configuration (optional here)
this.mediaRecorder.release();
this.mediaRecorder = null;
}
}
void releaseResources() {
this.releaseMediaRecorder();
this.releaseCamera();
}
#Override
public void onPause() {
super.onPause();
this.releaseResources();
}
// gets called by the button press
public void startRecording(View v) {
Log.d(TAG, "startRecording()");
// we need to unlock the camera so that mediaRecorder can use it
this.camera.unlock(); // unnecessary in API >= 14
// now we can initialize the media recorder and set it up with our
// camera
ctimer = new CountDownTimer(10000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
timerText.setText("seconds remaining \n 00: " + millisUntilFinished / 1000);
}
#Override
public void onFinish() {
// TODO Auto-generated method stub
timerText.setText("done!");
stopRecordingg();
}
};
ctimer.start();
this.mediaRecorder = new MediaRecorder();
this.mediaRecorder.setCamera(this.camera);
this.mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
this.mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
this.mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
// this.mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_480P));
this.mediaRecorder.setMaxDuration(10000);
this.mediaRecorder.setOutputFile(this.initFile().getAbsolutePath());
this.mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
this.mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
this.mediaRecorder.setVideoSize(640,480);
// this.mediaRecorder.setVideoFrameRate(12);
// this.mediaRecorder.setOnInfoListener(null);
// this.mediaRecorder.setOutputFile("/sdcard/videocapture_example.mp4");
try {
this.mediaRecorder.setPreviewDisplay(this.cameraPreview.getHolder().getSurface());
this.mediaRecorder.prepare();
// start the actual recording
// throws IllegalStateException if not prepared
this.mediaRecorder.start();
Toast.makeText(this, R.string.recording, Toast.LENGTH_SHORT).show();
// enable the stop button by indicating that we are recording
this.toggleButtons(true);
} catch (Exception e) {
Log.wtf(TAG, "Failed to prepare MediaRecorder", e);
Toast.makeText(this,"record nathi thatu...", Toast.LENGTH_SHORT).show();
this.releaseMediaRecorder();
}
}
protected void stopRecordingg() {
// TODO Auto-generated method stub
Log.d(TAG, "stopRecording()");
assert this.mediaRecorder != null;
try {
// this.mediaRecorder.stop();
Toast.makeText(this, R.string.saved, Toast.LENGTH_SHORT).show();
// we are no longer recording
this.toggleButtons(false);
} catch (RuntimeException e) {
// the recording did not succeed
Log.w(TAG, "Failed to record", e);
if (this.file != null && this.file.exists() && this.file.delete()) {
Log.d(TAG, "Deleted " + this.file.getAbsolutePath());
}
return;
} finally {
this.releaseMediaRecorder();
}
if (this.file == null || !this.file.exists()) {
Log.w(TAG, "File does not exist after stop: " + this.file.getAbsolutePath());
} else {
Log.d(TAG, "Going to display the video: " + this.file.getAbsolutePath());
Intent intent = new Intent(this, VideoPlayBack.class);
intent.setData(Uri.fromFile(file));
intent.putExtra("hold",getIntent().getExtras().getString("hold"));
intent.putExtra("cwi",getIntent().getExtras().getString("cwi"));
// intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
this.finish();
}
}
// gets called by the button press
public void stopRecording(View v) {
Log.d(TAG, "stopRecording()");
ctimer.cancel();
assert this.mediaRecorder != null;
try {
this.mediaRecorder.stop();
Toast.makeText(this, R.string.saved, Toast.LENGTH_SHORT).show();
// we are no longer recording
this.toggleButtons(false);
} catch (RuntimeException e) {
// the recording did not succeed
Log.w(TAG, "Failed to record", e);
if (this.file != null && this.file.exists() && this.file.delete()) {
Log.d(TAG, "Deleted " + this.file.getAbsolutePath());
}
return;
} finally {
this.releaseMediaRecorder();
}
if (this.file == null || !this.file.exists()) {
Log.w(TAG, "File does not exist after stop: " + this.file.getAbsolutePath());
} else {
Log.d(TAG, "Going to display the video: " + this.file.getAbsolutePath());
Intent intent = new Intent(this, VideoPlayBack.class);
intent.setData(Uri.fromFile(file));
this.finish();
super.startActivity(intent);
}
}
private File initFile() {
// holdVideoName= getIntent().getExtras().getString("vpath","");
//System.out.println("vpath is:"+vpath);
// File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES), "namefolder");
File dir = new File("/sdcard/test/");
if (!dir.exists() && !dir.mkdirs()) {
Log.wtf(TAG, "Failed to create storage directory: " + dir.getAbsolutePath());
this.file = null;
} else {
this.file = new File("/sdcard/test/"+getIntent().getExtras().getString("hold")+".mp4");
}
return this.file;
}
}
Related
I'm trying to record video by using GLSurfaceview in android. But every time when i tap to record, it gives me null pointer exception onPause.
here is my code to record video
mCamera = new CameraLoader();
buttonn_capture.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try{
if (recording) {
mediaRecorder.stop(); // stop the recording
recording = false;
} else {
// Release Camera before MediaRecorder start
mCamera.releaseCamera();
if (!prepareMediaRecorder()) {
finish();
}
try {
mediaRecorder.prepare();
} catch (IllegalStateException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mediaRecorder.start();
recording = true;
// myButton.setText("Cancel");
}
}catch(Exception ex){
Toast.makeText(getApplicationContext(), "Please tap and hold to record!",
Toast.LENGTH_LONG).show();
reload();
}
}
});
private boolean prepareMediaRecorder() {
mCamera.mCameraInstance.unlock();
mediaRecorder.setCamera(mCamera.mCameraInstance);
// Step 2: Set sources
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES),
"MusicDubs");
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
mediaStorageDir.mkdirs();
}
timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault())
.format(new Date());
CameraInfo caminfo = new CameraInfo();
mCamera.mCameraInstance.getCameraInfo(0, caminfo);
if (caminfo.facing == CameraInfo.CAMERA_FACING_FRONT) {
mediaRecorder.setProfile(CamcorderProfile.get(0,
CamcorderProfile.QUALITY_HIGH));
mediaRecorder
.setOrientationHint(270);
} else if (caminfo.facing == CameraInfo.CAMERA_FACING_BACK) {
mediaRecorder.setProfile(CamcorderProfile.get(0,
CamcorderProfile.QUALITY_HIGH));
mediaRecorder
.setOrientationHint(270);
mediaRecorder.setOrientationHint(90);
}
//mediaRecorder.setCaptureRate(20);
mediaRecorder.setVideoFrameRate(120);
mediaRecorder.setOutputFile(mediaStorageDir.getPath() + "/"
+ "_" + timeStamp + ".mp4");
// Step 5: Set the preview output
mediaRecorder.setPreviewDisplay(glSurfaceView.getHolder()
.getSurface());
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
// releaseMediaPlayer();
return false;
} catch (IOException e) {
releaseMediaRecorder();
// releaseMediaPlayer();
return false;
}
return true;
}
private void releaseMediaRecorder() {
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
mCamera.mCameraInstance.lock(); // lock camera for later use
}
}
on Activity pause and resume i added that code
#Override
protected void onResume() {
super.onResume();
mCamera.onResume();
}
#Override
protected void onPause() {
mCamera.onPause();
super.onPause();
}
here is my camera class to load camera
private class CameraLoader {
private int mCurrentCameraId = 0;
private Camera mCameraInstance;
public void onResume() {
setUpCamera(mCurrentCameraId);
}
public void onPause() {
releaseCamera();
}
public void switchCamera() {
releaseCamera();
mCurrentCameraId = (mCurrentCameraId + 1) % mCameraHelper.getNumberOfCameras();
setUpCamera(mCurrentCameraId);
}
private void setUpCamera(final int id) {
mCameraInstance = getCameraInstance(id);
Parameters parameters = mCameraInstance.getParameters();
// TODO adjust by getting supportedPreviewSizes and then choosing
// the best one for screen size (best fill screen)
if (parameters.getSupportedFocusModes().contains(
Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
mCameraInstance.setParameters(parameters);
int orientation = mCameraHelper.getCameraDisplayOrientation(
ActivityCamera.this, mCurrentCameraId);
CameraInfo2 cameraInfo = new CameraInfo2();
mCameraHelper.getCameraInfo(mCurrentCameraId, cameraInfo);
boolean flipHorizontal = cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT;
mGPUImage.setUpCamera(mCameraInstance, orientation, flipHorizontal, false);
}
/** A safe way to get an instance of the Camera object. */
private Camera getCameraInstance(final int id) {
Camera c = null;
try {
c = mCameraHelper.openCamera(id);
} catch (Exception e) {
e.printStackTrace();
}
return c;
}
private void releaseCamera() {
mCameraInstance.setPreviewCallback(null);
mCameraInstance.release();
mCameraInstance = null;
}
}
Its behavior is very strange, I didn't get why it is giving me null pointer exception onPause because there is no point of getting camera null there. please tell me where i'm doing wrong. Any help would be much appreciated. Thank you :)
I making a custom camera android application . I have added a button to switch between cameras in my activity . On clicking that button , my camera gets switched perfectly, But when i try to save the image through the callback ,My app crashes due to NullPointerException. Here is my code . Please help me.
Thank You in advance
Camera Activity Code
public class CameraActivity extends Activity {
private Camera mCamera;
private CameraHandler surface_view;
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
public static final String TAG="Aloo";
Bitmap bmp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
if(checkifCamera(this))
{
mCamera=getCameraInstance();
surface_view = new CameraHandler(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(surface_view);
}
else
{
Toast.makeText(this,"Sorry camera is not supported on your device",Toast.LENGTH_LONG).show();
}
}
private boolean checkifCamera(Context context)
{
if(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))
{
return true;
}
else {
return false;
}
}
public Camera getCameraInstance()
{
Toast.makeText(this,"Chrj",Toast.LENGTH_LONG).show();
Camera c=null;
try{
releaseCameraAndPreview();
c=Camera.open();
}
catch (Exception e)
{
Toast.makeText(this,"Print error"+e.getMessage(),Toast.LENGTH_LONG).show();
return c;
}
Toast.makeText(this,"Check this out "+c,Toast.LENGTH_LONG).show();
return c;
}
public void switchC(View view)//Function called to switch camera
{
surface_view.switchCamera();
mCamera=getCameraInstance();
}
private void releaseCameraAndPreview() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
#Override
protected void onPause() {
super.onPause();
try
{
// release the camera immediately on pause event
//releaseCamera();
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void takePH(View view)
{
int toRotate=0;
Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int displayRotation = display.getRotation();
switch (displayRotation) {
case Surface.ROTATION_0: toRotate=90; break;
case Surface.ROTATION_90: break;
case Surface.ROTATION_180: break;
case Surface.ROTATION_270: toRotate=270; break;
}
Toast.makeText(this,"Rotation "+toRotate,Toast.LENGTH_LONG).show();
Camera.Parameters params = mCamera.getParameters();
params.set("rotation",270);
mCamera.setParameters(params);
mCamera.takePicture(null,null,mPicture);
}
Camera.PictureCallback mPicture = new Camera.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();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
Toast.makeText(CameraActivity.this,"Image saves successfully", Toast.LENGTH_LONG).show();
}
};
/** 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_PICTURES), "Fotos");
// 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;
}
}
My Custom Camera Handler
public class CameraHandler extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera=null;
public int currentCameraID=0;
public CameraHandler(Context context,Camera camera) {
super(context);
mCamera=camera;
mHolder=getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
Camera.Parameters p = mCamera.getParameters();
}
catch (IOException e)
{
Log.d("--DS", "Error setting camera preview: " + e.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
fixOr();
if(mHolder.getSurface()==null)
{
return;
}
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("--DS", "Error starting camera preview: " + e.getMessage());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
public void fixOr()
{
mCamera.stopPreview();
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
}
public void switchCamera() {
mCamera.stopPreview();
mCamera.release();
if(currentCameraID==Camera.CameraInfo.CAMERA_FACING_BACK)
{
currentCameraID = Camera.CameraInfo.CAMERA_FACING_FRONT;
}
else
{
currentCameraID=Camera.CameraInfo.CAMERA_FACING_BACK;
}
mCamera=Camera.open(currentCameraID);
fixOr();
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
}
}
I believe my app crashes because when I switch the camera mCamera becomes null. How can I fix that ?
The Error I am getting is:
java.lang.IllegalStateException: Could not execute method of the activity
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method
'android.hardware.Camera$Parameters android.hardware.Camera.getParameters()'
on a null object reference
After listening to Rami s comment i changed my code in 2 places
1.)
public void switchC(View view)//Function called to switch camera
{
mCamera=surface_view.switchCamera();
}
2.) Switch Camera function
public Camera switchCamera() {
mCamera.stopPreview();
mCamera.release();
if(currentCameraID==Camera.CameraInfo.CAMERA_FACING_BACK)
{
currentCameraID = Camera.CameraInfo.CAMERA_FACING_FRONT;
}
else
{
currentCameraID=Camera.CameraInfo.CAMERA_FACING_BACK;
}
mCamera=Camera.open(currentCameraID);
fixOr();
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
} return mCamera;
Following the documentation from developper.android.com
I wrote a short Activity to take picture from within the app.
I sometimes met this error :
02-23 17:37:06.323: E/IMemory(5003): binder=0x3c010388 transaction failed fd=-2147483647, size=0, err=-2147483646 (Unknown error: 2147483646)
02-23 17:37:06.328: E/IMemory(5003): cannot dup fd=-2147483647, size=0, err=-2147483646 (Bad file number)
02-23 17:37:06.328: E/IMemory(5003): cannot map BpMemoryHeap (binder=0x3c010388), size=0, fd=-1 (Bad file number)
can you help me understand it ?
Does setting the picture size to the smallest value retrieved from the getPictureSizes() method requieres less memory at the capture time or is it applied later ?
For information, here is my activitity (just the concatenation of the code example from this page ). Before that code, I used a very simplistic code with a preview and takePicture.
public class CatchImage extends Activity {
private boolean fgDebugLocal = true;
private String tagLocal = "CatchImage ";
private Button btTake, btRetour;
private Intent intent;
private String refPhoto;
private String strPath = "";
private String strFileName = "";
private Context context;
private CameraPreview mPreview;
private FrameLayout preview;
private Camera cameraCatchImage;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
context = getApplicationContext();
/**
* Set full screen
* Used in Landscape
*/
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
Baseline.tepvLogger.stat(tagLocal, "init ");
setContentView(R.layout.camera);
/**
* get the id of picture
*/
intent = getIntent();
refPhoto = intent.getStringExtra("refPhoto");
strPath = intent.getStringExtra("strSdInternalPath");
StringBuilder sb = new StringBuilder();
sb.append(strPath);
sb.append(File.separatorChar);
sb.append(Params.PATH_REP_PHOTO);
sb.append(File.separatorChar);
sb.append(Params.PHOTO_FILE_NAME);
sb.append(refPhoto);
sb.append(Params.PHOTO_FILE_EXT_JPG);
strFileName = sb.toString();
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "strFileName = " + strFileName);};
btTake = (Button) findViewById(R.id.btStatCatchPictureTake);
btRetour = (Button) findViewById(R.id.btStatCatchPictureRetour);
btTake.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "btTake");};
mPreview.mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
}
});
btRetour.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "btRetour ");};
Intent intent = new Intent(CatchImage.this, StationnementPhoto.class);
startActivity(intent);
finish();
}
});
}
#Override
public void onResume() {
super.onResume();
if (!checkCameraHardware(context)) {
afficheAlertDlg(getResources().getString(R.string.dlg_titre_alert), getResources().getString(R.string.catch_image_no_camera), getResources().getDrawable(R.drawable.ic_alert));
} else {
if (Camera.getNumberOfCameras()>1) {
new TePVException(this.getClass().getName(), "checkCameraHardware", "More than one camera detected");
}
if (safeCameraOpen(0)) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "safeCameraOpen(0) true : creating preview");};
btTake.setEnabled(true);
btTake.setBackgroundResource(R.drawable.bt_border_selector);
mPreview = new CameraPreview(context, cameraCatchImage);
preview = (FrameLayout) findViewById(R.id.flStatCatchPreview);
preview.addView(mPreview);
} else {
btTake.setEnabled(false);
btTake.setBackgroundResource(R.drawable.bt_border_disable);
}
}
}
#Override
public void onPause() {
super.onPause();
releaseCameraAndPreview(); // release the camera immediately on pause event
}
private boolean safeCameraOpen(int id) {
boolean qOpened = false;
try {
releaseCameraAndPreview();
cameraCatchImage = Camera.open(id);
qOpened = (cameraCatchImage != null);
} catch (Exception e) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "failed to open Camera");};
e.printStackTrace();
}
return qOpened;
}
private void releaseCameraAndPreview() {
if (mPreview!=null) mPreview.setCamera(null);
if (cameraCatchImage != null) {
cameraCatchImage.release();
cameraCatchImage = null;
}
}
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "shutterCallback ");};
}
};
/** Handles data for raw picture */
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "rawCallback ");};
}
};
private PictureCallback jpegCallback = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "jpegCallback ");};
FileOutputStream outStream = null;
try {
//String strFileNameComplet = strPath + File.separatorChar + strFileName + refPhoto + Params.PHOTO_FILE_EXT_JPG;
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "strFileName = " + strFileName);};
outStream = new FileOutputStream(strFileName);
outStream.write(data);
outStream.close();
File fileVerif = new File(strFileName);
if (fileVerif.exists()){
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "Photo stockée ");};
Intent intent = new Intent(CatchImage.this, StationnementPhoto.class);
startActivity(intent);
finish();
}else {
new TePVException("CatchImage", "PictureCallback", "Pb stockage image = " + strFileName);
Toast.makeText(context, "Erreur enregistrement de la photo, essayez à nouveau", Toast.LENGTH_LONG).show();
}
} catch (FileNotFoundException e) {
new TePVException("CatchImage", "PictureCallback", "FileNotFoundException = " + e.getMessage());
} catch (IOException e) {
new TePVException("CatchImage", "PictureCallback", "IOException = " + e.getMessage());
} finally {
}
}
};
/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
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 setCamera(Camera object) {
mCamera = object;
}
public Camera getCamera() {
return mCamera;
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
if (Params.tagFgDebug && fgDebugLocal){Log.d(tagLocal, "Error setting camera preview: " + e.getMessage());}
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
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){
if (Params.tagFgDebug && fgDebugLocal){Log.d(tagLocal, "Error starting camera preview: " + e.getMessage());}
}
}
}
Edit : I saw this question but I already saved the image as a file.
I found a solution :
We stop using Camera camera.takePicture() and only use the preview object. Idea based on #CommonsWare code for the photo display and base on zebra crossing astute solution.
idea :
btTake.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(Params.tagGen, tagLocal + "btTake");};
if (inPreview) {
camera.setOneShotPreviewCallback(previewCallback);
inPreview=false;
}
}
});
The preview code :
final class PreviewCallback implements Camera.PreviewCallback {
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.i( tagLocal , "onPreviewFrame ");
File photo= new File(strFileName);
if (photo.exists()) {
photo.delete();
}
try {
Camera.Parameters parameters = camera.getParameters();
Size size = parameters.getPreviewSize();
YuvImage image = new YuvImage(data, parameters.getPreviewFormat(),
size.width, size.height, null);
FileOutputStream filecon = new FileOutputStream(photo);
image.compressToJpeg(new Rect(0, 0, image.getWidth(), image.getHeight()), 90, filecon);
} catch (FileNotFoundException e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
/**
* Restart :
*/
File fileVerif = new File(strFileName);
if (fileVerif.exists() && fileVerif.length()!=0) {
if (Params.tagFgDebug && fgDebugLocal){Log.i(tagLocal , "Photo stockée file lenght = "+ fileVerif.length());};
Intent intent = new Intent(CatchImageCommonsWare.this, Photo.class);
startActivity(intent);
finish();
} else {
new Exception("CatchImageCommonsWare", "PreviewCallback", "Pb stockage image = " + strFileName);
Toast.makeText(context, "Erreur enregistrement de la photo, essayez à nouveau", Toast.LENGTH_LONG).show();
}
}
}
I am facing problems with android camera recording, the issue is whenever I record the video and go to videoPlayer activity to view the video and after I finish the videoPlayer activity and coming back to my videoRecrding activity if I start capturing the video again with back camera it gives me the exception mentioned in the title of this post, if the camera was in FRONT mode before going to videoPlayer activity it behaves normal and records again normally but the only problem is with BACK CAMERA.
here my videoRecorder activity
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");
}
}
}
and here is my CameraPreview class
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());
}
}
}
here is my 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
I am stuck here.
This is the code i used to record video from an android device in MP4 format. The file is being created but is of 0 bytes size. I dont seem to understand what has gone wrong. Any help will be appreciated.
if(mCamera == null) {
mCamera = Camera.open();
mCamera.unlock();
}
if(mediaRecorder == null)
mediaRecorder = new MediaRecorder();
mediaRecorder.setCamera(mCamera);
mediaRecorder.setCamera(mCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setMaxDuration(maxDurationInMs);
mediaRecorder.setOutputFile("/sdcard/1.mp4");
mediaRecorder.setVideoFrameRate(videoFramesPerSecond);
mediaRecorder.setVideoSize(176,144);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mediaRecorder.setPreviewDisplay(surface);
mediaRecorder.setMaxFileSize(maxFileSizeInBytes);
mediaRecorder.prepare();
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
// This is thrown if the previous calls are not called with the
// proper order
e.printStackTrace();
}
mediaRecorder.start();
The reason for such behavior is that you are probably (95% sure) calling recorder.setOutputFile() again after you have finished your recording (after recorder.stop() perhaps). Thus old file is being rewritten by new empty file.
okay so i finally figured it out myself. i used the method described here and it worked properly.
http://developer.android.com/guide/topics/media/camera.html#saving-media
The Below code worked for me :
private boolean isRecording = false;
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_record);
// Create an instance of Camera
mCamera = getCameraInstance();
mHolder = surfaceViewRecReadyTestimonial.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
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
}
private boolean prepareVideoRecorder() {
mCamera = getCameraInstance();
mMediaRecorder = new MediaRecorder();
// Step 1: Unlock and set camera to MediaRecorder
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
// Step 2: Set sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
// Step 4: Set output file
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
// Step 5: Set the preview output
mMediaRecorder.setPreviewDisplay(surfaceViewRecReadyTestimonial.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) {
if (v == btnStart) {
// initialize video camera
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;
} else {
// prepare didn't work, release the camera
releaseMediaRecorder();
// inform user
}
} else if (v == btnStop) {
if (isRecording) {
// stop recording and release camera
mMediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); // take camera access back from MediaRecorder
// inform the user that recording has stopped
isRecording = false;
}
} }
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;
}
}
/**
* 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), "FolderName");
// 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("FolderName", "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;
}
#Override
protected void onPause() {
super.onPause();
releaseMediaRecorder(); // if you are using MediaRecorder, release it first
releaseCamera(); // release the camera immediately on pause event
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("RecordVideo", "Error setting camera preview: " + e.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// 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
}
try {
Camera.Parameters parameters = mCamera.getParameters();
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
if (display.getRotation() == Surface.ROTATION_0) {
parameters.setPreviewSize(height, width);
mCamera.setDisplayOrientation(90);
}
if (display.getRotation() == Surface.ROTATION_90) {
parameters.setPreviewSize(width, height);
}
if (display.getRotation() == Surface.ROTATION_180) {
parameters.setPreviewSize(height, width);
}
if (display.getRotation() == Surface.ROTATION_270) {
parameters.setPreviewSize(width, height);
mCamera.setDisplayOrientation(180);
}
if (mCamera != null) {
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
// 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());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
public static final String rootDir = getStorageDir().concat(yours_dir);
...
mediaRecorder.setOutputFile(rootDir);
Do you have set user permission
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />