I'm trying to create a video recorder on Android, and I've prepared my code which is supposed to be working - but I constantly get an error message start failed: -19.
Here's my code:
public boolean startRecording() {
try {
camera.unlock();
mediaRecorder = new MediaRecorder();
mediaRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() {
#Override
public void onError(MediaRecorder mr, int what, int extra) {
Log.i(TAG, "Error");
}
});
mediaRecorder.setCamera(camera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
Log.i(TAG, "a");
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
Log.i(TAG, "b");
mediaRecorder.setMaxDuration(maxDurationInMs); // set to 20000
String uniqueOutFile = OUTPUT_FILE + System.currentTimeMillis() + ".3gp";
File outFile = new File(uniqueOutFile);
if (outFile.exists()) {
outFile.delete();
}
mediaRecorder.setOutputFile(uniqueOutFile);
mediaRecorder.setVideoFrameRate(videoFramesPerSecond); // set to 20
mediaRecorder.setVideoSize(sView.getWidth(), sView.getHeight());
Log.i(TAG, "c");
mediaRecorder.setPreviewDisplay(holder.getSurface());
mediaRecorder.setMaxFileSize(maxFileSizeInBytes); // set to 50000
mediaRecorder.prepare();
Log.i(TAG, "d");
mediaRecorder.start();
Log.i(TAG, "e");
return true;
} catch (IllegalStateException e) {
Log.i(TAG, "f");
Log.e(TAG, e.getMessage());
e.printStackTrace();
camera.lock();
return false;
} catch (IOException e) {
Log.i(TAG, "g");
Log.e(TAG, e.getMessage());
e.printStackTrace();
camera.lock();
return false;
} catch (RuntimeException e) {
Log.i(TAG, "h");
Log.e(TAG, e.getMessage());
camera.lock();
return false;
}
}
All the debug logs (from "a" through "d") are printed in log, so it seems that all the steps upto mediaRecorder.prepare() are properly done. Then it catches a RuntimeException with message start failed: -19. There is a similar question, but that doesn't solve my problem.
Is there any other reason to get such an error?
Just found out the bug, in this line:
mediaRecorder.setVideoSize(sView.getWidth(), sView.getHeight());
after commenting out this line, the code runs perfectly!
I solved my problem once i added this for video recording
/**
* Start video recording by cleaning the old camera preview
*/
private void startVideoRecorder() {
// THIS IS NEEDED BECAUSE THE GLASS CURRENTLY THROWS AN ERROR OF
// "MediaRecorder start failed: -19"
// THIS WONT BE NEEDED INCASE OF PHONE AND TABLET
// This causes crash in glass kitkat version so remove it
// try {
// mCamera.setPreviewDisplay(null);
// } catch (java.io.IOException ioe) {
// Log.d(TAG,
// "IOException nullifying preview display: "
// + ioe.getMessage());
// }
// mCamera.stopPreview();
// mCamera.unlock();
recorder = new MediaRecorder();
// Let's initRecorder so we can record again
initRecorder();
}
/**
* Initialize video recorder to record video
*/
private void initRecorder() {
try {
File dir = new File(folderPath);
if (!dir.exists()) {
dir.mkdirs();
}
mCamera.stopPreview();
mCamera.unlock();
videofile = new File(dir, fileName + ".mp4");
recorder.setCamera(mCamera);
// Step 2: Set sources
recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
recorder.setProfile(CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH));
// Step 4: Set output file
recorder.setOutputFile(videofile.getAbsolutePath());
// Step 5: Set the preview output
recorder.setPreviewDisplay(mPreview.getHolder().getSurface());
// Step 6: Prepare configured MediaRecorder
recorder.setMaxDuration(video_duration * 1000);
recorder.setOnInfoListener(new OnInfoListener() {
#Override
public void onInfo(MediaRecorder mr, int what, int extra) {
if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
mCamera.stopPreview();
releaseMediaRecorder();
/*
* initiate media scan and put the new things into the
* path array to make the scanner aware of the location
* and the files you want to see
*/MediaScannerConnection.scanFile(
CuxtomCamActivity.this,
new String[] { videofile.getPath() }, null,
null);
Intent intent = new Intent();
intent.putExtra(CuxtomIntent.FILE_PATH,
videofile.getPath());
intent.putExtra(CuxtomIntent.FILE_TYPE, FILE_TYPE.VIDEO);
setResult(RESULT_OK, intent);
finish();
}
}
});
recorder.prepare();
recorder.start();
} catch (Exception e) {
Log.e("Error Stating CuXtom Camera", e.getMessage());
}
}
private void releaseMediaRecorder() {
if (recorder != null) {
recorder.reset(); // clear recorder configuration
recorder.release(); // release the recorder object
recorder = null;
}
}
For detailed guide refer to this Open Source Cuxtom Cam
the problem is in your setVideoSize() code .
and why this code error ...
From the research I have done, error code -19 comes about when there is a problem with the size of the video as set by MediaRecorder#setVideoSize()
run this code , and see whitch screen that your camera in your device can support :
final List<Camera.Size> mSupportedVideoSizes = getSupportedVideoSizes(mCamera);
for (Camera.Size str : mSupportedVideoSizes)
Log.e(TAG, "mSupportedVideoSizes "+str.width + ":" + str.height + " ... "
+ ((float) str.width / str.height));
and method is :
public List<Size> getSupportedVideoSizes(Camera camera) {
if (camera.getParameters().getSupportedVideoSizes() != null) {
return camera.getParameters().getSupportedVideoSizes();
} else {
// Video sizes may be null, which indicates that all the supported
// preview sizes are supported for video recording.
return camera.getParameters().getSupportedPreviewSizes();
}
}
I had that problem with some specific phones, I've found out that I couldn't set camcoder profile sizes in some of them. But when that worked for the problematic androids it stopped working on the previous working devices.
So in the end my implemented logic was something like:
Set width/height
Try to start the merdia recorder
In case of exception, try again without setting width/height
Kind of a trash logic, but that worked.
I've setup a github project with that implementation, try it out: https://github.com/rafaelsilverio/MediaRecorder
I also encountered this problem and annotated the following two ways, because the hardware does not support the two configurations.
MediaRecorder .setVideoSize()
MediaRecorder .setVideoFrameRate()
Related
I'm attempting to create a simple app that records audio. I'm using the standard MediaRecorder to achieve that. Here is what I have so far:
I'm successfully starting the mediaRecorder using this method
public void startRecording(String filePath) 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(filePath).getParentFile();
if (!directory.exists() && !directory.mkdirs()) {
throw new IOException("Path to file could not be created.");
}
recorder.setAudioSource(MediaRecorder.AudioSource.MIC );
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(filePath);
recorder.setOnErrorListener(errorListener);
recorder.setOnInfoListener(infoListener);
try {
recorder.prepare();
} catch (Exception e) {
Timber.e("Error while prepareing media recorder " + e.getMessage());
}
try {
recorder.start();
SharedPrefs.setIsRecording(true);
Timber.d("Started to record " + SharedPrefs.isRecording());
} catch (Exception e) {
Timber.e("Error while starting the media recorder " + e.getMessage());
} }
this works fine and I can see locally that the file is created in the specified folder.
Now this is what I use to stop recording:
public void stopRecording() {
if (recorder == null) {
Timber.e("recorder is null");
}
if (SharedPrefs.isRecording()) {
try {
recorder.stop();
} catch (Exception r) {
Timber.e("Error while attempting to stop " + r.getMessage());
}
try {
recorder.release();
} catch (Exception e) {
Timber.e("Error while attempting to release " + e.getMessage());
}
Timber.e("We stopped recording");
SharedPrefs.setIsRecording(false);
} else {
Timber.e("Attempting to stop recording while not recording ");
} }
Now when stopRecording() is being called this is the error message that I get:
E/MediaRecorder: stop called in an invalid state:1
AudioRecorder: Error while attempting to stop null
Note: When I locally go to the folder where the file is and I refresh it, I can see the size of the file is incrementing.
Thanks in advance!
I am trying to write video to socket (with ParcelFileDescriptor). But when calling mediaPlayer.start() method - an IllegalStateException occurs with this message - "E/MediaRecorder: start failed: -38".
Code for file descriptor (Socket is 100% properly connected by the time programm calls it):
public ParcelFileDescriptor getFileDescriptorToSocket() {
return ParcelFileDescriptor.fromSocket(socket);
}
Preparing media recorder:
private boolean prepareMediaRecorder() {
mediaRecorder = new MediaRecorder();
camera.unlock();
mediaRecorder.setCamera(camera);
// mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setPreviewDisplay(cameraSurface.getHolder().getSurface());
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setVideoSize(320, 240);
mediaRecorder.setVideoFrameRate(30);
//mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_720P));
mediaRecorder.setOutputFile(MainActivity.socketClient.getFileDescriptorToSocket().getFileDescriptor());
try {
mediaRecorder.prepare();
} catch (IllegalStateException ise) {
// TODO Delete test code
Log.d(TAG, "Error during MediaRecorder preparing: " + ise.getMessage());
ise.printStackTrace();
releaseMediaRecorder();
return false;
} catch (IOException ioe) {
// TODO Delete test code
Log.d(TAG, "Error during MediaRecorder preparing: " + ioe.getMessage());
ioe.printStackTrace();
releaseMediaRecorder();
return false;
}
return true;
}
and call for start recording:
private void startRecording() {
if (!prepareMediaRecorder()) {
// TODO Delete test code
Log.d(TAG, "Error starting recording process");
finish();
} else {
new Thread(new Runnable() {
#Override
public void run() {
try {
mediaRecorder.start();
} catch (Exception e) {
// TODO Delete test code
Log.d(TAG, "Error in recording thread: " + e.getMessage());
e.printStackTrace();
}
}
}).start();
recordingStatus = true;
}
}
I should note that when i disable start recording method - camera works fine - i can properly see camera preview surface.
I am able to get the video frame data in the form of byte array from onPreviewFrame(). I need to make a video from this byte array.
Below is my code snippet:
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
try {
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
}
}
FileOutputStream out = new FileOutputStream(mediaStorageDir.getAbsolutePath() + "video.mp4");
out.write(data);
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The resultant file "video.mp4" is not playable.
Any help or guidance to resolve the issue will be well appreciated.
Note
My application is going to support Android 4+ versions.
here is code for take picture & video
// Add listener to video capture button
VideoCapture = (Button)findViewById(R.id.buttonVideo);
VideoCapture.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
captureButton.setVisibility(View.GONE);
if(isRecording){
VideoCapture.setBackgroundResource(R.drawable.ic_action_videoplay);
// 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;
}
else{
releaseCamera();
// 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
}
VideoCapture.setBackgroundResource(R.drawable.ic_launcher_videopause);
isRecording = true;
}
}
});
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();
/* set image preview in imageview */
previewImage = (ImageView)findViewById(R.id.imageViewPrieview);
previewImage.setImageURI(Uri.fromFile(pictureFile));
/* release camera & removeallview from preview */
relaese();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
/** Create a file Uri for saving an image or video */
private Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private 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());
if (type == MEDIA_TYPE_IMAGE){
// mediaFile = new File(mediaStorageDir.getPath() + File.separator +
// "IMG_"+ timeStamp + ".jpg");
mediaFile = new File("/sdcard/"+ "IMG_"+ timeStamp + ".jpg");
Log.i("Image","Image is captured");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
These code for prepare video recorder
private boolean prepareVideoRecorder(){
mCamera = getCameraInstance();
mMediaRecorder = new MediaRecorder();
// step 1: Unlock camera & Set camera to MediaRecorder
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
// step 2: set Audio & Video Source
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// step 3: set camcorder profile , it required Api Level 8
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
// step 4: set output file
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
// step 5: set preview output
mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
// step 6: prepare Configured Media recorder
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d("TAG","IllegalStateException preparing MediaRecorder" + e.getMessage());
return false;
}catch (IOException e) {
Log.d("TAG","IO Exception preparing MediaRecorde" + e.getMessage());
return false;
}
return true;
}
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
}
I think this will help you. because it work for me.
The Android API currently does not provide the pause method
This is a bit technical, but was solicited on the comments.
The public class MediaRecorder, being used since API level 1, doesn't has the capability to pause, as one can observe from the MediaRecorder State Diagram:
When recording, the API allows us to either use the reset() or stop() Public Methods:
reset() -> Restarts the MediaRecorder to its idle state.
stop() -> Stops recording.
I'm trying to develop a video recorder with the front and back camera. The app can switch between the back (default) and front camera. When the app is activated the front camera, and I press the recording button, the app goes to on error method, and I release and init the camera and the recording, but the error persists another time. Any idea?
UPDATE: I update the onError method, with the code below, and I think I don't make the release and the init camera well, because when the app executes this method the surface holder is black and doesn't give me what the camera sees
Here, my code:
onError method:
public void onError(MediaRecorder mr, int what, int extra) {
stopRecording();
//if Error 100, app must release the Camera object and instantiate a new one.
if (what == 100) {
if (error_100 == 2) { //Error 100 persists, change camera
if (Camera.getNumberOfCameras() <= 1) {
//No mas camaras para app
} else {
if (selected_camera == FRONT_CAMERA) {
selected_camera=BACK_CAMERA;
} else {
selected_camera=FRONT_CAMERA;
}
selected_camera_button.setEnabled(false);
Toast.makeText(this, "Initializing other camera", Toast.LENGTH_SHORT).show();
}
} else { //No camera init finish activity
if (error_100 == 3) {
Toast.makeText(this, "Initialize cameras failed", Toast.LENGTH_SHORT).show();
finish();
} else {
Toast.makeText(this, "Recording error has occurred. Stopping the recording", Toast.LENGTH_SHORT).show();
}
}
error_100++;
initCamera();
initCameraRecorder();
}
}
And the other method:
/** Initializes the back/front camera */
private boolean initCamera() {
try {
camera = getCameraInstance(selected_camera);
Camera.Parameters camParams = camera.getParameters();
camParams.set( "cam_mode", 1 );
camParams.set("orientation", "portrait");
checkCameraFlash(camParams);
//Establish the rotation angle camera
setAngleCameraRotation();
camera.setDisplayOrientation(angle_rotation_camera);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Establish 4:3 ratio and 480x640 if is posible
setAspectResolutionCamera(camParams);
camera.setParameters(camParams);
//Camera eye
video_view.getHolder().setFixedSize(height_video, width_video);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(height_video, width_video);
video_view.setLayoutParams(lp);
camera.lock();
surface_holder = video_view.getHolder();
surface_holder.addCallback(this);
surface_holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
setPreviewCamera();
} catch(Exception e) {
Log.v("RecordVideo", "Could not initialize the Camera");
return false;
}
return true;
}
/** Initializes the camera recorder before starts the recording */
private void initCameraRecorder() {
if(media_recorder != null) return;
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
output_file_name = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + File.separator + timeStamp + ".mp4";
File outFile = new File(output_file_name);
if(outFile.exists()) {
outFile.delete();
}
try {
camera.stopPreview();
camera.unlock();
media_recorder = new MediaRecorder();
media_recorder.setCamera(camera);
media_recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
media_recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
profile.videoBitRate = 885000; //Medium quality
profile.videoFrameHeight = height_video;
profile.videoFrameWidth = width_video;
media_recorder.setProfile(profile);
media_recorder.setMaxDuration(21000); // limit to 21 seconds
media_recorder.setOrientationHint(setOrientationCameraRecorder());
media_recorder.setPreviewDisplay(surface_holder.getSurface());
media_recorder.setOutputFile(output_file_name);
media_recorder.prepare();
Log.v("RecordVideo", "MediaRecorder initialized");
} catch(Exception e) {
Log.v("RecordVideo", "MediaRecorder failed to initialize");
e.printStackTrace();
}
}
/** Starts the recording video */
private void beginRecording() {
media_recorder.setOnInfoListener(this);
media_recorder.setOnErrorListener(this);
media_recorder.start();
record_button.setTextColor(getResources().getColor(android.R.color.holo_red_dark));
}
/** Stops the recording video */
private void stopRecording() {
if (media_recorder != null) {
media_recorder.setOnErrorListener(null);
media_recorder.setOnInfoListener(null);
try {
media_recorder.stop();
} catch(IllegalStateException e) {
// This can happen if the recorder has already stopped.
Log.e("INFO:", "Got IllegalStateException in stopRecording");
}
releaseRecorder();
record_button.setTextColor(getResources().getColor(android.R.color.black));
releaseCamera();
}
video_task.cancel(true);
output_file_name.isEmpty();
}
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" />