Android hell: MediaRecorder.Start() always throws IllegalStateException - android

I have this camera app that previews alright but whenever I try to record it gives me an illegalstatexception like my MediaRecorder isn't setup properly but it is. I must note that I am using an emulator for this with both front and back cams emulated.
package l33trus.com.shite
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.media.CamcorderProfile;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.util.Calendar;
public class VideoCapture extends Fragment implements OnClickListener, SurfaceHolder.Callback ,MediaRecorder.OnInfoListener,Camera.PictureCallback
{
public static final String LOGTAG = "VIDEOCAPTURE";
private static final int PICTURE_SIZE_MAX_WIDTH = 0;
String[] varNames; // for reflection function
private MediaRecorder recorder;
private MediaPlayer mp;
private SurfaceHolder holder;
int cameraCount = 0;
private CamcorderProfile camcorderProfile;
//final MediaPlayer interfaceSounds;
Cvars varPtr; // static global variable class
private ImageView isRecordingView;
private boolean photoMode; // if not in photo mode it's in video mode
private Camera camera;
private Camera.Size mPreviewSize;
private ImageButton recordButton;
private RawCallback rawCallback;
private SurfaceView cameraView;
CameraInfo cameraInfo = new CameraInfo();
private int resid = 0;
private int cameraId;
String fileExtension = ".mp4";
private boolean recording = false;
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
private View currentView;
private LayoutInflater inflateTmp;
private boolean usecamera = true;
private boolean previewRunning = false;
private boolean paused = false;
#Override
public void onSaveInstanceState(Bundle state)
{
super.onSaveInstanceState(state);
}
public VideoCapture()
{
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.videocapture, container, false);
recordButton = (ImageButton) rootView.findViewById(R.id.recordButton);
SurfaceView cameraView = (SurfaceView) rootView.findViewById(R.id.CameraView);
initRecorder();
holder = cameraView.getHolder();
holder.addCallback(this);
previewRunning = true;
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
{
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
recordButton.setOnClickListener(this);
cameraView.setClickable(true);
cameraView.setOnClickListener(this);
this.currentView = rootView;
this.inflateTmp = inflater;
return rootView;
}
private void initRecorder()
{
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
CamcorderProfile cpHigh = CamcorderProfile.get(cameraInfo.facing,CamcorderProfile.QUALITY_HIGH);
recorder.setProfile(cpHigh);
String fileName = java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime());
recorder.setOutputFile(varPtr.DefaultStorageDir + fileName + ".mp4");
recorder.setMaxDuration(50000); // 50 seconds
}
private void prepareRecorder()
{
recorder.setPreviewDisplay(holder.getSurface());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
Toast toasty = Toast.makeText(this.getActivity(),"IllegalStateException prepareRecorder",Toast.LENGTH_LONG);
} catch (IOException e) {
e.printStackTrace();
Toast toasty = Toast.makeText(this.getActivity(),"IOException prepareRecorder",Toast.LENGTH_LONG);
}
}
public void onRecordStop() // handles manually stopping of the record and also called if it is closed when a tab or orientation is changed
{
recorder.stop();
recorder.release();
recording = false;
varPtr.recording = false;
isRecordingView.setImageResource(R.drawable.notrecordingimage);
recordButton.setImageResource(R.drawable.recording_button);
}
public void onRecordStart()
{
recording = true;
varPtr.recording = recording;
isRecordingView.setImageResource(R.drawable.recordingimage);
recordButton.setImageResource(R.drawable.record_stop_button);
}
#Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.recordButton:
if(photoMode)
{
//camera.takePicture(shutter,mPicture,new ImageCaptureCallback(this));
}
if (recording)
{
recorder.stop();
if (usecamera)
{
try {
camera.reconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
recorder.release();
prepareRecorder();
}
else
{
onRecordStart();
recorder.start();
Log.v(LOGTAG, "Recording Started");
}
recording ^= true;
varPtr.recording = recording;
break;
case R.id.CameraView:
break;
case R.id.photoToggleButton:
photoMode ^= true;
break;
case R.id.videoToggleButton:
photoMode ^= true;
break;
}
}
private 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;
}
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;
}
}
#Override
public void surfaceCreated(SurfaceHolder holder)
{
Log.v(LOGTAG, "surfaceCreated");
// configure(camera);
if(! checkCameraHardware(getActivity().getApplicationContext()))
{
getActivity().finish();
}
prepareRecorder();
try
{
camera.setPreviewDisplay(holder);
camera.startPreview();
previewRunning = true;
} catch (IOException e)
{
Log.e(LOGTAG,e.getMessage());
e.printStackTrace();
} catch (NullPointerException e)
{
Log.e("WTF","This sucks");
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
Log.v(LOGTAG, "surfaceChanged");
if (!recording && usecamera)
{
try
{
Camera.Parameters p = camera.getParameters();
p.setPreviewSize(camcorderProfile.videoFrameWidth, camcorderProfile.videoFrameHeight);
p.setPreviewFrameRate(camcorderProfile.videoFrameRate);
camera.setParameters(p);
holder = cameraView.getHolder();
holder.addCallback(this);
camera.setPreviewDisplay(holder);
camera.startPreview();
previewRunning = true;
}
catch (IOException e)
{
Log.e(LOGTAG,e.getMessage());
e.printStackTrace();
}
catch(NullPointerException e)
{
Log.e("WTF","I hate my life");
e.printStackTrace();
}
prepareRecorder();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
Log.v(LOGTAG, "surfaceDestroyed");
if (recording)
{
recorder.stop();
onRecordStop();
}
}
#Override
public void onPause()
{
super.onPause();
holder.removeCallback(this); //http://stackoverflow.com/questions/12411346/camera-is-null-when-the-surfacecreated-method-is-executed-for-second-time
camera.release();
}
#Override
public void onInfo(MediaRecorder mr, int what, int extra)
{
}
#Override
public void onPictureTaken(byte[] data, Camera camera)
{
}
}
here is what logcat says
start called in an invalid state: 4
1762-1762/com.L33TRUS.shite D/AndroidRuntime﹕ Shutting down VM
1762-1762/com.L33TRUS.shite W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x409961f8)
1762-1762/com.L33TRUS.shite E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalStateException
at android.media.MediaRecorder.start(Native Method)
at l33trus.com.moment.Fragments.VideoCapture.onClick(VideoCapture.java:194)

fixed by sanitizing the file name like this
fileName = fileName.replaceAll(":", "~");
fileName = fileName.replaceAll(",","");
fileName = fileName.replaceAll(" ","_");
also made sure the dirs were created before opening the file via the mkdirs() call

Related

Android MediaRecorder preview size changed after start capturing video

i'm developing an camera app which allows users to capture video, and i started following some tutorials.
But the problem is when i press the Capture video button to start recording, the preview is just stretched
Before
After press record button
This is my code:
package com.example.phuongnguyen.cameraz;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class MainActivity extends Activity implements SurfaceHolder.Callback {
Camera mCamera;
Button btnCapture;
Button btnSwitch;
Button btnRecord;
SurfaceHolder surfaceHolder;
int cameraID;
private PreviewSurfaceView mOpenCvCameraView;
private DrawingView drawingView;
static MediaRecorder mediaRecorder;
boolean recording;
String RECORD = "Record \nvideo";
String STOP_RECORD = "Stop";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createImageGallary();
btnCapture = (Button) findViewById(R.id.captureImage);
btnSwitch = (Button) findViewById(R.id.button_switch);
btnRecord = (Button) findViewById(R.id.button_record);
mOpenCvCameraView = (PreviewSurfaceView) findViewById(R.id.surfaceView);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setListener(this);
drawingView = (DrawingView) findViewById(R.id.drawing_view);
mOpenCvCameraView.setDrawingView(drawingView);
surfaceHolder = mOpenCvCameraView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
btnCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
captureImage();
}
});
btnSwitch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switchCamera();
}
});
mediaRecorder = new MediaRecorder();
recording = false;
//initMediaRecorder();
btnRecord.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(recording){
mediaRecorder.stop();
releaseMediaRecorder();
btnRecord.setText(RECORD);
recording = false;
//finish();
}else{
//refreshCamera();
//MediaRecorder test = mediaRecorder;
try {
initMediaRecorder();
mediaRecorder.start();
} catch (Exception e) {
e.printStackTrace();
}
recording = true;
btnRecord.setText(STOP_RECORD);
}
}
});
}
private void initMediaRecorder(){
//mediaRecorder.setVideoSize(mOpenCvCameraView.getWidth(), mOpenCvCameraView.getHeight());
mCamera.unlock();
mediaRecorder.setCamera(mCamera);
//mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
CamcorderProfile camcorderProfile_HQ = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_HIGH);
mediaRecorder.setProfile(camcorderProfile_HQ);
//mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
//mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setOutputFile("/sdcard/myvideo.mp4");
mediaRecorder.setMaxDuration(5000); // Set max duration 5 sec.
mediaRecorder.setMaxFileSize(5000000); // Set max file size 5M
if(cameraID == Camera.CameraInfo.CAMERA_FACING_BACK){
mediaRecorder.setOrientationHint(90);
}else{
mediaRecorder.setOrientationHint(270);
}
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void prepareMediaRecorder(){
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
//e.printStackTrace();
} catch (IOException e) {
releaseMediaRecorder();
//e.printStackTrace();
}
}
private void releaseMediaRecorder() {
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
//mCamera.lock(); // lock camera for later use
}
}
private String GALLARY_LOCATION_NAME = "Camera Z";
File galleryFolder;
private void createImageGallary(){
File storageDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
galleryFolder = new File(storageDirectory,GALLARY_LOCATION_NAME);
if (!galleryFolder.exists()){
galleryFolder.mkdirs();
}
}
private String imagePath(File imageFile){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyymmddhhmmss");
String date = simpleDateFormat.format(new Date());
String photo = "CameraZ_"+date+".jpg";
String file_name = imageFile.getAbsolutePath()+"/"+photo;
return file_name;
}
Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
new BitmapAsyncTask(getApplicationContext(), imagePath(galleryFolder), cameraID, data).execute();
//Toast.makeText(getApplicationContext(), "Picture saved : "+imagePath(gallaryFolder), Toast.LENGTH_SHORT).show();
refreshCamera();
//refreshGallery(photoFile);
}
};
AutoFocusCallback autoFocusCallback = new AutoFocusCallback() {
#Override
public void onAutoFocus(boolean success, Camera camera) {
btnCapture.setEnabled(true);
}
};
#Override
protected void onResume() {
super.onResume();
refreshCamera();
}
#Override
protected void onPause() {
super.onPause();
if(mOpenCvCameraView != null){
releaseCamera();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if(mOpenCvCameraView != null){
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
cameraID = Camera.CameraInfo.CAMERA_FACING_BACK;
}catch (RuntimeException e){
e.printStackTrace();
}
mediaRecorder.setPreviewDisplay(holder.getSurface());
Camera.Parameters parameter = mCamera.getParameters();
parameter.setPreviewFrameRate(20);
parameter.setPreviewSize(mOpenCvCameraView.getWidth(), mOpenCvCameraView.getHeight());
mCamera.setParameters(parameter);
mCamera.setDisplayOrientation(90);
try{
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
}catch (Exception e){
}
//prepareMediaRecorder();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
refreshCamera();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
releaseCamera();
}
public void switchCamera(){
mCamera.stopPreview();
mCamera.release();
if(cameraID == Camera.CameraInfo.CAMERA_FACING_BACK){
cameraID = Camera.CameraInfo.CAMERA_FACING_FRONT;
}else{
cameraID = Camera.CameraInfo.CAMERA_FACING_BACK;
}
try {
mCamera = Camera.open(cameraID);
}catch (RuntimeException e){
}
Camera.Parameters parameter = mCamera.getParameters();
parameter.setPreviewFrameRate(20);
parameter.setPreviewSize(mOpenCvCameraView.getWidth(), mOpenCvCameraView.getHeight());
mCamera.setParameters(parameter);
mCamera.setDisplayOrientation(90);
try{
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
}catch (Exception e){
}
}
public void captureImage(){
mCamera.takePicture(null, null, pictureCallback);
}
public void refreshGallery( File file){
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(file));
sendBroadcast(intent);
}
public void refreshCamera(){
if(surfaceHolder.getSurface()== null){
return;
}
try{
mCamera.stopPreview();
}catch (Exception e){
}
try{
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
}catch (Exception e){
}
}
public void releaseCamera() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}
public void doTouchFocus(final Rect tfocusRect) {
try {
final List<Camera.Area> focusList = new ArrayList<Camera.Area>();
Camera.Area focusArea = new Camera.Area(tfocusRect, 1000);
focusList.add(focusArea);
Camera.Parameters para = mCamera.getParameters();
para.setFocusAreas(focusList);
para.setMeteringAreas(focusList);
mCamera.setParameters(para);
mCamera.autoFocus(autoFocusCallback);
} catch (Exception e) {
e.printStackTrace();
}
}
}

Setting the setPreviewDisplayof the camera with the mHolder of SurfaceView in a separate thread?

I have created separate thread to open the camera for preview with setPreviewCallbackWithBuffer. However, how do I set the of the camera with the mHolder of SurfaceView? The Handler has to pass it as a message to the mThread?
package com.example.cameraactivity;
import java.io.IOException;
import java.util.concurrent.Semaphore;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Button;
/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "CameraPreview";
private SurfaceHolder mHolder;
private CameraHandlerThread mThread = null;
private static class CameraHandlerThread extends HandlerThread implements PreviewCallback{
private static final String TAG = "CameraHandlerThread";
Handler mHandler = null;
private Camera mCamera;
private float framerate = 0;
int i = 0, t = 0;
long now, oldnow, count = 0;
private int preview_width = 640, preview_height = 320;
private int bitsPerPixel = 8;
private int bufSize = preview_width * preview_height * bitsPerPixel/ 8;
static final private int NUM_CAMERA_PREVIEW_BUFFERS = 2;
CameraHandlerThread() {
super("CameraHandlerThread");
start();
mHandler = new Handler(getLooper());
}
synchronized void notifyCameraOpened() {
notify();
}
void openCamera() {
mHandler.post(new Runnable() {
#Override
public void run() {
getCameraInstance();
notifyCameraOpened();
}
});
try {
wait();
}
catch (InterruptedException e) {
Log.w(TAG, "wait was interrupted");
}
}
private void getCameraInstance(){
try {
mCamera = Camera.open(1);
}
catch (RuntimeException e) {
Log.e(TAG, "failed to open front camera");
}
setParameters();
for (int i = 0; i < NUM_CAMERA_PREVIEW_BUFFERS; i++) {
byte [] cameraBuffer = new byte[bufSize];
mCamera.addCallbackBuffer(cameraBuffer);
}
mCamera.setPreviewCallbackWithBuffer(this);
//mCamera.setPreviewDisplay(mHolder);
}
private void setParameters(){
Camera.Parameters params = mCamera.getParameters();
//params.setPreviewSize(640, 320);
params.setPreviewFpsRange(150000, 150000);
params.setAutoWhiteBalanceLock(true);
params.setAutoExposureLock(true);
mCamera.setParameters(params);
}
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
i++;
now = System.nanoTime()/1000;
t = (int)( now - oldnow);
framerate = (int) (1000000/t);
oldnow = now;
Log.i(TAG, "Framerate: " + framerate);
mCamera.addCallbackBuffer(data);
}
void startPreview() {
mCamera.startPreview();
}
void stopPreview() {
mCamera.stopPreview();
}
}
private void openCamera() {
if (mThread == null) {
mThread = new CameraHandlerThread();
}
synchronized (mThread) {
mThread.openCamera();
}
}
private void startPreview() {
synchronized (mThread) {
mThread.startPreview();
}
}
private void stopPreview() {
synchronized (mThread) {
mThread.stopPreview();
}
}
public CameraPreview(Context context) {
super(context);
//mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
//mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Log.i(TAG, "init");
}
public void surfaceCreated(SurfaceHolder holder) {
try {
openCamera();
startPreview();
Log.i(TAG, "surfaceCreated");
} catch (Exception e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
stopPreview();
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mHolder.getSurface() == null){
return;
}
try {
stopPreview();
} catch (Exception e){
}
try {
startPreview();
Log.i(TAG, "surfaceChanged");
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
You really want to limit your interactions with Camera to a single thread. You should be able to wrap accesses from multiple threads with explicit mutex synchronization, but it's usually simpler to do everything on one. If the camera handling and your surface callbacks run on different threads, it's probably best to pass the SurfaceHolder through a message to a Handler.
Grafika demonstrates a couple of different approaches. In "Show + capture camera", the camera is handled on the UI thread. In "Texture from camera", it's handled on the renderer thread. See the notes near the top of each activity class for additional info.
Things can get complicated in a hurry when you try to manage the Camera object so that it is handled correctly with regard to the lifecycles of the app (pause/resume) and surface (created/destroyed), which aren't as tightly coupled as one might hope. Some details about that can be found here (also referenced from the comments in Grafika).

I can't see preview of camera when starting activity on android

Update:
I could solve the rotation issue (I will write modified code later by an answer). But I can't see preview of camera when starting activity still.
I read below links but didn’t help me.
Can't create Camera preview in onCreate?
[Android camera preview in surfaceview2]
Modify my code if you know any response please.
//-------------------------------------------
I have an android app with below code for capture videos. Every things works correctly except 2 things.
First is : I can't have preview for Camera before capturing. Means I want have a preview by my camera when VideoRecorderActivity1 is started.
Second: when I press start for ToggleButton, then every things rotates 90 degree that is very bad. But output file has correct degree for show. You can use from below code and see result.
Please help and solve my apps issue.Thanks.
Here is my Classess.
import java.io.File;
import java.io.IOException;
import android.hardware.Camera.Parameters;
import android.app.Activity;
import android.hardware.Camera;
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.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
import android.widget.ToggleButton;
public class VideoRecorderActivity1 extends Activity
implements SurfaceHolder.Callback
{
private SurfaceHolder surfaceHolder;
private SurfaceView surfaceView;
public MediaRecorder mrec= new MediaRecorder();
private Camera mCamera;
private ToggleButton mToggleButton=null;
private String Videname="";
private String Videopath="";
private VideoRecorder myVideo=null;
private static Boolean isRecording=false;
String filePath= Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator
+"My Audios"+File.separator+"video2camera5.3gpp";
private Boolean ExistVideo(String path1)
{
File file = new File(SDcard.Dir_recordedVideos );
File list[] = file.listFiles();
for( int i=0; i< list.length; i++)
{
if(list[i].getPath().equals(path1))
return true;
}
return false;
}
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.recorder_video);
InitializeUI();
mToggleButton.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
if (((ToggleButton) v).isChecked())
try
{ myVideo=new VideoRecorder();
do{
myVideo.setName();
Videname=myVideo.getName();
myVideo.setPath();
Videopath=myVideo.getPath();
}while(ExistVideo(Videopath));
startRecording();
}
catch (Exception e)
{
String message = e.getMessage();
Log.i(null, "Problem Start"+message);
if(mrec!= null)
mrec.release();
}
else
stopRecording();
}
});
}
protected void startRecording() throws IOException
{
String state = android.os.Environment.getExternalStorageState();
if (!state.equals(android.os.Environment.MEDIA_MOUNTED))
{
throw new IOException("SD Card is not mounted. It is " + state + ".");
}
// make sure the directory we plan to store the recording in exists
File directory = new File(this.Videopath).getParentFile();
if (!directory.exists() && !directory.mkdirs())
{
throw new IOException("Path to file could not be created.");
}
mrec = new MediaRecorder(); // Works well
mCamera.unlock();
mrec.setCamera(mCamera);
mrec.setPreviewDisplay(surfaceHolder.getSurface());
mrec.setAudioSource(MediaRecorder.AudioSource.MIC);
mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mrec.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mrec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mrec.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mrec.setOutputFile(Videopath);
mrec.prepare();
isRecording=true;
mrec.start();
}
protected void stopRecording()
{
if(mrec !=null)
mrec.stop();
releaseMediaRecorder();
isRecording=false;
}
private void releaseMediaRecorder()
{
if (mrec != null)
{
mrec.reset(); // clear recorder configuration
mrec.release(); // release the recorder object
mrec = null;
mCamera.lock(); // lock camera for later use
}
}
private void releaseCamera()
{
if (mCamera != null)
{
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
//------------------------------------------------------------
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height)
{
// TODO Auto-generated method stub
}
//------------------------------------------------------------
#Override
public void surfaceCreated(SurfaceHolder holder)
{
if (mCamera != null)
{
Parameters params = mCamera.getParameters();
mCamera.setParameters(params);
}
else
{
Toast.makeText(getApplicationContext(), "Camera not available!", Toast.LENGTH_LONG).show();
VideoRecorderActivity1.this.finish();
}
}
//------------------------------------------------------------
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
}
//------------------------------------------------------------
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK )
{
if(isRecording)
mCamera.stopPreview();
mCamera.release();
VideoRecorderActivity1.this.finish();
}
return super.onKeyDown(keyCode, event);
}
//------------------------------------------------------------
private void InitializeUI()
{
mCamera = Camera.open();
surfaceView = (SurfaceView) findViewById(R.id.surface_camera);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mrec.setPreviewDisplay(surfaceHolder.getSurface());
mToggleButton = (ToggleButton) findViewById(R.id.toggleRecordingButton);
}
}
And import this Class:
public class VideoRecorder
{
private String name="";
private static int id=0;
private String path=null;
public VideoRecorder()
{
}
public String getName()
{
return(this.name);
}
public void setName()
{
id++;
this.name="video "+id;
}
public String getPath()
{
return this.path;
}
public void setPath()
{
if (!this.name.contains("."))
{
this.name += ".3gpp";
}
this.path=SDcard.Dir_recordedVideos + this.name;
}
}
You are not creating the preview i think, in your surface created code put this:
public void surfaceCreated(SurfaceHolder holder) {
Log.v(TAG,"in surfaceCreated"); //Surface created for video preview and playback
try{
mCamera .setPreviewDisplay(holder);
mCamera .startPreview();
}catch(IOException e)
{
Log.v(TAG,"could not start the preview ");
e.printStackTrace();
}
}
In your startrecording function do it like this:
protected void startRecording() throws IOException
{
String state = android.os.Environment.getExternalStorageState();
if (!state.equals(android.os.Environment.MEDIA_MOUNTED))
{
throw new IOException("SD Card is not mounted. It is " + state + ".");
}
// make sure the directory we plan to store the recording in exists
File directory = new File(this.Videopath).getParentFile();
if (!directory.exists() && !directory.mkdirs())
{
throw new IOException("Path to file could not be created.");
}
mcamera.stopPreview();
mcamera.unlock();
mrec = new MediaRecorder(); // Works well
mrec.setCamera(mCamera);
mrec.setAudioSource(MediaRecorder.AudioSource.MIC);
mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mrec.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mrec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mrec.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mrec.setOutputFile(Videopath);
mrec.setPreviewDisplay(surfaceHolder.getSurface());
mrec.prepare();
isRecording=true;
mrec.start();
}

Record video and over the video show time and date over the video

Hi does anybody knows how to record video in android and for example above the recording screen at the bottom show current time and date
Here is code that record video in surface view and store in sdcard and for date and time by This
package com.po;
import java.io.IOException;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
public class VideoRD extends Activity implements OnClickListener,
SurfaceHolder.Callback {
MediaRecorder recorder;
SurfaceHolder holder;
boolean recording = false;
public static final String TAG = "VIDEOCAPTURE";
String str_getValue ;
#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);
Intent i1 = getIntent();
str_getValue = i1.getStringExtra("videoImagename");
recorder = new MediaRecorder();
initRecorder();
setContentView(R.layout.surface);
SurfaceView cameraView = (SurfaceView) findViewById(R.id.CameraView);
holder = cameraView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cameraView.setClickable(true);
cameraView.setOnClickListener(this);
final Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
if (recording) {
try {
recorder.stop();
recorder.release();
recording = false;
Log.v(TAG, "Recording Stopped");
initRecorder();
prepareRecorder();
} catch (Exception e) {
// TODO: handle exception
}
} else {
try {
recording = true;
recorder.start();
button.setText("stop");
} catch (Exception e) {
// TODO: handle exception
}
}
}
});
}
private void initRecorder() {
try {
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
// recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
CamcorderProfile cpHigh = CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH);
recorder.setProfile(cpHigh);
recorder.setOutputFile("/sdcard/audiometer/video/"+str_getValue+"");
recorder.setMaxDuration(1200000000); // 50 seconds
recorder.setMaxFileSize(22000000); // Approximately 5 megabytes
} catch (Exception e) {
// TODO: handle exception
}
}
private void prepareRecorder() {
try {
recorder.setPreviewDisplay(holder.getSurface());
try {
recorder.prepare();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (Exception e) {
// TODO: handle exception
}
}
public void onClick(View v) {
/*
* if (recording) { recorder.stop(); recorder.release(); recording =
* false; Log.v(TAG, "Recording Stopped"); initRecorder();
* prepareRecorder(); } else { recording = true; recorder.start(); }
*/
}
public void surfaceCreated(SurfaceHolder holder) {
prepareRecorder();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
finish();
}
}

how to switch between front and back camera when using MediaRecorder android

if anyone has any idea that how to switch between front and back camera when using MediaRecorder . I defing a button for this function, but have no idea how to define the onclickListener.
the total activity is the following:
import java.io.File;
import java.io.IOException;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.SurfaceHolder.Callback;
import android.view.View.OnClickListener;
import android.widget.Button;
public class Test_cameraActivity extends Activity implements Callback {
// Camera variables to fiddle with video preview.
// private Camera cam;
// Viewholders etc
private SurfaceHolder recordViewHolder;
private SurfaceView recordSurface;
private int width, height;
// Button
private Button recordBut;
private Button switchBut;
private Button libraryBut;
private final static String DIRECTORY = "/hdrecorder"; // Directory where
// the film is
// stored
private final static String recordFileName = "/hdtestfile.mp4";
private final static String saveFileName = "/hdsavefile.mp4";
private MyMediaRecorder recorder = null;
private final static String LOG_TAG = "HD Recorder";
private String filePath;
// Activity overrides
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// *******************************************
// fullscreen mode
// *******************************************
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// *******************************************
setContentView(R.layout.main);
File dir = new File(Environment.getExternalStorageDirectory()
+ DIRECTORY);
if (!dir.exists()) {
if (dir.mkdir()) {
Log.v(LOG_TAG, "Created directory");
} else {
Log.v(LOG_TAG, "Failed to create Directory");
}
}
File videoFile = new File(Environment.getExternalStorageDirectory()
+ DIRECTORY + recordFileName);
if (!videoFile.exists()) {
videoFile.delete(); // Reset recording
}
filePath = videoFile.getAbsolutePath();
Log.v(LOG_TAG, "PATH:" + filePath);
Log.v(LOG_TAG, "PATH:" + filePath);
recordSurface = (SurfaceView) findViewById(R.id.videoSurface);
recordBut = (Button) findViewById(R.id.RecordBut);
recordBut.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (recorder.getState() != MyMediaRecorder.RECORDING) {
startRecord();
} else {
stopRecord();
recorder.release();
moveRecordFileToSave();
if (recorder == null) {
Log.v(LOG_TAG, "Recorder is null");
}
Log.v(LOG_TAG, "Value of recorder:" + recorder);
createRecorder();
initiateRecorder(recordViewHolder, width, height);
}
}
});
switchBut = (Button) findViewById(R.id.SwitchBut);
switchBut.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
}
});
libraryBut = (Button) findViewById(R.id.LibraryBut);
libraryBut.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Test_cameraActivity.this,
FileExplorer.class);
Test_cameraActivity.this.startActivity(intent);
}
});
recordViewHolder = recordSurface.getHolder();
recordViewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
recordViewHolder.addCallback(this);
// setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
createRecorder();
}
#Override
protected void onStart() {
super.onStart();
Log.v(LOG_TAG, "OnStart");
if (recorder != null) {
if (recorder.getState() == MyMediaRecorder.RELEASED) {
createRecorder();
}
}
Log.v(LOG_TAG, "SurfaceView create initiated. OnStart Done");
}
#Override
protected void onStop() {
super.onStop();
Log.v(LOG_TAG, "onStop received");
forceStopRecorder();
}
// General Helpers.
private void createRecorder() {
recorder = new MyMediaRecorder();
}
private void startRecord() {
if (recorder.getState() != MyMediaRecorder.PREPARED) {
Log.e(LOG_TAG, "Not recordable yet");
return;
}
recorder.start();
Log.v(LOG_TAG, "Recording started");
recordBut.setText("Stop Record");
}
private void stopRecord() {
Log.v(LOG_TAG, "Stop of recorder");
if (recorder.getState() == MyMediaRecorder.RECORDING) {
recorder.stop();
}
recorder.reset();
recordBut.setText("Record");
}
private void initiateRecorder(SurfaceHolder holder, int width, int height) {
Log.v(LOG_TAG, "H: " + height + " W:" + width);
if (recorder.getState() != MyMediaRecorder.INITIAL) {
Log.v(LOG_TAG, "Dude - not existing MediaRecorder - quitting");
return;
}
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(this.filePath);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setVideoSize(width, height);
recorder.setVideoFrameRate(24);
recorder.setPreviewDisplay(holder.getSurface());
Log.d(LOG_TAG, "Preview restarted");
try {
recorder.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// isPrepared = true;
}
private void forceStopRecorder() {
Log.v(LOG_TAG, "Force release of recorder");
if (recorder.getState() != MyMediaRecorder.RELEASED) {
stopRecord();
recorder.release();
}
}
private void moveRecordFileToSave() {
File source = new File(filePath);
File dest = new File(Environment.getExternalStorageDirectory()
+ DIRECTORY + saveFileName);
if (dest.exists()) {
Log.v(LOG_TAG, "Delete old save file");
dest.delete();
}
source.renameTo(dest);
}
// ***** Implementing Callback ********/
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
recordViewHolder = holder;
this.width = width;
this.height = height;
if (recorder.getState() == MyMediaRecorder.RECORDING) {
stopRecord();
}
if (recorder.getState() == MyMediaRecorder.PREPARED) {
recorder.reset();
}
initiateRecorder(holder, width, height);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
Log.v(LOG_TAG, "Surface is created: Path to use" + filePath);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
Log.v(LOG_TAG, "Surface is Destroyed");
forceStopRecorder();
}
}
I have something that might also help, in order to jump to the other camera, follow this method:
public void flipit() {
//myCamera is the Camera object
if (Camera.getNumberOfCameras()>=2) {
myCamera.stopPreview();
myCamera.release();
//"which" is just an integer flag
switch (which) {
case 0:
myCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
which = 1;
break;
case 1:
myCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
which = 0;
break;
}
try {
myCamera.setPreviewDisplay(mHolder);
//"this" is a SurfaceView which implements SurfaceHolder.Callback,
//as found in the code examples
myCamera.setPreviewCallback(this);
myCamera.startPreview();
} catch (IOException exception) {
myCamera.release();
myCamera = null;
}
}
}
Now... for the magic trick, don't call this method from the main thread. Instead this method has to be kicked off from a separate thread, my code does this:
//btn is a Button that the user clicks on
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//onClick is invoked from main thread
//kick-off a different Thread to handle this call
Thread t = new Thread() {
public void run() {
//myViewer is the SurfaceView object which uses
//the camera
myViewer.flipit();
}
};
t.start();
}
});
I've tested this on Android 4.1.1 so I think it might work for you. (or until Google decides to break the way the camera opening/closing/releasing/unlocking/reconnecting/surfaceholder/onPause/onResume/etc..? works)
First, check if your device has more than one camera:
Camera.getNumberOfCameras();
Then, assign a camId value:
camId = Camera.CameraInfo.CAMERA_FACING_BACK;
or
camId = Camera.CameraInfo.CAMERA_FACING_FRONT;
and then creates a new Camera object to access a particular hardware camera (camId).
mCamera = Camera.open(camId);
Hope this help!

Categories

Resources