I am writing a video capture app for android. I have preview first time I want to capture. But after I press stop, I no longer get preview when I start recording again. How can I have preview option permanently?
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();
}
//-------------------------------------------------------------
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)
{
try {
mCamera .setPreviewDisplay(holder);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera .startPreview();
}
//-------------------------------------------------------------
#Override
public void surfaceCreated(SurfaceHolder holder)
{
if (mCamera != null)
{
Parameters params = mCamera.getParameters();
mCamera.setParameters(params);
mCamera.setDisplayOrientation(90);
try {
mCamera .setPreviewDisplay(holder);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera .startPreview();
}
else
{
Toast.makeText(getApplicationContext(), "Camera not available!", Toast.LENGTH_LONG).show();
VideoRecorderActivity.this.finish();
}
}
//-------------------------------------------------------------
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
}
After you press stop recording either you can play the recorded video or if you want to restart your preview then in your stoprecording method do this:
protected void stopRecording()
{
if(mrec !=null)
try{
mrec.stop();
}catch(IllegalStateException e)
{
Log.e(TAG,"Got illegal ");
}
releaseRecorder();
releaseCamera();
isRecording=false;
/*Here do the same process which you do while creating the preview i.e initilize the camera and create the preview */
mCamera = Camera.open();
camera.lock();
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
try{
mCamera .setPreviewDisplay(holder);
mCamera .startPreview();
}catch(IOException e)
{
Log.v(TAG,"could not start the preview ");
e.printStackTrace();
}
}
// release the recorder after recording
private void releaseRecorder() {
if( mrec!=null){
Log.v(TAG, "recorder released");
mrec.release();
mrec=null;
}
}
// release the camera after recording
private void releaseCamera() {
if(mcamera!=null){
try{
mcamera.reconnect();
}catch(IOException e){
e.printStackTrace();
}
Log.v(TAG, "camera released");
mcamera.release();
mcamera=null;
}
Related
I am developing an app which should record a video of Maximum limit one minute, and saving it in gallery and then right after it saves it should start playing automatically.
Following is my code.
public class MainActivity extends Activity {
private Camera myCamera;
private MyCameraSurfaceView myCameraSurfaceView;
private MediaRecorder mediaRecorder;
Button myButton;
SurfaceHolder surfaceHolder;
boolean recording;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
recording = false;
setContentView(R.layout.main);
//Get Camera for preview
myCamera = getCameraInstance();
if(myCamera == null){
Toast.makeText(MainActivity.this,
"Fail to get Camera",
Toast.LENGTH_LONG).show();
}
myCameraSurfaceView = new MyCameraSurfaceView(this, myCamera);
FrameLayout myCameraPreview = (FrameLayout)findViewById(R.id.videoview);
myCameraPreview.addView(myCameraSurfaceView);
myButton = (Button)findViewById(R.id.mybutton);
myButton.setOnClickListener(myButtonOnClickListener);
Log.i("Camera !Error", "Cameray ka koi masla ni Agay chcek karo");
}
Button.OnClickListener myButtonOnClickListener
= new Button.OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(recording){
// stop recording and release camera
mediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
//Exit after saved
finish();
}else{
//Release Camera before MediaRecorder start
releaseCamera();
if(!prepareMediaRecorder()){
Toast.makeText(MainActivity.this,
"Fail in prepareMediaRecorder()!\n - Ended -",
Toast.LENGTH_LONG).show();
finish();
}
mediaRecorder.start();
recording = true;
myButton.setText("STOP");
Log.i("Camera !Error", "Record to stop");
}
}};
private Camera getCameraInstance(){
// TODO Auto-generated method stub
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
Log.i("Camera Error", "Camera Not Found");
}
Log.i("Camera Error", "Camera Found");
return c; // returns null if camera is unavailable
}
private boolean prepareMediaRecorder(){
myCamera = getCameraInstance();
mediaRecorder = new MediaRecorder();
myCamera.unlock();
mediaRecorder.setCamera(myCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
mediaRecorder.setOutputFile("/sdcard/myvideo2.3gp");
mediaRecorder.setMaxDuration(10000); // Set max duration 10 sec.
mediaRecorder.setMaxFileSize(5000000); // Set max file size 5M
mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder().getSurface());
Log.i("Camera Error", "Media Recorder is ready");
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
return true;
}
#Override
protected void onPause() {
super.onPause();
releaseMediaRecorder(); // if you are using MediaRecorder, release it first
releaseCamera(); // release the camera immediately on pause event
}
private void releaseMediaRecorder(){
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
myCamera.lock(); // lock camera for later use
}
Log.i("Media Recorder", "Media Recorer Released");
}
private void releaseCamera(){
if (myCamera != null){
myCamera.release(); // release the camera for other applications
myCamera = null;
}
Log.i("Camera Recorder", "Camera Released");
}
public class MyCameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mHolder;
private Camera mCamera;
public MyCameraSurfaceView(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);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int weight,
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
}
// make any resize, rotate or reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
}
my main.xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:id="#+id/videoview"
android:layout_width="720px"
android:layout_height="480px"/>
<Button
android:id="#+id/mybutton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="REC"
android:textSize="12sp"/>
</LinearLayout>
On button click recording starts and on click again, it stops and exits using
finish() for this purpose. Here i want that instead of exiting the recorded video should start.
Hope i managed to clearly explain my question.
I am trying to use the front camera to record. My code is working fine
with the back camera.
The problem is in getFrontCameraId() and getCameraInstance()
Here is my code..
public class AndroidVideoCapture extends Activity{
private Camera myCamera;
private MyCameraSurfaceView myCameraSurfaceView;
private MediaRecorder mediaRecorder;
Button myButton;
SurfaceHolder surfaceHolder;
boolean recording;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
recording = false;
setContentView(R.layout.activity_android_video_capture);
//Get Camera for preview
myCamera = getCameraInstance();
if(myCamera == null){
Toast.makeText(AndroidVideoCapture.this,
"Fail to get Camera",
Toast.LENGTH_LONG).show();
}
myCameraSurfaceView = new MyCameraSurfaceView(this, myCamera);
FrameLayout myCameraPreview = (FrameLayout)findViewById(R.id.videoview);
myCameraPreview.addView(myCameraSurfaceView);
myButton = (Button)findViewById(R.id.mybutton);
myButton.setOnClickListener(myButtonOnClickListener);
}
Button.OnClickListener myButtonOnClickListener
= new Button.OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(recording){
// stop recording and release camera
mediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
//Exit after saved
finish();
}else{
//Release Camera before MediaRecorder start
releaseCamera();
if(!prepareMediaRecorder()){
Toast.makeText(AndroidVideoCapture.this,
"Fail in prepareMediaRecorder()!\n - Ended -",
Toast.LENGTH_LONG).show();
finish();
}
mediaRecorder.start();
recording = true;
myButton.setText("STOP");
}
}};
public int getFrontCameraId() {
CameraInfo ci = new CameraInfo();
for (int i = 0 ; i < Camera.getNumberOfCameras(); i++) {
Camera.getCameraInfo(i, ci);
if (ci.facing == CameraInfo.CAMERA_FACING_FRONT) return i;
}
return -1; // No front-facing camera found
}
private Camera getCameraInstance(){
// TODO Auto-generated method stub
Camera c = null;
try {
int index = getFrontCameraId();
if (index == -1)
c = Camera.open(index);
// 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 prepareMediaRecorder(){
myCamera = getCameraInstance();
mediaRecorder = new MediaRecorder();
myCamera.unlock();
mediaRecorder.setCamera(myCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
mediaRecorder.setOutputFile("/sdcard/myvideo.mp4");
mediaRecorder.setMaxDuration(60000); // Set max duration 60 sec.
mediaRecorder.setMaxFileSize(5000000); // Set max file size 5M
mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder().getSurface());
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
return true;
}
#Override
protected void onPause() {
super.onPause();
releaseMediaRecorder(); // if you are using MediaRecorder, release it first
releaseCamera(); // release the camera immediately on pause event
}
private void releaseMediaRecorder(){
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
myCamera.lock(); // lock camera for later use
}
}
private void releaseCamera(){
if (myCamera != null){
myCamera.release(); // release the camera for other applications
myCamera = null;
}
}
public class MyCameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mHolder;
private Camera mCamera;
public MyCameraSurfaceView(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);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int weight,
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
}
// make any resize, rotate or reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
}
You have a wrong condition in your module
private Camera getCameraInstance() {
// TODO Auto-generated method stub
Camera c = null;
try {
int index = getFrontCameraId();
if (index == -1)
c = Camera.open(index);
// 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
}
It should be
private Camera getCameraInstance() {
// TODO Auto-generated method stub
Camera c = null;
try {
int index = getFrontCameraId();
if (index != -1)
c = Camera.open(index);
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
public class FulfillVideoTaskActivity extends Activity implements SurfaceHolder.Callback, OnInfoListener, OnErrorListener{
private Button initBtn = null;
private Button startBtn = null;
private Button stopBtn = null;
private Button playBtn = null;
private Button stopPlayBtn = null;
// save Button should be implemented
private TextView recordingMsg = null;
private VideoView videoView = null;
private SurfaceHolder holder = null;
private Camera camera = null;
private static final String TAG ="RecordVideo";
private MediaRecorder recorder = null;
private String outputFileName;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fulfill_video_task);
// get references to UI elements
initBtn = (Button) findViewById(R.id.initBtn);
startBtn = (Button) findViewById(R.id.startBtn);
stopBtn = (Button) findViewById(R.id.stopBtn);
playBtn = (Button) findViewById(R.id.playBtn);
stopPlayBtn = (Button) findViewById(R.id.stopPlayBtn);
recordingMsg = (TextView) findViewById(R.id.recording);
videoView = (VideoView)this.findViewById(R.id.videoView);
}
public void buttonTapped(View view) {
switch(view.getId()) {
case R.id.initBtn:
initRecorder();
break;
case R.id.startBtn:
beginRecording();
break;
case R.id.stopBtn:
stopRecording();
break;
case R.id.playBtn:
playRecording();
break;
case R.id.stopPlayBtn:
stopPlayback();
break;
}
}
private void stopPlayback() {
videoView.stopPlayback();
}
private void playRecording() {
MediaController mc = new MediaController(this);
videoView.setMediaController(mc);
videoView.setVideoPath(outputFileName);
videoView.start();
stopPlayBtn.setEnabled(true);
}
private void stopRecording() {
if(recorder != null) {
recorder.setOnErrorListener(null);
recorder.setOnInfoListener(null);
try {
recorder.stop();
}
catch(IllegalStateException e) {
//this can happen if the recorder has already stopped.
Log.e(TAG, "Got IllegalStateException in stopRecording");
}
releaseRecorder();
recordingMsg.setText("");
releaseCamera();
startBtn.setEnabled(false);
stopBtn.setEnabled(false);
playBtn.setEnabled(true);
}
}
private void releaseCamera() {
if(camera != null) {
try {
camera.reconnect();
} catch (IOException e) {
e.printStackTrace();
}
camera.release();
camera = null;
}
}
private void releaseRecorder() {
if(recorder != null) {
recorder.release();
recorder = null;
}
}
private void beginRecording() {
recorder.setOnInfoListener(this);
recorder.setOnErrorListener(this);
recorder.start();
recordingMsg.setText("RECORDING");
startBtn.setEnabled(false);
stopBtn.setEnabled(true);
}
// Initialize the recorder
private void initRecorder() {
if(recorder != null) return;
// The place where the video will be saved.
outputFileName = Environment.getExternalStorageDirectory() + "/videooutput.mp4";
File outFile = new File(outputFileName);
//if File already exists, we delete it
if(outFile.exists())
outFile.delete();
try{
camera.stopPreview();
camera.unlock();
recorder = new MediaRecorder();
recorder.setCamera(camera);
recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setVideoSize(280, 200);
recorder.setVideoFrameRate(15);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setMaxDuration(10000); // limit to 10 seconds
recorder.setPreviewDisplay(holder.getSurface());
recorder.setOutputFile(outputFileName); // setting our output file to our FileName
recorder.prepare();
Log.v(TAG, "MediaRecorder initialized");
initBtn.setEnabled(false);
startBtn.setEnabled(true);
}
//error checking
catch(Exception e) {
Log.v(TAG, "MediaRecorder failed to initialize");
e.printStackTrace();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_fulfill_video_task, menu);
return true;
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
public void surfaceCreated(SurfaceHolder holder) {
Log.v(TAG, "in sufaceCreated");
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
}catch (IOException e) {
Log.v(TAG, "Could not start the preview");
e.printStackTrace();
}
initBtn.setEnabled(true);
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
public void onError(MediaRecorder mr, int what, int extra) {
Log.e(TAG, "got a recording error");
stopRecording();
Toast.makeText(this, "Recording error has occurred. Stopping the recording", Toast.LENGTH_SHORT).show();
}
public void onInfo(MediaRecorder mr, int what, int extra) {
Log.i(TAG, "got a recording event");
if(what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
Log.i(TAG, "...max duration reached");
stopRecording();
Toast.makeText(this, "Recording limit has been reached. Stopping the recording", Toast.LENGTH_SHORT).show();
}
}
// disable the buttons until the camera is initialized
protected void onResume() {
Log.v(TAG, "in onResume");
super.onResume();
initBtn.setEnabled(false);
startBtn.setEnabled(false);
stopBtn.setEnabled(false);
playBtn.setEnabled(false);
stopPlayBtn.setEnabled(false);
if(!initCamera())
finish();
}
// initializes the camera
private boolean initCamera() {
try {
camera = Camera.open();
Camera.Parameters camParams = camera.getParameters();
camera.lock();
holder = videoView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
catch(RuntimeException re) {
Log.v(TAG, "Could not initialize the Camera");
re.printStackTrace();
return false;
}
return true;
}
}
Hi, I'm trying to record a video on android right now, when I run my code (the whole code above), the camera can't be initialized. I guess I have an error in the following part.
private boolean initCamera() {
try {
camera = Camera.open();
Camera.Parameters camParams = camera.getParameters();
camera.lock();
holder = videoView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
catch(RuntimeException re) {
Log.v(TAG, "Could not initialize the Camera");
re.printStackTrace();
return false;
}
return true;
}
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); this line in this code gets multiple markers, saying
The method setType(int) from the type SurfaceHolder is deprecated
The field SURFACE_TYPE_PUSH_BUFFERS is deprecated
Does anyone know the reason why I'm getting this?
Try this code
first
setRecorder() ;
SurfaceView videoShootSurfaceView = (SurfaceView) findViewById(R.id.shootVideosurfaceView_VSD);
SurfaceHolder videoSurfaceHolder = videoShootSurfaceView.getHolder();
videoSurfaceHolder.addCallback(this);
videoSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
set the recorder type
public void setRecorder() {
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
// recorder.setVideoSize(640, 480);
recorder.setVideoSize(320, 240);
// recorder.setVideoSize(480, 320);
// recorder.setVideoSize(176, 144);
recorder.setVideoFrameRate(15);
// recorder.setMaxDuration(3600000);
recorder.setMaxDuration(300000);
recorder.setOutputFile("/sdcard/videocapture_example.mp4");
}
override this methhod.
#Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
recorder.setPreviewDisplay(holder.getSurface());
if (recorder != null) {
try {
recorder.prepare();
} catch (IllegalStateException e) {
Log.e("IllegalStateException", e.toString());
} catch (IOException e) {
Log.e("IOException", e.toString());
}
}
}
To start the recording
public void startRecording() {
setRecorder();
recorder.setPreviewDisplay(recoderTempHolder.getSurface());
if (recorder != null) {
try {
recorder.prepare();
recorder.start();
} catch (IllegalStateException e) {
Log.e("IllegalStateException", e.toString());
} catch (IOException e) {
Log.e("IOException", e.toString());
}
}
}
To stop the recording
public void stopRecording() {
recorder.stop();
// recorder.reset();
recorder.release();
}
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" />
Is it possible to record video in a service, that is without setting the setPreviewDisplay?
I tried it on a HTC Desire, however it is throwing this info in the log,
MediaRecorder Prepare Failed: -1
CameraInput No surface is available for display
Is there some additional properties to be set?
I found this snippet somewhere. Not sure if it works for media recorder, but it was working reasonably well for camera.takePicture on HTC hero android 2.1-update1 (and simulator).
if (camera == null) {
Log.i(TAG, "Opening camera");
camera = Camera.open();
}
SurfaceView view = new SurfaceView(new DummyContext()); //You'll have to create your own class extending Context
camera.setPreviewDisplay(view.getHolder());
camera.startPreview();
//wait
Log.i(TAG, "Wait for cam");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Log.e(TAG, "Woken violently");
e.printStackTrace();
}
//take pic
Log.i(TAG, "Take pic");
camera.takePicture(shutterCallback, rawCallback, jpegCallback);
I believe according to the docs
public final void setPreviewDisplay
(SurfaceHolder holder)
Since: API Level 1 Sets the Surface to
be used for live preview. A surface is
necessary for preview, and preview is
necessary to take pictures. The same
surface can be re-set without harm.
I know you are desiring to take video but, I take this to me any camera usage requires a surface.
public class RecorderService extends Service {
private static final String TAG = "RecorderService";
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private static Camera mServiceCamera;
private boolean mRecordingStatus;
private MediaRecorder mMediaRecorder;
private File filefolder;
private String strphoto;
private File photo;
#Override
public void onCreate() {
mRecordingStatus = false;
//mServiceCamera = CameraRecorder.mCamera;
mServiceCamera = Camera.open();
mSurfaceView = CameraRecorder.mSurfaceView;
mSurfaceHolder = CameraRecorder.mSurfaceHolder;
super.onCreate();
if (mRecordingStatus == false)
startRecording();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
stopRecording();
mRecordingStatus = false;
super.onDestroy();
}
public boolean startRecording(){
try {
Toast.makeText(getBaseContext(), "Recording Started", Toast.LENGTH_SHORT).show();
//mServiceCamera = Camera.open();
Camera.Parameters params = mServiceCamera.getParameters();
mServiceCamera.setParameters(params);
Camera.Parameters p = mServiceCamera.getParameters();
final List<Size> listSize = p.getSupportedPreviewSizes();
Size mPreviewSize = listSize.get(2);
Log.v(TAG, "use: width = " + mPreviewSize.width
+ " height = " + mPreviewSize.height);
p.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
p.setPreviewFormat(PixelFormat.YCbCr_420_SP);
mServiceCamera.setParameters(p);
try {
mServiceCamera.setPreviewDisplay(mSurfaceHolder);
mServiceCamera.startPreview();
}
catch (IOException e) {
Log.e(TAG, e.getMessage());
e.printStackTrace();
}
mServiceCamera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(mServiceCamera);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
{
filefolder=new File(android.os.Environment.getExternalStorageDirectory(),"Backgroundcamera/videos");
}
else
{
filefolder=RecorderService.this.getCacheDir();
}
if(!filefolder.exists())
filefolder.mkdirs();
strphoto = System.currentTimeMillis()+".mp4";
mMediaRecorder.setOutputFile(filefolder+"/"+strphoto);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mPreviewSize.width, mPreviewSize.height);
mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
mMediaRecorder.prepare();
mMediaRecorder.start();
mRecordingStatus = true;
return true;
} catch (IllegalStateException e) {
Log.d(TAG, e.getMessage());
e.printStackTrace();
return false;
} catch (IOException e) {
Log.d(TAG, e.getMessage());
e.printStackTrace();
return false;
}
}
public void stopRecording() {
Toast.makeText(getBaseContext(), "Recording Stopped", Toast.LENGTH_SHORT).show();
try {
mServiceCamera.reconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mMediaRecorder.stop();
mMediaRecorder.reset();
mServiceCamera.stopPreview();
mMediaRecorder.release();
mServiceCamera.release();
mServiceCamera = null;
}
}
and
start the service on a click listerner.