I'm trying to reocord many videos of 30 seconds in background but, after 20 or 30 videos my service wich is stoping and launching the process to record go slowly.
I have try with a service in the same process and the problem was the same.
My video handler:
#Override
public void onCreate() {
super.onCreate();
isRunning = true;
idAlerta = Common.getStorage().getString(Constants.ID_ALERTA_SERVICE, "");
videoCount = 1;
mIntentRecorder = new Intent(VideoHandlerService.this, RecorderService.class);
mIntentSend = new Intent(VideoHandlerService.this, SendVideoService.class);
updateVideoTime();
mIntentRecorder.putExtra(Constants.VIDEO_TIME, videoTime);
mIntentRecorder.putExtra(Constants.ID_ALERTA_SERVICE, idAlerta);
mIntentRecorder.putExtra(Constants.COUNT_ALERTA, videoCount);
startService(mIntentRecorder);
newVideo();
}
public void newVideo() {
Common.log("new Video");
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
videoCount++;
startNewVideo();
if (videoCount == 2)
sendVideo(4000);
}
}, videoTime + 2000);
}
public void startNewVideo() {
final Intent intentRecorder = new Intent(VideoHandlerService.this, RecorderService.class);
intentRecorder.putExtra(Constants.VIDEO_TIME, videoTime);
Common.log("idAlerta " + idAlerta);
intentRecorder.putExtra(Constants.ID_ALERTA_SERVICE, idAlerta);
intentRecorder.putExtra(Constants.COUNT_ALERTA, videoCount);
stopService(intentRecorder);
if (Common.getStorage().getBoolean(Constants.RECORDER_ACTIVE, false)) {
if (Common.getStorage().getString(Constants.ID_ALERTA_SERVICE, "") != null && Common.getStorage().getString(Constants.ID_ALERTA_SERVICE, "").length() > 0) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Common.log("Start service recorder");
startService(intentRecorder);
newVideo();
}
}, 5000);
}
} else
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
startNewVideo();
}
}, 5000);
}
And this is the process to record:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Common.log("onStartCommand");
if (intent != null && ((Common.getStorage().getString(Constants.ID_ALERTA_SERVICE, "") != null && Common.getStorage().getString(Constants.ID_ALERTA_SERVICE, "").length() > 0))) {
windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
mLayoutParams = new WindowManager.LayoutParams(
1, 1,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT
);
mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
//Cojo Información del videohandler
Common.log("Intent distinto de null");
mVideoTime = intent.getIntExtra(Constants.VIDEO_TIME, 15000);
mIdAlerta = intent.getStringExtra(Constants.ID_ALERTA_SERVICE);
mVideoCount = intent.getIntExtra(Constants.COUNT_ALERTA, 1);
Common.log("Video time" + mVideoTime);
Common.getStorage().putBoolean(Constants.RECORDER_ACTIVE, true);
initRecording();
}
return START_NOT_STICKY;
}
public void initRecording() {
Common.log("INIT RECORDING IN");
surfaceView = new SurfaceView(this);
windowManager.addView(surfaceView, mLayoutParams);
surfaceView.getHolder().addCallback(this);
Common.log("INIT RECORDING OUT");
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
Common.log("onDestroy Video");
PreferenceHelper preferenceHelper = PreferenceHelper.newInstance(RecorderService.this, Constants.USER_PREFERENCES);
preferenceHelper.setBoolean(Constants.IS_RECORDING, false);
try {
camera.setPreviewCallback(null);
} catch (Exception e){
Common.log("error setPrevieCallback" + (e.getMessage() != null ? e.getMessage() : "sin mensaje"));
}
try {
muteSounds(false);
} catch (Exception e) {
Common.log(e.getMessage());
}
try {
Common.log("media recorder stop");
mediaRecorder.stop();
Common.log("media recorder reset");
mediaRecorder.reset();
Common.log("media recorder release");
mediaRecorder.release();
Common.log("media camera lock");
camera.lock();
Common.log("media camera release");
camera.release();
} catch (Exception e) {
}
Common.log("onDestroy Video");
Common.getStorage().putBoolean(Constants.RECORDER_ACTIVE, false);
RecorderService.super.onDestroy();
System.exit(0);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
mSurfaceHolder = holder;
Common.log("SurfaceCreated");
try {
try {
muteSounds(true);
} catch (Exception e) {
Common.log(e.getMessage());
}
Common.log("CAMERA OPEN 1");
try {
camera = Camera.open(1);
} catch (RuntimeException e) {
Common.log(e.getMessage());
}
Common.log("CAMERA OPEN 2");
///////////////////////////
mCamCoderProfile = CamcorderProfile.get(1, CamcorderProfile.QUALITY_LOW);
mCamCoderProfile.videoCodec = MediaRecorder.VideoEncoder.MPEG_4_SP;
mCamCoderProfile.audioCodec = MediaRecorder.AudioEncoder.AAC;
///////////////////////////
startRecorder();
} catch (Exception e) {
if (e.getMessage() != null)
Common.log(e.getMessage());
}
}
public void muteSounds(boolean mute) {
Common.log("MUTE SOUNDS IN");
AudioManager mgr = ((AudioManager) getSystemService(Context.AUDIO_SERVICE));
mgr.setStreamMute(AudioManager.STREAM_SYSTEM, true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (mute) {
mgr.adjustStreamVolume(AudioManager.STREAM_SYSTEM, AudioManager.ADJUST_MUTE, 0);
mgr.adjustVolume(AudioManager.ADJUST_MUTE, 0);
mgr.adjustVolume(AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE, 0);
} else {
mgr.adjustStreamVolume(AudioManager.STREAM_SYSTEM, AudioManager.ADJUST_UNMUTE, 0);
mgr.adjustVolume(AudioManager.ADJUST_UNMUTE, 0);
}
} else {
mgr.setStreamMute(AudioManager.STREAM_SYSTEM, mute);
mgr.setStreamMute(AudioManager.STREAM_MUSIC, mute);
if (mute) {
mOlderVolumen = mgr.getStreamVolume(AudioManager.STREAM_RING);
mgr.setStreamVolume(AudioManager.STREAM_RING, 0, 0);
} else
mgr.setStreamVolume(AudioManager.STREAM_RING, mOlderVolumen, 0);
mgr.adjustVolume(AudioManager.ADJUST_LOWER, 0);
}
Common.log("MUTE SOUNDS OUT");
}
public void startRecorder() {
mediaRecorder = new MediaRecorder();
camera.unlock();
mediaRecorder.setCamera(camera);
mediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(mCamCoderProfile);
videoFile = new File(Environment.getExternalStorageDirectory() + "/" +
"wbunker_" + mIdAlerta + "_" + mVideoCount + ".mp4");
Common.log("Video rercorder name file " + videoRecording);
mediaRecorder.setOutputFile(videoFile.getPath());
mediaRecorder.setOrientationHint(270);
try {
Common.log("mediaRecorder prepare");
mediaRecorder.prepare();
Common.log("mediaRecorder prepare");
} catch (Exception e) {
}
Common.log("mediaRecorder start");
mediaRecorder.start();
Common.log("mediaRecorder start");
Common.log("Estoy grabando macho");
}
When I try to stop the service the services stops, but the camera isn't released even killing the app. Can someone help me?? thanks in advance.
In the onDestroy() method of your service replace the camera.lock() with camera.unLock() and in the startRecorder() method replace the camera.unLock() with camera.lock()
Finally the key was use PowerManager, if you are going to use it, don't forget to release it!
private fun lock() {
log("lock")
var powerManager: PowerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
powerWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP, "WakeLock-Manager")
powerWakeLock.acquire()
var wifiManger: WifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
wifiWakeLock = wifiManger.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "WifiLock-Manger")
wifiWakeLock.acquire()
log("lock")
}
Related
In my Media Player app I use default media player and in my app song stops in between 10-13 min
and that's starts from 0 again when click on pause icon.
I have an issue with Media player always stopping randomly after some few mins. then I put secondary buffer progress I have check my audio is not buffering after some time that's why it is not play after that buffering min.
is there any solution to over come this issue? please help me for this as soon as possible.
if (mediaPlayer == null)
mediaPlayer = new MediaPlayer();
initMediaplyer();
if (mediaPlayer.isPlaying()) {
Log.e("Playinggggg", "stoppppp");
mediaPlayer.stop();
isMediaStart = false;
isPrepare = false;
isPause = false;
}
mediaPlayer = new MediaPlayer();
initMediaplyer();
mediaPlayer.setDataSource(url);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mediaPlayer.setAudioAttributes(
new AudioAttributes
.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build());
}
mediaPlayer.prepareAsync();
isPause = false;
isPrepare = true;
} catch (IllegalStateException | IOException e) {
FileDescriptor fileDescriptor1 = null;
setMediaPlayer("0", fileDescriptor1);
e.printStackTrace();
}
if (!mediaPlayer.isPlaying()) {
mediaPlayer.setOnPreparedListener(mp -> {
Log.e("Playinggggg", "Startinggg");
mediaPlayer.start();
isMediaStart = true;
isprogressbar = false;
setMediaPlaybackState(STATE_PLAYING);
mediaPlayer.setOnBufferingUpdateListener((mediaPlayer, i) -> {
binding.simpleSeekbar.setSecondaryProgress(i);
});
mediaPlayer.setOnCompletionListener(mediaPlayer -> {
if(mediaPlayer.isPlaying()){
callComplete();
}
});
mediaPlayer.setOnErrorListener((mediaPlayer, i, i1) -> {
switch (i) {
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
Log.d("MediaPlayer Error", "MEDIA ERROR NOT VALID FOR PROGRESSIVE PLAYBACK " + i1);
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.d("MediaPlayer Error", "MEDIA ERROR SERVER DIED " + i1);
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.d("MediaPlayer Error", "MEDIA ERROR UNKNOWN " + i1);
break;
default:
Log.d("MediaPlayer Error", "not conform " + i1);
break;
}
return false;
});
});
}
}
if (isPause) {
binding.llPlay.setVisibility(View.VISIBLE);
binding.llPause.setVisibility(View.GONE);
buildNotification(PlaybackStatus.PAUSED, ctx, mainPlayModelList, addToQueueModelList, playFrom, position);
} else {
binding.llPause.setVisibility(View.VISIBLE);
binding.llPlay.setVisibility(View.GONE);
buildNotification(PlaybackStatus.PLAYING, ctx, mainPlayModelList, addToQueueModelList, playFrom, position);
}
private void initMediaplyer() {
try {
if (mediaSessionManager != null) return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mediaSessionManager = (MediaSessionManager) ctx.getSystemService(Context.MEDIA_SESSION_SERVICE);
}
mediaSession = new MediaSessionCompat(ctx.getApplicationContext(), "AudioPlayer");
//Get MediaSessions transport controls
transportControls = mediaSession.getController().getTransportControls();
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mMediaControllerCompatCallback = new MediaControllerCompat.Callback() {
#Override
public void onPlaybackStateChanged(PlaybackStateCompat state) {
super.onPlaybackStateChanged(state);
if( state == null ) {
return;
}
switch( state.getState() ) {
case PlaybackStateCompat.STATE_PLAYING: {
mCurrentState = STATE_PLAYING;
break;
}
case PlaybackStateCompat.STATE_PAUSED: {
mCurrentState = STATE_PAUSED;
break;
}
}
}
};
mediaSession.setCallback(new MediaSessionCompat.Callback() {
// Implement callbacks
#Override
public void onPlay() {
super.onPlay();
callPlay();
}
#Override
public void onPause() {
super.onPause();
callPause();
}
#Override
public void onSkipToNext() {
super.onSkipToNext();
if (!url.equalsIgnoreCase("")) {
callNext();
}
}
#Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
if (!url.equalsIgnoreCase("")) {
callPrevious();
}
}
#Override
public void onStop() {
super.onStop();
}
});
} catch (Exception e) {
Log.e("playwell init media err",e.getMessage());
e.printStackTrace();
}
}
}
I need to implement video streaming via sockets in that I have to Record video on server side and Stream it live on client side, I have connected peers via socket successfully but video stream making trouble, I am facing following problems:
I have tested Media Recorder on API level 15 and 18 but not working on higher Android version, it's giving IllegalStateException start failed -38.
Media Player is not working, I have tried ParcelFileDescriptor to get the stream from socket and also tried to save the stream into a file to play on Media Player but I gained no outcome.
public class MainActivity2 extends Activity implements SurfaceHolder.Callback{
private Handler handler = new Handler();
private TextView text;
private EditText input, serverIP, port;
private Button send, connect;
private Socket socket;
private DataOutputStream outputStream;
private BufferedReader inputStream;
private String DeviceName = "Device", ipAddr;
Thread thread;
Integer portno;
private Handler handler2 = new Handler();
MediaPlayer mp;
private SurfaceView mPreview;
private SurfaceHolder holder;
VideoView mView;
SurfaceHolder mHolder;
// Video variable
MediaRecorder recorder, mMediaRecorder;
private Handler handler3 = new Handler();
boolean isRecording = false;
String AudioSavePathInDevice = null;
ParcelFileDescriptor pfd1;
Camera mCamera;
LocalServerSocket server;
LocalSocket sender;
private boolean searchNetwork() {
log("Connecting");
String ip = serverIP.getText().toString();
portno = Integer.parseInt(port.getText().toString());
try {
socket = new Socket();
socket.connect(new InetSocketAddress(ip, portno), 100);
outputStream = new DataOutputStream(socket.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
DeviceName += "1";
Log.i("Server", DeviceName);
log("Connected");
return true;
} catch (Exception e) {
}
return false;
}
private void runNewChatServer() {
ServerSocket serverSocket;
try {
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String myIP = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
serverSocket = new ServerSocket(portno);
log("I am ready to connect. Please enter the IP " + myIP + " in another device to connect...");
socket = serverSocket.accept();
DeviceName += "2";
log("another device Connected");
pfd1 = ParcelFileDescriptor.fromSocket(socket);
handler3.post(new Runnable() {
#Override
public void run() {
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
log("Stopped");
isRecording = false;
} else {
// initialize video camera
if (prepareVideoRecorder()) {
// Camera is available and unlocked, MediaRecorder is prepared,
// now you can start recording
try {
mMediaRecorder.start();
// inform the user that recording has started
log("Started");
isRecording = true;
} catch (IllegalStateException e) {
log("IllegalStateException in media start " + e.getStackTrace());
e.printStackTrace();
} catch (NullPointerException e) {
log("NullException in media start " + e.getMessage());
e.printStackTrace();
} catch (Exception e) {
log("Exception in media start " + e.getMessage());
e.printStackTrace();
}
} else {
// prepare didn't work, release the camera
releaseMediaRecorder();
// inform user
}
}
}
});
}
catch (Exception e) {
final String msg = e.getMessage();
log("Oops.Connection interrupted. Please reconnect your phones." + msg);
e.printStackTrace();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
text = (TextView) findViewById(R.id.textin);
input = (EditText) findViewById(R.id.textout);
send = (Button) findViewById(R.id.send);
connect = (Button) findViewById(R.id.connect);
serverIP = (EditText)findViewById(R.id.serverip);
port = (EditText)findViewById(R.id.port);
mPreview = (SurfaceView) findViewById(R.id.surfaceView1);
holder = mPreview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mp = new MediaPlayer();
mView = (VideoView) findViewById(R.id.videoView);
mHolder = mView.getHolder();
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
thread = new Thread(new Runnable() {
#Override
public void run() {
try {
if (!searchNetwork()) {
runNewChatServer();
}
else
{
prepareMediaPlayer();
}
outputStream = new DataOutputStream(
socket.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
while (true) {
String Message = inputStream.readLine();
if (Message != null) {
log(Message);
}
}
} catch (IOException e) {
log("Error: IO Exception");
e.printStackTrace();
}
catch (Exception e) {
log("Error: Exception");
e.printStackTrace();
}
}
});
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if (outputStream == null) {
return;
}
try {
String Message = input.getText().toString() + "\n";
outputStream.write(Message.getBytes());
log2(input.getText().toString());
} catch (IOException e) {
e.printStackTrace();
}
input.setText("");
}
});
connect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
ipAddr = serverIP.getText().toString();
thread.start();
}
});
}
private void log(final String message) {
handler.post(new Runnable() {
String DeviceName2 = "";
#Override
public void run() {
if (DeviceName.equals("Device1")) {
DeviceName2 = "Device2";
} else if (DeviceName.equals("Device2")) {
DeviceName2 = "Device1";
} else {
DeviceName2 = "UnknowDevice";
}
text.setText(text.getText() + "\n" + DeviceName2 + " :"
+ message);
}
});
}
private void log2(final String message) {
handler.post(new Runnable() {
#Override
public void run() {
text.setText(text.getText() + "\n" + "you" + " :"
+ message);
}
});
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.exit(0);
return true;
}
return super.onKeyDown(keyCode, event);
}
private boolean prepareVideoRecorder(){
mMediaRecorder = new MediaRecorder();
mCamera = getCameraInstance();
// 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_LOW));
mMediaRecorder.setOutputFile(pfd1.getFileDescriptor());
// Step 5: Set the preview output
mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
// Step 6: Prepare configured MediaRecorder
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
log("IllegalStateException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
} catch (IOException e) {
log("IOException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
return true;
}
private boolean prepareMediaPlayer() {
try {
ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
pfd.getFileDescriptor().sync();
mp.setDataSource(pfd.getFileDescriptor());
pfd.close();
mp.setDisplay(mHolder);
mp.prepareAsync();
mp.start();
return true;
}catch(Exception ex){
ex.printStackTrace();
return false;
}
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
Log.d("CameraInstance", e.getMessage());
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
#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 (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;
}
}
public void surfaceCreated(SurfaceHolder holder) {
/* try {
prepareVideoRecorder();
} catch (IllegalStateException e) {
e.printStackTrace();
log("IllegalStateException preparing MediaRecorder2: " + e.getMessage());
finish();
}*/
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (isRecording) {
mMediaRecorder.stop();
isRecording = false;
}
releaseMediaRecorder();
releaseCamera();
finish();
}
}
I have also used these following code snippet to save the input stream into a file to play on Media Player but it didn't work for me.
File downloadingMediaFile = File.createTempFile("downloading", ".mp4");
FileOutputStream out = new FileOutputStream(downloadingMediaFile);
IOUtils.copy(socket.getInputStream(), out);
mp.setDataSource(out.getFD());
I have tried this code snippet to Record the video stream on Lollipop or Higher API version but it's too didn't work.
ParcelFileDescriptor[] parcelFileDescriptors = new ParcelFileDescriptor[0];
try {
parcelFileDescriptors = ParcelFileDescriptor.createPipe();
} catch (IOException e) {
e.printStackTrace();
}
ParcelFileDescriptor parcelRead = new
ParcelFileDescriptor(parcelFileDescriptors[0]);
ParcelFileDescriptor parcelWrite = new
ParcelFileDescriptor(parcelFileDescriptors[1]);
mMediarecorder.setOutputFile(parcelWrite.fromSocket(socket).getFileDescriptor());
I am new in android development. When i am recording a call in my service class the recorder.start() is getting IllegalStateException.Here is my Logcat:
java.lang.IllegalStateException.android.media.MediaRecorder.stop(Native Method)
my serivce class is:--
public class RecordService extends Service {
private MediaRecorder recorder = null;
private String phoneNumber = null;
private String fileName;
private boolean onCall = false;
private boolean recording = false;
private boolean silentMode = false;
private boolean onForeground = false;
private int currentFormat = 0;
private String AUDIO_RECORDER_FOLDER = "Testing_recording";
String file_exts[] = { AUDIO_RECORDER_FILE_EXT_MP3,
AUDIO_RECORDER_FILE_EXT_MP4, AUDIO_RECORDER_FILE_EXT_3GP };
static final String AUDIO_RECORDER_FILE_EXT_MP3 = ".mp3";
static final String AUDIO_RECORDER_FILE_EXT_3GP = ".3gp";
static final String AUDIO_RECORDER_FILE_EXT_MP4 = ".mp4";
private int output_formats[] = { MediaRecorder.OutputFormat.MPEG_4,
MediaRecorder.OutputFormat.THREE_GPP };
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(Constants.TAG, "RecordService onStartCommand");
if (intent != null) {
int commandType = intent.getIntExtra("commandType", 0);
if (commandType != 0) {
if (commandType == Constants.RECORDING_ENABLED) {
Log.d(Constants.TAG, "RecordService RECORDING_ENABLED");
silentMode = intent.getBooleanExtra("silentMode", true);
if (!silentMode && phoneNumber != null && onCall
&& !recording)
commandType = Constants.STATE_START_RECORDING;
} else if (commandType == Constants.RECORDING_DISABLED) {
Log.d(Constants.TAG, "RecordService RECORDING_DISABLED");
silentMode = intent.getBooleanExtra("silentMode", true);
if (onCall && phoneNumber != null && recording)
commandType = Constants.STATE_STOP_RECORDING;
}
if (commandType == Constants.STATE_INCOMING_NUMBER) {
Log.d(Constants.TAG, "RecordService STATE_INCOMING_NUMBER");
startService();
if (phoneNumber == null)
phoneNumber = intent.getStringExtra("phoneNumber");
silentMode = intent.getBooleanExtra("silentMode", true);
} else if (commandType == Constants.STATE_CALL_START) {
Log.d(Constants.TAG, "RecordService STATE_CALL_START");
onCall = true;
if (phoneNumber != null && onCall
&& !recording) {
startService();
startRecording(intent);
}
} else if (commandType == Constants.STATE_CALL_END) {
Log.d(Constants.TAG, "RecordService STATE_CALL_END");
onCall = false;
phoneNumber = null;
stopAndReleaseRecorder();
recording = false;
stopService();
} else if (commandType == Constants.STATE_START_RECORDING) {
Log.d(Constants.TAG, "RecordService STATE_START_RECORDING");
if ( phoneNumber != null && onCall) {
startService();
startRecording(intent);
}
} else if (commandType == Constants.STATE_STOP_RECORDING) {
Log.d(Constants.TAG, "RecordService STATE_STOP_RECORDING");
stopAndReleaseRecorder();
recording = false;
}
}
}
return super.onStartCommand(intent, flags, startId);
}
/**
* in case it is impossible to record
*/
private void terminateAndEraseFile() {
Log.d(Constants.TAG, "RecordService terminateAndEraseFile");
stopAndReleaseRecorder();
recording = false;
// deleteFile();
}
private void stopService() {
Log.d(Constants.TAG, "RecordService stopService");
stopForeground(true);
onForeground = false;
this.stopSelf();
}
private void deletseFile() {
Log.d(Constants.TAG, "RecordService deleteFile");
FileHelper.deleteFile(fileName);
fileName = null;
}
private void stopAndReleaseRecorder() {
if (recorder == null)
return;
Log.d(Constants.TAG, "RecordService stopAndReleaseRecorder");
boolean recorderStopped = false;
boolean exception = false;
try {
recorder.stop();
recorderStopped = true;
} catch (IllegalStateException e) {
Log.e(Constants.TAG, "IllegalStateException");
e.printStackTrace();
exception = true;
} catch (RuntimeException e) {
Log.e(Constants.TAG, "RuntimeException");
exception = true;
} catch (Exception e) {
Log.e(Constants.TAG, "Exception");
e.printStackTrace();
exception = true;
}
try {
recorder.reset();
} catch (Exception e) {
Log.e(Constants.TAG, "Exception");
e.printStackTrace();
exception = true;
}
try {
recorder.release();
} catch (Exception e) {
Log.e(Constants.TAG, "Exception");
e.printStackTrace();
exception = true;
}
recorder = null;
if (exception) {
// deleteFile();
}
if (recorderStopped) {
Toast toast = Toast.makeText(this,
this.getString(R.string.receiver_end_call),
Toast.LENGTH_SHORT);
toast.show();
}
}
#Override
public void onDestroy() {
Log.d(Constants.TAG, "RecordService onDestroy");
stopAndReleaseRecorder();
stopService();
super.onDestroy();
}
private void startRecording(Intent intent) {
Log.d(Constants.TAG, "RecordService startRecording");
boolean exception = false;
recorder = new MediaRecorder();
try {
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_UPLINK);
// recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFormat(output_formats[currentFormat]);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
// fileName = FileHelper.getFilename(phoneNumber);
recorder.setOutputFile(getFilename());
recorder.setOnErrorListener(errorListener);
recorder.setOnInfoListener(infoListener);
OnErrorListener errorListener = new OnErrorListener() {
public void onError(MediaRecorder arg0, int arg1, int arg2) {
Log.e(Constants.TAG, "OnErrorListener " + arg1 + "," + arg2);
terminateAndEraseFile();
}
};
recorder.setOnErrorListener(errorListener);
OnInfoListener infoListener = new OnInfoListener() {
public void onInfo(MediaRecorder arg0, int arg1, int arg2) {
Log.e(Constants.TAG, "OnInfoListener " + arg1 + "," + arg2);
terminateAndEraseFile();
}
};
recorder.setOnInfoListener(infoListener);
recorder.prepare();
// Sometimes prepare takes some time to complete
Thread.sleep(2000);
try {
recorder.start();
} catch (Throwable t) {
t.printStackTrace();
Log.w("sf", t);
}
// recorder.start();
/*new Handler().postDelayed(new Runnable() {
public void run() {
// recorder.stop();
if (null != recorder) {
recorder.stop();
recorder.reset();
recorder.release();
System.out.println("hello helloo");
recorder = null;
}
Log.e("Ho rha hai", "goodndnd");
}
}, 40000);*/
recording = true;
Log.d(Constants.TAG, "RecordService recorderStarted");
Toast.makeText(getApplicationContext(), "recording is strated ", 2000).show();
} catch (IllegalStateException e) {
Log.e(Constants.TAG, "IllegalStateException");
e.printStackTrace();
exception = true;
} catch (IOException e) {
Log.e(Constants.TAG, "IOException");
e.printStackTrace();
exception = true;
} catch (Exception e) {
Log.e(Constants.TAG, "Exception");
e.printStackTrace();
exception = true;
}
if (exception) {
terminateAndEraseFile();
}
if (recording) {
Toast toast = Toast.makeText(this,
this.getString(R.string.receiver_start_call),
Toast.LENGTH_SHORT);
toast.show();
} else {
Toast toast = Toast.makeText(this,
this.getString(R.string.record_impossible),
Toast.LENGTH_LONG);
toast.show();
}
}
private MediaRecorder.OnErrorListener errorListener = new MediaRecorder.OnErrorListener() {
public void onError(MediaRecorder mr, int what, int extra) {
}
};
private MediaRecorder.OnInfoListener infoListener = new MediaRecorder.OnInfoListener() {
public void onInfo(MediaRecorder mr, int what, int extra) {
}
};
private void startService() {
if (!onForeground) {
Log.d(Constants.TAG, "RecordService startService");
Intent intent = new Intent(this, MainActivity.class);
// intent.setAction(Intent.ACTION_VIEW);
// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
PendingIntent pendingIntent = PendingIntent.getActivity(
getBaseContext(), 0, intent, 0);
Notification notification = new NotificationCompat.Builder(
getBaseContext())
.setContentTitle(
this.getString(R.string.notification_title))
.setTicker(this.getString(R.string.notification_ticker))
.setContentText(this.getString(R.string.notification_text))
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pendingIntent).setOngoing(true)
.getNotification();
notification.flags = Notification.FLAG_NO_CLEAR;
startForeground(1337, notification);
onForeground = true;
}
}
private String getFilename() {
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath, AUDIO_RECORDER_FOLDER);
if (!file.exists()) {
file.mkdirs();
}
SimpleDateFormat formatter = new SimpleDateFormat("dd_MMM_yy_HH_mm_ss");
String dateString = formatter.format(new Date(System
.currentTimeMillis()));
return (file.getAbsolutePath() + "/" + "Rec_" + dateString + file_exts[currentFormat]);
}
}
and broadcast receiver is this:--
public class MyPhoneReceiver extends BroadcastReceiver {
private String phoneNumber;
#Override
public void onReceive(Context context, Intent intent) {
phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
String extraState = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
Log.d(Constants.TAG, "MyPhoneReciever phoneNumber "+phoneNumber);
if (MainActivity.updateExternalStorageState() == Constants.MEDIA_MOUNTED) {
try {
SharedPreferences settings = context.getSharedPreferences(
Constants.LISTEN_ENABLED, 0);
boolean silent = settings.getBoolean("silentMode", true);
if (extraState != null) {
if (extraState.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
Intent myIntent = new Intent(context,
RecordService.class);
myIntent.putExtra("commandType",
Constants.STATE_CALL_START);
context.startService(myIntent);
} else if (extraState
.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
Intent myIntent = new Intent(context,
RecordService.class);
myIntent.putExtra("commandType",
Constants.STATE_CALL_END);
context.startService(myIntent);
} else if (extraState
.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
if (phoneNumber == null)
phoneNumber = intent
.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
Intent myIntent = new Intent(context,
RecordService.class);
myIntent.putExtra("commandType",
Constants.STATE_INCOMING_NUMBER);
myIntent.putExtra("phoneNumber", phoneNumber);
myIntent.putExtra("silentMode", silent);
context.startService(myIntent);
}
} else if (phoneNumber != null) {
Intent myIntent = new Intent(context, RecordService.class);
myIntent.putExtra("commandType",
Constants.STATE_INCOMING_NUMBER);
myIntent.putExtra("phoneNumber", phoneNumber);
myIntent.putExtra("silentMode", silent);
context.startService(myIntent);
}
} catch (Exception e) {
Log.e(Constants.TAG, "Exception");
e.printStackTrace();
}
}
}
}
I want to make an app that record video, it seems like vine, hold to record, release it stop, hold to record and keep that to the end.
I have used MediaRecorder, but it just record once a time, if I start record again, app is crashed.
Please tell me there is any way to do this?
I edited my code:
public class VideoRecordingActivity extends AppCompatActivity implements View.OnTouchListener, View.OnLongClickListener {
private Context myContext;
private boolean hasCamera;
private boolean onRecording;
private Camera mCamera;
private CameraPreview mPreview;
private MediaRecorder mediaRecorder;
private boolean cameraFront = false;
private int cameraId;
private int videoNumer;
private boolean isActionDown = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_introduction_recording);
initUI();
initialize();
}
private LinearLayout lnCameraPreview;
private ImageButton btn_recording;
private void initUI() {
lnCameraPreview = (LinearLayout) findViewById(R.id.ln_body_recording);
btn_recording = (ImageButton) findViewById(R.id.btn_recording);
}
public void initialize() {
myContext = this;
mPreview = new CameraPreview(this, cameraId, mCamera);
lnCameraPreview.addView(mPreview);
btn_recording.setOnLongClickListener(this);
btn_recording.setOnTouchListener(this);
videoNumer = 0;
}
public boolean onLongClick(View v) {
isActionDown = true;
try {
boolean isPrepared = false;
if (isActionDown)
isPrepared = prepareMediaRecorder();
if (isPrepared && isActionDown) {
// work on UiThread for better performance
runOnUiThread(new Runnable() {
public void run() {
mediaRecorder.start();
onRecording = true;
}
});
}
} catch (Exception e) {
e.printStackTrace();
Log.e("onLongPress Error ", e.toString());
}
return true;
}
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
isActionDown = false;
try {
if (onRecording) {
if (mediaRecorder != null) {
mediaRecorder.stop();
}
onRecording = false;
videoNumer++;
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
break;
}
return false;
}
public void onResume() {
super.onResume();
if (!hasCamera(myContext)) {
Toast.makeText(myContext, "Sorry, your phone does not have a camera!", Toast.LENGTH_LONG).show();
return;
}
initCamera();
}
#Override
protected void onPause() {
super.onPause();
// when on Pause, release camera in order to be used from other
// applications
releaseCamera();
}
private final int cMaxRecordDurationInMs = 30000;
private final long cMaxFileSizeInBytes = 5000000;
private final int cFrameRate = 20;
private File prRecordedFile;
#SuppressLint("SdCardPath")
private boolean prepareMediaRecorder() {
mediaRecorder = new MediaRecorder();
try {
mCamera.unlock();
} catch (Exception ex) {
return false;
}
// adjust the camera the way you need
mediaRecorder.setCamera(mCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
//
CamcorderProfile cpHigh = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
mediaRecorder.setProfile(cpHigh);
mediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
mediaRecorder.setOutputFile("/sdcard/" + videoNumer + "videocapture_example.mp4");
//set max size
mediaRecorder.setMaxDuration(600000); // Set max duration 60 sec.
mediaRecorder.setMaxFileSize(50000000); // Set max file size 50M
try {
mediaRecorder.prepare();
} catch (Exception e) {
releaseMediaRecorder();
e.printStackTrace();
}
return true;
}
private void releaseMediaRecorder() {
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
if (mCamera != null) {
mCamera.lock(); // lock camera for later use
}
}
}
/**
* Camera
*/
private void initCamera() {
if (mCamera == null) {
// if the front facing camera does not exist
if (findFrontFacingCamera() < 0) {
Toast.makeText(this, "No front facing camera found.", Toast.LENGTH_LONG).show();
}
mCamera = Camera.open(findBackFacingCamera());
mPreview.refreshCamera(mCamera);
}
onRecording = false;
}
private boolean hasCamera(Context context) {
// check if the device has camera
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
hasCamera = true;
} else {
hasCamera = false;
}
return hasCamera;
}
private int findFrontFacingCamera() {
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
cameraId = i;
cameraFront = true;
break;
}
}
this.cameraId = cameraId;
return cameraId;
}
private int findBackFacingCamera() {
int cameraId = -1;
// Search for the back facing camera
// get the number of cameras
int numberOfCameras = Camera.getNumberOfCameras();
// for every camera check
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
cameraId = i;
cameraFront = false;
break;
}
}
this.cameraId = cameraId;
return cameraId;
}
public void switchCamera() {
// if the camera preview is the front
if (cameraFront) {
int cameraId = findBackFacingCamera();
if (cameraId >= 0) {
// open the backFacingCamera
mCamera = Camera.open(cameraId);
// refresh the preview
mPreview.refreshCamera(mCamera);
}
} else {
int cameraId = findFrontFacingCamera();
if (cameraId >= 0) {
// open the backFacingCamera
mCamera = Camera.open(cameraId);
// refresh the preview
mPreview.refreshCamera(mCamera);
}
}
}
private void releaseCamera() {
// stop and release camera
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
}
You can do achieve this functionality by setting OnLongClickListener() and OnTouchListener() on your record button. Like this:
recordBtn.setOnLongClickListener(recordBtnLCListener);
recordBtn.setOnTouchListener(recordBtnTouchListener);
then :
#Override
public boolean onLongClick(View v) {
ivCancel.setVisibility(View.GONE);
ivDone.setVisibility(View.GONE);
isActionDown = true;
try {
if (isActionDown) {
initRecorder();
if (isActionDown)
prepareRecorder();
}
if (isPrepared && isActionDown) {
mMediaRecorder.start();
isRecording = true;
}
} catch (Exception e) {
e.printStackTrace();
Log.e("onLongPress Error ", e.toString());
}
return true;
}
and :
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
isActionDown = false;
try {
if (isRecording) {
if (mMediaRecorder != null) {
mMediaRecorder.stop();
}
isRecording = false;
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
break;
}
return false;
}
So, in this way you can record the parts of video.Means each time you LongPress your record button, the recording starts. And time you release the button, the recording stops and here you have to save this part of video in any temporary folder.
Once you done taking all parts of videos as many as you want, then you have to combine all that parts of videos to make a single video.
Here, is the code to merge all that video parts saved in temperory folder:
public void mergeVideos() {
try {
List<Movie> inMovies = new ArrayList<>();
for (int i = 0; i < videosPathList.size(); i++) {
String filePath = videosPathList.get(i);
try {
Movie movie = MovieCreator.build(filePath);
if (movie != null)
inMovies.add(movie);
} catch (Exception e) {
e.printStackTrace();
}
}
List<Track> videoTracks = new LinkedList<Track>();
List<Track> audioTracks = new LinkedList<Track>();
for (Movie m : inMovies) {
for (Track t : m.getTracks()) {
try {
if (t.getHandler().equals("soun")) {
audioTracks.add(t);
}
if (t.getHandler().equals("vide")) {
videoTracks.add(t);
}
} catch (Exception e) {
}
}
}
Movie result = new Movie();
if (audioTracks.size() > 0) {
result.addTrack(new AppendTrack(audioTracks
.toArray(new Track[audioTracks.size()])));
}
if (videoTracks.size() > 0) {
result.addTrack(new AppendTrack(videoTracks
.toArray(new Track[videoTracks.size()])));
}
BasicContainer out = (BasicContainer) new DefaultMp4Builder().build(result);
File f = null;
String finalVideoPath;
try {
f = setUpVideoFile(Environment
.getExternalStorageDirectory()+"/MyApp/videos/");
finalVideoPath = f.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
f = null;
finalVideoPath = null;
}
WritableByteChannel fc = new RandomAccessFile(finalVideoPath, "rw").getChannel();
out.writeContainer(fc);
fc.close();
deleteFilesDir(); //In this method you have to delete all parts of video stored in temporary folder.
} catch (Exception e) {
e.printStackTrace();
progressDialog.dismiss();
finish();
}
}
File setUpVideoFile(String directory) throws IOException {
File videoFile = null;
if (Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState())) {
File storageDir = new File(directory);
if (storageDir != null) {
if (!storageDir.mkdirs()) {
if (!storageDir.exists()) {
Log.d("CameraSample", "failed to create directory");
return null;
}
}
}
videoFile = File.createTempFile("video_"
+ System.currentTimeMillis() + "_",
.mp4, storageDir);
}
return videoFile;
}
You can call mergeVideos() method after stopping mediaRecorder.
Hope this code helps you. :)
For merging the videos you have to use the isoparser library. So you have to add following dependendy in your gradle file :
compile 'com.googlecode.mp4parser:isoparser:1.0.5.4'
This is my code.
public class VideoRecordingActivity extends AppCompatActivity implements View.OnClickListener, SurfaceHolder.Callback {
MediaRecorder recorder;
SurfaceHolder holder;
boolean recording = false;
private boolean isPrepared = false;
int videoNumber = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
super.onCreate(savedInstanceState);
recorder = new MediaRecorder();
initRecorder();
setContentView(R.layout.activity_video_introduction_recording);
SurfaceView cameraView = (SurfaceView) findViewById(R.id.ln_body_recording);
holder = cameraView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cameraView.setClickable(true);
cameraView.setOnClickListener(this);
}
private void initRecorder() {
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "CameraSample");
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
CamcorderProfile cpHigh = CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH);
recorder.setProfile(cpHigh);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
//CGlobal.VIDEO_RECORD_PATH = CGlobal.VIDEO_HOME_PATH + "VID_" + timeStamp;
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
recorder.setOutputFile(mediaFile+".mp4");
recorder.setMaxDuration(50000); // 50 seconds
recorder.setMaxFileSize(5000000); // Approximately 5 megabytes
}
private void prepareRecorder() {
recorder.setPreviewDisplay(holder.getSurface());
try {
recorder.prepare();
isPrepared = true;
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
}
public void onClick(View v) {
if (recording) {
recorder.stop();
recording = false;
isPrepared = false;
videoNumber++;
// Let's initRecorder so we can record again
} else {
if (!isPrepared){
initRecorder();
prepareRecorder();
}
recording = true;
recorder.start();
}
}
public void surfaceCreated(SurfaceHolder holder) {
prepareRecorder();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (recording) {
recorder.stop();
recording = false;
}
recorder.release();
finish();
}
}
I am working on camera app. I wrote code which can record and save video in sdcard. I used CountDownTimer to record video. Program is working perfect but when I click on device's home button(i.e onPause method is called) program crashed.i have illegalstateexception. This is my source:
public class CameraPreview extends Activity implements SurfaceHolder.Callback {
private Button upload_btn, start_record, reset;
private Camera prCamera;
private SurfaceHolder prSurfaceHolder;
private SurfaceView prSurfaceView;
private int cMaxRecordDurationInMs = 8000;
private TextView video_start_timer;
private MediaRecorder prMediaRecorder;
final String mVideoFilename = Environment.getExternalStorageDirectory()
+ "/video.mp4";
String strFile = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.camera_preview);
start_record = (Button) findViewById(R.id.play_video);
upload_btn = (Button) findViewById(R.id.upload_btn);
reset = (Button) findViewById(R.id.reset_btn);
reset.setEnabled(false);
prSurfaceView = (SurfaceView) findViewById(R.id.surfaceView1);
video_start_timer = (TextView) findViewById(R.id.timeElapsed);
prSurfaceHolder = prSurfaceView.getHolder();
prSurfaceHolder.addCallback(this);
prSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
prMediaRecorder = new MediaRecorder();
start_record.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
StartRecordVideo();
}
});
}
#Override
protected void onPause() {
super.onPause();
if (prCamera != null) {
prCamera.stopPreview();
prCamera.release();
prCamera = null;
}
}
#Override
public void surfaceChanged(SurfaceHolder _holder, int _format, int _width,
int _height) {
try {
if (prCamera == null)
return;
prCamera.setPreviewDisplay(_holder);
prCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
CameraInfo cameraInfo = new CameraInfo();
int cameraCount = Camera.getNumberOfCameras();
if (cameraCount > 1)
for (int camIdx = 0; camIdx < Camera.getNumberOfCameras(); camIdx++) {
Camera.getCameraInfo(camIdx, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
try {
prCamera = Camera.open(camIdx);
} catch (RuntimeException e) {
Log.i("Camera failed to open: ",
e.getLocalizedMessage());
}
}
}
else
prCamera = Camera.open();
if (prCamera == null) {
Toast.makeText(this, "Camera is not available!", Toast.LENGTH_SHORT)
.show();
finish();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
stopRecording();
}
protected void startRecording() throws IOException {
prMediaRecorder = new MediaRecorder(); // Works well
prCamera.unlock();
prMediaRecorder.setCamera(prCamera);
prMediaRecorder.setPreviewDisplay(prSurfaceHolder.getSurface());
prMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
prMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
prMediaRecorder.setProfile(CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH));
prMediaRecorder.setPreviewDisplay(prSurfaceHolder.getSurface());
prMediaRecorder.setOutputFile(mVideoFilename);
prMediaRecorder.prepare();
prMediaRecorder.start();
}
private void stopRecording() {
if (prMediaRecorder != null) {
prMediaRecorder.stop();
prMediaRecorder.reset();
prMediaRecorder.release();
video_start_timer.setText("--:--");
}
}
private CountDownTimer timer = new CountDownTimer(cMaxRecordDurationInMs,
1000) {
#Override
public void onTick(long millisUntilFinished) {
video_start_timer.setText(countTime(millisUntilFinished));
start_record.setEnabled(false);
}
#Override
public void onFinish() {
stopRecording();
timer.cancel();
start_record.setEnabled(true);
reset.setEnabled(true);
}
};
private String countTime(long miliseconds) {
String timeInMinutes = new String();
long minutes = miliseconds / 60000;
long seconds = (miliseconds % 60000) / 1000;
timeInMinutes = minutes + ":"
+ (seconds < 10 ? "0" + seconds : seconds);
return timeInMinutes;
}
public void StartRecordVideo() {
start_record.setEnabled(false);
reset.setEnabled(false);
try {
timer.start();
startRecording();
} catch (IOException e) {
e.printStackTrace();
}
}
}
If anyone knows solution help me.
Thanks
This is because You call prMediaRecorder.reset() before prMediaRecorder.release() in your stopRecording()-method. If You press the home button onSurfaceDestroyed will be called, so You stop the prMediaRecorder. If You call reset(), the MediaRecorder is in it´s idle state and have to be configured again, so I think the release() call will cause the error.