I'm currently trying to create a very simple video recorder on Android without using intent, just a custom app. My code snippet is following
import java.io.IOException;
import android.app.Activity;
import android.media.MediaRecorder;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class CameraActivity extends Activity implements SurfaceHolder.Callback {
public enum State {
UNKNOWN, CONNECTED, NOT_CONNECTED
}
SurfaceView cameraView;
SurfaceHolder holder;
public boolean mListening;
public Object mState;
public NetworkInfo mNetworkInfo;
public boolean mSending;
boolean recording = false;
public static final String TAG = "VIDEOCAPTURE";
private MediaRecorder recorder;
protected void captureVideo() {
if (recording) {
recorder.stop();
// recorder.release();
recording = false;
Log.v(TAG, "Recording Stopped");
// Let's initRecorder so we can record again
initRecorder();
prepareRecorder();
} else {
recording = true;
recorder.start();
Log.v(TAG, "Recording Started");
}
}
private void initRecorder() {
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setOutputFile("/sdcard/videocapture_example.mp4");
recorder.setMaxDuration(50000); // 50 seconds
recorder.setMaxFileSize(5000000);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
recorder = new MediaRecorder();
initRecorder();
setContentView(R.layout.main);
cameraView = (SurfaceView) this.findViewById(R.id.CameraView);
holder = cameraView.getHolder();
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.addCallback(this);
}
private void prepareRecorder() {
recorder.setPreviewDisplay(holder.getSurface());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Log.v(TAG, "surfaceCreated");
prepareRecorder();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// camera.stopPreview();
// camera.release();
Log.v(TAG, "surfaceDestroyed");
if (recording) {
recorder.stop();
recording = false;
}
recorder.release();
finish();
}
}
But when i deployed this code within emulator, in the LogCat i got some errors like this.
java.lang.RuntimeException: Unable to start activity ComponentInfo...
java.lang.RuntimeException: setMaxDuration failed.
at android.media.MediaRecorder.setMaxDuration(Native Method)
What wrong with my code?
Quote from http://developer.android.com/reference/android/media/MediaRecorder.html:
"Note: Currently, MediaRecorder does not work on the emulator."
Related
I am trying to make a simple video recorder app in which I specify the maximum file size as a given number. The application as such works fine but I am not able to display a toast informing the user that the video clip has been saved, once the recording is complete. This is my code:
package com.example.videocapture2;
import java.io.IOException;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
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;
import android.widget.Toast;
public class MainActivity extends Activity implements SurfaceHolder.Callback,android.media.MediaRecorder.OnInfoListener{
MediaRecorder recorder;
SurfaceHolder holder;
Button Rec = null;
boolean recording = false;
int count =1;
#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);
recorder = new MediaRecorder();
initRecorder();
setContentView(R.layout.activity_main);
SurfaceView cameraView = (SurfaceView) findViewById(R.id.videoview);
holder = cameraView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
//recorder.start();
//cameraView.setClickable(true);
// cameraView.setOnClickListener(this);
Rec = (Button)findViewById(R.id.mybutton);
Rec.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (recording) {
recorder.stop();
recording = false;
// Let's initRecorder so we can record again
initRecorder();
prepareRecorder();
} else {
recording = true;
recorder.start();
}
}
});
}
private void initRecorder() {
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
CamcorderProfile cpHigh = CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH);
recorder.setProfile(cpHigh);
recorder.setOutputFile("/sdcard/videocapture_example"+count+".mp4");
recorder.setMaxDuration(50000); // 50 seconds
recorder.setMaxFileSize(2*1048576); // Approximately 2 megabytes
count++;
}
private void prepareRecorder() {
recorder.setPreviewDisplay(holder.getSurface());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
}
public void surfaceCreated(SurfaceHolder holder) {
prepareRecorder();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (recording) {
recorder.stop();
recording = false;
}
recorder.release();
//Toast.makeText(getApplicationContext(), "Video is saved", Toast.LENGTH_LONG).show();
//finish();
}
#Override
public void onInfo(MediaRecorder mr, int what, int extra) {
// TODO Auto-generated method stub
System.out.println("Reached onInfoListener");
if(what==android.media.MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED)
{
Toast.makeText(getApplicationContext(), "Video clip recorded", Toast.LENGTH_LONG).show();
}
}
}
I found out that due to the
recorder.setMaxFileSize(2*1048576); // Approximately 2 megabytes
in initRecorder() method, once the specified file size is reached, notification is sent to the OnInfoListener with a particular what code. So I overrode the method in my MainActivity, however, the toast doesn't display after the video file is completely recorded, though I am able to access the video clip and play it.
What should I do display this toast in the above mentioned conditions?
I think you haven't assigned the onInfoListener. i.e. you need to:
recorder.setOnInfoListener(this);
since your activity extends MediaRecorder.OnInfoListener
I am developing an application which will be able to record video from background of application by using Service.
Problem description :
In my application recording will be scheduled. If user want to record video from 1 PM to 3 PM, he will schedule the task and can exit from application. Application will automatically start recording at 1PM to 3PM.
What I did yet :
I googled about my query but didn't get solution. Many articles say that it is not possible. But in Google Play there are some applications (for eg MyCar Recorder) which can record video from background of application.
I got an article about same but its not working.
What is the way to implement this functionality?
1- I have created a activity to start service like this:
package com.android.camerarecorder;
import android.app.Activity;
import android.content.Intent;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
public class CameraRecorder extends Activity implements SurfaceHolder.Callback {
private static final String TAG = "Recorder";
public static SurfaceView mSurfaceView;
public static SurfaceHolder mSurfaceHolder;
public static Camera mCamera ;
public static boolean mPreviewRunning;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView1);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Button btnStart = (Button) findViewById(R.id.StartService);
btnStart.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Intent intent = new Intent(CameraRecorder.this, RecorderService.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startService(intent);
finish();
}
});
Button btnStop = (Button) findViewById(R.id.StopService);
btnStop.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
stopService(new Intent(CameraRecorder.this, RecorderService.class));
}
});
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
2 - Now I have created a service to record the video in background like this:
package com.android.camerarecorder;
import java.io.IOException;
import java.util.List;
import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.media.MediaRecorder;
import android.os.IBinder;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
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;
#Override
public void onCreate() {
mRecordingStatus = false;
//mServiceCamera = CameraRecorder.mCamera;
mServiceCamera = Camera.open(1);
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);
mMediaRecorder.setOutputFile("/sdcard/video.mp4");
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;
}
}
It will create a file video.mp4 in your sd card. you may change the code for adding more functionality but the basic functionality is achieved through this code i.e. record video in background.
NOTE: I have started the service through button click in activity but you can start it through any other way also like broadcastreceiver etc.
Yes, you can record the background video like this:
First, create a video app using service. Do not set its view so that it will not be visible.
If you are doing it in service then that is better because...
Second, you can use the AlarmManager for setting the alarm of particular time and then at that time, by using intent, start your service again. For stopping your app you can use AlarmManager, as well.
I am a student doing my task of Android APPs. And I got a problem I can't fix.Pls give me some advice, thx.
I want to have an activity of video recording, and I have done by using this code.
Video recording with media recorder
And here is my code, it work fine in other phone but it didnt work fine in moto-razr
here are two video taking by HTC desire and MOTO razr.
desire:http://youtu.be/suPF9Hk6iYk razr:http://youtu.be/wLvH7SXdcIs
Can any one help me to fix my problem?
package video.pac;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;
public class video extends Activity{
private MediaRecorder recorder;
private Preview mPreview;
boolean flag=false;
boolean startedRecording=false;
boolean stoppedRecording=false;
boolean key = false;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
recorder = new MediaRecorder();
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setVideoSize(640,480);
recorder.setVideoFrameRate(20);
recorder.setVideoEncodingBitRate(3000000);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
//recorder.setMaxDuration(5000);
mPreview = new Preview(video.this,recorder);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(mPreview);
}
private CountDownTimer mCountDownTimer = new CountDownTimer(9000, 1000) {
public void onTick(long millisUntilFinished) {}
public void onFinish() {
recorder = null;
System.out.println("stop");
video.this.finish();
}
};
class stopThread implements Runnable {
public void run() {
try {
mCountDownTimer.start();
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
class Preview extends SurfaceView implements SurfaceHolder.Callback{
//Create objects for MediaRecorder and SurfaceHolder.
SurfaceHolder mHolder;
MediaRecorder tempRecorder;
public Preview(Context context,MediaRecorder recorder) {
super(context);
tempRecorder=recorder;
mHolder=getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// TODO Auto-generated constructor stub
}
public Surface getSurface(){
return mHolder.getSurface();
}
public void surfaceCreated(SurfaceHolder holder){
tempRecorder.setOutputFile("/sdcard/test" + ".3gpp");
tempRecorder.setPreviewDisplay(mHolder.getSurface());
try{
tempRecorder.prepare();
recorder.start();
new Thread(new stopThread()).start();
System.out.println("start");
} catch (Exception e) {
tempRecorder.release();
tempRecorder = null;
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
if(tempRecorder!=null){
tempRecorder.stop();
tempRecorder.release();
tempRecorder = null;
System.out.println("release");
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {}
}
}
I think the issue is a security issue:
you need to set the recorder preview, otherwise some devices will see this as a security breach for capturing a video without displaying your capture/preview on screen. Try adding this to your recorder setup:
.
.
recorder.setPreviewDisplay(mHolder.getSurface());
.
.
When i try to record video from camera which seems with an error prepare failed: -1.
I search lot and I cant get any acceptable answers from anywhere. here is my code below.
I don't know it by parameter? and by unlocking camera. Any one who can it will be grateful.
package com.camara.activity;
import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class CamcorderView extends SurfaceView implements
SurfaceHolder.Callback {
MediaRecorder recorder;
SurfaceHolder holder;
String outputFile = "/sdcard/default.mp4";
public CamcorderView(Context context, AttributeSet attrs) {
super(context, attrs);
holder = getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
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(480, 320);
recorder.setVideoFrameRate(10);
recorder.setMaxDuration(10000);
}
public void surfaceCreated(SurfaceHolder holder) {
recorder.setOutputFile(outputFile);
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());
}
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
public void setOutputFile(String filename) {
outputFile = filename;
recorder.setOutputFile(filename);
}
public void startRecording() {
recorder.start();
}
public void stopRecording() {
recorder.stop();
recorder.release();
}
}
following is the output from the logcat
01-10 17:33:00.450: I/MediaRecorderJNI(14046): prepare: surface=0x243398 (id=1)
01-10 17:33:00.500: E/MediaRecorder(14046): prepare failed: -1
01-10 17:33:00.500: E/IOException(14046): java.io.IOException: prepare failed.
thanks in advance.
Ok I actually found my mistake. Because of course there was a mistake. Actually I wanted to have a preview and recording at the same time, and thought I had to use the object Camera for that. But Actually the MediaRecorder does that by itself using SetDisplayPreview and .... MediaRecord.Prepare :)
I'm in a good mood, so here's all the class ;)
import java.io.File;
import java.io.IOException;
import android.content.Context;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnInfoListener;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.FrameLayout;
public class ModuleVideo implements SurfaceHolder.Callback, OnInfoListener
{
public static final int STATE_NONE = -1;
public static final int STATE_STOPPED = 0;
public static final int STATE_PREVIEW = 1;
public static final int STATE_CAPTURE = 2;
public static final int STATE_RECORDING = 3;
private SurfaceHolder mHolder;
private MediaRecorder mRecorder;
private SurfaceView mCameraView;
private Context mContext;
private FrameLayout mParent;
private int mState;
private boolean mRecording;
public ModuleVideo(Context context, FrameLayout parent)
{
//Initiate the Surface Holder properly
mParent = parent;
mContext = context;
mRecorder = null;
mState = STATE_NONE;
mRecording = false;
}
private void Init()
{
mRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
CamcorderProfile camcorderProfile_HQ = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
mRecorder.setProfile(camcorderProfile_HQ);
mRecorder.setOutputFile("/sdcard/MY_VIDEO.mp4");
}
private void Prepare()
{
try
{
mRecorder.setPreviewDisplay(mHolder.getSurface());
mRecorder.prepare();
}
catch (IllegalStateException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void UI_StartPreview()
{
if(mState == STATE_STOPPED || mState == STATE_NONE)
{
mRecorder= new MediaRecorder();
Init();
mCameraView= new SurfaceView(mContext);
mParent.addView(mCameraView);
this.mHolder = mCameraView.getHolder();
this.mHolder.addCallback(this);
this.mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
}
public void UI_StopPreview()
{
if(mState == STATE_PREVIEW)
{
if(mRecording)
{
UI_StopRecord();
}
if(mRecorder != null)
{
mRecorder.release();
mRecorder= null;
}
mParent.removeView(mCameraView);
//mCameraView= null;
}
}
public boolean UI_StartRecord()
{
if(mState != STATE_PREVIEW )
{
return false;
}
String path= "/sdcard/PLUS_VIDEO.mp4";
String state = android.os.Environment.getExternalStorageState();
if(!state.equals(Environment.MEDIA_MOUNTED))
{
return false;
}
File directory = new File(path).getParentFile();
if(!directory.exists() && !directory.mkdirs())
{
return false;
}
mRecorder.start();
mRecording= true;
mState= STATE_RECORDING;
return true;
}
public void UI_StopRecord()
{
if(mRecorder != null)
{
mRecorder.stop();
mRecorder.reset();
Init();
Prepare();
mRecording= false;
mState= STATE_PREVIEW;
}
}
public boolean UI_IsRecording()
{
return mRecording;
}
#Override
public void onInfo(MediaRecorder mr, int what, int extra)
{
// TODO Auto-generated method stub
Log.i(null, "onInfo");
}
#Override
public void surfaceCreated(SurfaceHolder holder)
{
Prepare();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
mState= STATE_PREVIEW;
}
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
mState= STATE_STOPPED;
}
}
I'm learning how to program the video camera in android and wrote a very basic program (XML with SurfaceView and two buttons, one to start, one to stop video recording). Video Preview works fine, but after clicking the start_video button I'm getting an IllegalStateException in line 71 mediaRecorder.setVideoFrameRate(videoFramesPerSecond);:
IllegalStateException.<init>() line: 33
MediaRecorder.setVideoFrameRate(int) line: not available [native method]
CamtestActivity$2.onClick(View) line: 71
. I can't understand why this line is throwing this exception while the former line for example, does not.
Any hints? Thanks.
package com.grapp.camtest;
import java.io.IOException;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
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;
import android.widget.Toast;
public class CamtestActivity extends Activity implements SurfaceHolder.Callback{
private static final String TAG = "Camera-Tutorial";
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private Camera camera;
private boolean previewRunning;
private MediaRecorder mediaRecorder;
private final int maxDurationInMs = 20000;
private final int videoFramesPerSecond = 20;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
surfaceView = (SurfaceView) findViewById(R.id.surface_camera);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Button start_video = (Button) findViewById(R.id.start_video);
Button stop_video = (Button) findViewById(R.id.stop_video);
stop_video.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mediaRecorder.stop();
camera.lock();
}
});
start_video.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
camera.unlock();
mediaRecorder = new MediaRecorder();
mediaRecorder.setCamera(camera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
mediaRecorder.setMaxDuration(maxDurationInMs);
mediaRecorder.setVideoFrameRate(videoFramesPerSecond);
mediaRecorder.setVideoSize(surfaceView.getWidth(), surfaceView.getHeight());
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mediaRecorder.setOutputFile("/sdcard/video.mp4");
mediaRecorder.prepare();
mediaRecorder.start();
} catch (IllegalStateException e) {
Log.e(TAG,e.getMessage());
e.printStackTrace();
} catch (IOException e) {
Log.e(TAG,e.getMessage());
e.printStackTrace();
}
}
});
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
if (camera != null){
Camera.Parameters params = camera.getParameters();
camera.setParameters(params);
}
else {
Toast.makeText(getApplicationContext(), "Camera not available!", Toast.LENGTH_LONG).show();
finish();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (previewRunning){
camera.stopPreview();
}
Camera.Parameters p = camera.getParameters();
p.setPreviewSize(width, height);
camera.setParameters(p);
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
previewRunning = true;
}
catch (IOException e) {
Log.e(TAG,e.getMessage());
e.printStackTrace();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
previewRunning = false;
camera.release();
}
}
From the documentation for setVideoFrameRate():
Sets the frame rate of the video to be captured.
Must be called after setVideoSource().
Call this after setOutFormat() but before prepare().
It seems like you have not yet called setVideoSource() before you try to setVideoFrameRate(). Try setting the video source and see if that solves your problem.