MediaRecorder stop failed: -1007 - android

I am using a SurfaceView which shows the stream of the drone on my smartphone and what I want is to record the stream of the drone, but it's not that easy. So I think I could use MediaRecorder for this. For this problem I have read many posts, but they didn't help me out.
In the OnCreate I am creating the SurfaceView:
mPreview = FindViewById<SurfaceView>(Resource.Id.surfaceView1);
holder = mPreview.Holder;
holder.AddCallback(this);
holder.SetFormat(Format.Rgba8888);
In the SurfaceCreated override I added the SetPreviewDisplay:
mRecorder = new Android.Media.MediaRecorder();
mRecorder.SetPreviewDisplay(mPreview.Holder.Surface);
So, when I click on the record button I start the following method in a new thread, otherwise the SurfaceView will be stuck:
private void StartRecord()
{
var sdCardPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
string path = System.IO.Path.Combine(sdCardPath, "test.mp4");
file = new File(path);
mRecorder.SetVideoSource(Android.Media.VideoSource.Surface);
mRecorder.SetOutputFormat(Android.Media.OutputFormat.Mpeg4);
mRecorder.SetVideoEncoder(Android.Media.VideoEncoder.H264);
mRecorder.SetVideoEncodingBitRate(512 * 1000);
mRecorder.SetVideoFrameRate(30);
mRecorder.SetOutputFile(file.AbsolutePath);
mRecorder.SetVideoSize(mPreview.Width, mPreview.Height);
mRecorder.Prepare();
mRecorder.Start();
}
There are no errors until the mRecorder.Stop() will be called:
private void StopRecord()
{
if(mRecorder != null)
{
try
{
mRecorder.Stop();
}
catch (Java.Lang.RuntimeException e)
{
// Here he always comes
file.Delete();
System.Console.WriteLine(e);
}
finally
{
mRecorder.Release();
mRecorder = null;
}
}
}
When I check into the mRecorder variable, it's saying at the surface object: failed to get surface. That's strange because when I check the mRecorder variable after the mRecorder started, it just has a surface object.
What am I doing wrong?

Related

android - Which MediaRecorder configuration is supported by all device?

I am recording communication voice in my app and I added storage and audio record permission manifest and also getting programmatically.
My code is working fine on one device(Android 6.0 Lenovo K3 Note)
But not on another (Android 8.1 ONEPLUS A5010)
In second device output is saved as a blank file of 3.15KB
I am adding my code which I am using please tell what I am doing wrong.
MediaRecorder mRecorder;
String mFileName;
Code in OnCreate
File file = new File(getFilesDir(), "engwingoLastCall.3gp");
mFileName = file.getAbsolutePath();
try {
if(mRecorder == null) {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(mFileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
}
} catch (Exception e) {
Log.d(TAG,"Recorder Error:"+e.getMessage());
}
Methods
public void startRecording() {
try {
if(mRecorder != null) {
mRecorder.prepare();
mRecorder.start();
}
} catch (Exception e) {
Log.d("Recorder", "prepare() failed");
}
}
public void stopRecording() {
if(mRecorder != null) {
try {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
} catch (IllegalStateException e) {
e.printStackTrace();
}catch (Exception e){
Log.d(TAG,e.getMessage());
}
}
}
Since you are not setting a profile with setProfile() method you may need to set audio channels, bitrate and sampling rate for audio too. Here is an example:
mRecorder.setAudioChannels(1);
// you would not want to record stereo, it is not logical
mRecorder.setAudioEncodingBitRate(128000);
// you can set it to 64000 or 96000 to lower quality, therefore decreasing the size of the audio
mRecorder.setAudioSamplingRate(44100);
// AFAIK, default value.
Hope this helps.
My Code was OK but the reason for this behavior of my recorder was,
Some other service also using my recorder at that time and that's why the file was saved empty (3.15KB Size)

Android: recording audio using MediaRecorder - file doesnt play

i´ve implemented the sample Code direct from Google using MediaRecorder
Also I have added some properties and set the filetype to ".mp3" (I know that it doesnt create a real mp3, but ".3gp" doesnt make sence to me either, I´m recording Audio not Video..)
Now my Problem is that, if I want to Play the file, it does nothing (0:00 sec). I checked the properties on the file, it fills up space on the storage.
ADDITIONAL:
Anyway I want to implement a visual Feedback while recording. Horizon seems to be the only good looking lib. But using Horizon you have to feed it with the buffer from Audiorecorder, which is not possible with MediaRecoder. Does anybody know a good looking lib that visualizes currently recording audio with MediaRecorder?
Thank you very much
private void startRecording() {
if(this.mRecorder != null)
return;
String fileToWrite = this.ProjectDirPath + File.separator + GetToday() + this.fileTpye;
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setOutputFile(fileToWrite);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC);
mRecorder.setAudioSamplingRate(16000);
mRecorder.setAudioEncodingBitRate(44100);
mRecorder.setAudioChannels(1);
try {
mRecorder.prepare();
}catch (IOException e) {
Log.e("startRecording()", "prepare() failed");
}
initRecorder();
mRecorder.start();
isRecording = true;
}
private void stopRecording() {
if(this.mRecorder == null)
return;
else{
try{
mRecorder.stop();
mRecorder.release();
mRecorder = null;
isRecording = false;
this.updateListView();
} catch(Exception e){
mRecorder = null;
isRecording = false;
}
}
}
public static String GetToday(){
Date presentTime_Date = Calendar.getInstance().getTime();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return dateFormat.format(presentTime_Date);
}
Permissions are set in the manifest and at runtime.
Finally found myself one good lib.
https://github.com/adrielcafe/AndroidAudioRecorder?utm_source=android-arsenal.com&utm_medium=referral&utm_campaign=4099

IllegalStateException when reusing MediaRecorder instance

Hey I'm trying to make MediaRecorder record the contents of my screen. It works when I'm making a recording for a first time but when I try to record the screen for a second time it fails. Here is relevant code:
void startRecording(String directory,String filename,MediaProjection mediaProjection) {
this.mediaProjection=mediaProjection;
this.directory=directory;
this.filename=filename;
initRecorder();
prepareRecorder();
virtualDisplay = createVirtualDisplay();
mediaRecorder.start();
}
void stopRecording() {
mediaRecorder.stop();
mediaRecorder.reset();
if (virtualDisplay != null) {
virtualDisplay.release();
}
if (mediaProjection != null) {
mediaProjection.stop();
mediaProjection = null;
}
initRecorder();
prepareRecorder();
}
void setScreen(int screenWidth, int screenHeight, int screenDensity) {
this.screenWidth = screenWidth;
this.screenHeight = screenHeight;
this.screenDensity = screenDensity;
}
void prepareRecorder() {
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
void initRecorder() {
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setVideoEncodingBitRate(512 * 1000);
mediaRecorder.setVideoFrameRate(30);
mediaRecorder.setVideoSize(screenWidth, screenHeight);
mediaRecorder.setOutputFile(directory + "/" + filename + ".mp4");
//mediaRecorder.setOutputFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).getAbsolutePath()+"/vitalij.mp4");
}
So in my activity I create a new instance of this class once then after pressing the button the startRecording method get's invoked. Then user can press stop recording which calls stopRecording method. When app is destroyed i release the mediaRecorder object.
This is the error I get:
Caused by: java.lang.IllegalStateException
at android.media.MediaRecorder.setAudioSource(Native Method)
at com.example.xxx.myapplication.VideoRecorder.initRecorder(VideoRecorder.java:77)
at com.example.xxx.myapplication.VideoRecorder.startRecording(VideoRecorder.java:30)
at com.example.xxx.myapplication.MainActivity.onActivityResult(MainActivity.java:134)
I'm sure that I have the correct permissions set and the first video gets created fine. The problem only occurs when making the recording for a second time.
The issue is that you're executing these two lines of code:
initRecorder();
prepareRecorder();
at the end of your stopRecording() function and again in your startRecording() function.
When you try to call mediaRecorder.setAudioSource in initRecorder() after the audio source has already been set, you get an IllegalStateException because it's in the incorrect state.
If you look at the state diagram on the Android MediaRecorder reference page, you'll see that a MediaRecorder must be in the Initial state to call setAudioSource(), but yours is in the Prepared state after stopRecording() has been called and you try to call setAudioSource() again.

IllegalStateException when MediaRecorder is recording: how to fix

I got this issue and cant get my head around it, im recording calls directly from the speaker, so when i get TelephonyManager.CALL_STATE_OFFHOOK I instantly start recording audio from VOICE_CALL. thats part its ok, start recording but if the call is ended and start a new one, I get a java.lang.IllegalStateException
I think this is because the first call it's still being recorded... I've tried to do:
mRecorder.stop();
mRecorder.release();
mRecorder.reset();
but no luck, they all gave me a illegalStateException, I just want to know how to stop first call recording and record a new one without errors.
Here's my code for recording and call handling,
//At least one call exists that is dialing, active, or on hold, and no calls are ringing or waiting.
if (state == TelephonyManager.CALL_STATE_OFFHOOK){
if (record_calls == 1){
record_enviroment();
}
}
//when Idle = No activity.
if (state == TelephonyManager.CALL_STATE_IDLE){
//Check for audio recorded and if exists post audio to server
}
public void record_enviroment(){
path = context.getFilesDir().getAbsolutePath() + "/";
try {
//Random number for file name
Random r = new Random( System.currentTimeMillis() );
i = 10000 + r.nextInt(20000);
// Save file local to app
mFileName = path + i + "_call_" + id_asociado + ".3gp";
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(mFileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e("AUDIO_RECORDER", "prepare() failed");
}
mRecorder.start();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Mediarecorder start failed -19

I am getting this error when running start() for mediarecorder.
06-28 18:46:22.570: E/MediaRecorder(9540): start failed: -19
06-28 18:46:22.570: W/System.err(9540): java.lang.RuntimeException: start failed.
I am extending mediarecorder class
My code:
camera = Camera.open(cameraId);
super.setCamera(camera);
super.setVideoSource(MediaRecorder.VideoSource.CAMERA);
super.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
if (mode==MODE_DEFAULT) {
super.setMaxDuration(1000);
super.setMaxFileSize(Integer.MAX_VALUE);
} else {
// On some phones a RuntimeException might be thrown :/
try {
super.setMaxDuration(0);
super.setMaxFileSize(Integer.MAX_VALUE);
} catch (RuntimeException e) {
Log.e(TAG,"setMaxDuration or setMaxFileSize failed !");
}
}
super.setVideoEncoder(videoEncoder);
if(surfaceHolder!=null)
super.setPreviewDisplay(surfaceHolder.getSurface());
//super.setVideoSize(quality.resX,quality.resY);
super.setVideoFrameRate(quality.frameRate);
super.setVideoEncodingBitRate(quality.bitRate);
I saw these pages
Error opening android camera for streaming video
Android MediaRecorder - "start failed: -19"
But non of them worked for me...
Running on archos 80 g9, android 3.2
Any one got any ideas?
Fixed by removing
super.setVideoFrameRate(quality.frameRate);
I was facing the same proble during video recording and i solved it by adding this for video recording
/**
* Start video recording by cleaning the old camera preview
*/
private void startVideoRecorder() {
// THIS IS NEEDED BECAUSE THE GLASS CURRENTLY THROWS AN ERROR OF
// "MediaRecorder start failed: -19"
// THIS WONT BE NEEDED INCASE OF PHONE AND TABLET
// This causes crash in glass kitkat version so remove it
// try {
// mCamera.setPreviewDisplay(null);
// } catch (java.io.IOException ioe) {
// Log.d(TAG,
// "IOException nullifying preview display: "
// + ioe.getMessage());
// }
// mCamera.stopPreview();
// mCamera.unlock();
recorder = new MediaRecorder();
// Let's initRecorder so we can record again
initRecorder();
}
/**
* Initialize video recorder to record video
*/
private void initRecorder() {
try {
File dir = new File(folderPath);
if (!dir.exists()) {
dir.mkdirs();
}
mCamera.stopPreview();
mCamera.unlock();
videofile = new File(dir, fileName + ".mp4");
recorder.setCamera(mCamera);
// Step 2: Set sources
recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
recorder.setProfile(CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH));
// Step 4: Set output file
recorder.setOutputFile(videofile.getAbsolutePath());
// Step 5: Set the preview output
recorder.setPreviewDisplay(mPreview.getHolder().getSurface());
// Step 6: Prepare configured MediaRecorder
recorder.setMaxDuration(video_duration * 1000);
recorder.setOnInfoListener(new OnInfoListener() {
#Override
public void onInfo(MediaRecorder mr, int what, int extra) {
if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
mCamera.stopPreview();
releaseMediaRecorder();
/*
* initiate media scan and put the new things into the
* path array to make the scanner aware of the location
* and the files you want to see
*/MediaScannerConnection.scanFile(
CuxtomCamActivity.this,
new String[] { videofile.getPath() }, null,
null);
Intent intent = new Intent();
intent.putExtra(CuxtomIntent.FILE_PATH,
videofile.getPath());
intent.putExtra(CuxtomIntent.FILE_TYPE, FILE_TYPE.VIDEO);
setResult(RESULT_OK, intent);
finish();
}
}
});
recorder.prepare();
recorder.start();
} catch (Exception e) {
Log.e("Error Stating CuXtom Camera", e.getMessage());
}
}
private void releaseMediaRecorder() {
if (recorder != null) {
recorder.reset(); // clear recorder configuration
recorder.release(); // release the recorder object
recorder = null;
}
}
To see detail of how a camera is actually implemented refer to Open Source Cuxtom Cam
I found a subtle hint in documentation for the MediaRecorder.start() method that suggest if it fails to lock() the Camera before attempting to re-record. This worked for me. Implies a Camera state bug was fixed post API level 13 - calling Camera.lock() is the known workaround.
This code worked for me (found here)
mCamera.unlock(); // maybe not for your activity flow
//1st. Initial state
mProfile = CamcorderProfile.get( CamcorderProfile.QUALITY_HIGH );
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera( mCamera );
//2nd. Initialized state
mMediaRecorder.setAudioSource( MediaRecorder.AudioSource.CAMCORDER );
mMediaRecorder.setVideoSource( MediaRecorder.VideoSource.CAMERA );
//3rd. config
mMediaRecorder.setOutputFormat( mProfile.fileFormat );
mMediaRecorder.setAudioEncoder( mProfile.audioCodec );
mMediaRecorder.setVideoEncoder( mProfile.videoCodec );
mMediaRecorder.setOutputFile( "/sdcard/FBVideo.3gp" );
mMediaRecorder.setVideoSize( mProfile.videoFrameWidth, mProfile.videoFrameHeight );
mMediaRecorder.setVideoFrameRate( mProfile.videoFrameRate );
mMediaRecorder.setVideoEncodingBitRate( mProfile.videoBitRate );
mMediaRecorder.setAudioEncodingBitRate( mProfile.audioBitRate );
mMediaRecorder.setAudioChannels( mProfile.audioChannels );
mMediaRecorder.setAudioSamplingRate( mProfile.audioSampleRate );
mMediaRecorder.setPreviewDisplay( mHolder.getSurface() );
try {
mMediaRecorder.prepare();
mMediaRecorder.start();
} catch ( IllegalStateException e ) {
e.printStackTrace();
} catch ( IOException e ) {
e.printStackTrace();
}
The problem here is about the camera. Just use camera.unlock() to allow the media process to access the camera.
This must be done before calling MediaRecorder.setCamera(Camera). This cannot be called after recording starts.
Read more here.

Categories

Resources