Emad Y
Emad Y

Reputation: 425

MediaRecorder skipping last few seconds

My problem is really simple: I'm using a MediaRecorder to record voice while the user is pressing on a FAB, and playing it afterwards (when he/she releases). The issue is that I lose a few seconds near the end of the recording, and I can't figure out why (they never get played back). Code (only relevant parts are shown):

Variables

double record_length = 0;
boolean recording = false;
String outputFile;
Handler myHandler = new Handler();
MediaRecorder recorder = new MediaRecorder();

OnTouchListener

        findViewById(R.id.record_record).setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                findViewById(R.id.delete_swipe).setVisibility(View.VISIBLE);
                StartRecord();
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                if(recording){
                    EndRecord();
                }
                findViewById(R.id.delete_swipe).setVisibility(View.INVISIBLE);

            }
            return true;
        }
    });

.

public void StartRecord() {
    recording = true;
    record_length = 0;
    SharedPreferences saved_login = getSharedPreferences("FalloundLogin", 0);

    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    recorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);

    //removed construction of outputFile, but it is generated correctly - I checked

    recorder.setOutputFile(outputFile);
    try {
        recorder.prepare();
        recorder.start();
    } catch (IOException e) {
        e.printStackTrace();
    }


    myHandler.postDelayed(UpdateUploadLength, 200);
}

.

public void EndRecord() {
    recording = false;

    try {
        recorder.stop();
        recorder.reset();
        recorder = null;
    } catch (IllegalStateException e) {
        e.printStackTrace();
    }

    MediaPlayer m = new MediaPlayer();

    try {
        m.setDataSource(outputFile);
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        m.prepare();
    } catch (IOException e) {
        e.printStackTrace();
    }

    m.start();


}

I need the recording to be a maximum of 27 seconds. To avoid complications, I tested without this extra termination condition and am including the Runnable just for completeness.

private Runnable UpdateUploadLength = new Runnable(){
    @Override
    public void run() {
        if(recording == true) {
            record_length += 0.2;
            if (record_length < 27) {
                myHandler.postDelayed(UpdateUploadLength, 200);
            } else {
                //TODO: stop recording
                myHandler.removeCallbacks(UpdateUploadLength);
            }
    }
};

I've been trying for a few hours with no luck, so any help is appreciated (also - and I dunno if it's bad to ask multiple questions in the same post - but is there any way to get better audio quality from MediaRecorder?)

Thanks in advance.

Upvotes: 0

Views: 433

Answers (1)

Sebastian Pakieła
Sebastian Pakieła

Reputation: 3029

Its answear for your second question. Yes you can have much better quality. There is more encoding types, file formats and parameters in library. Example:

mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mediaRecorder.setAudioSamplingRate(44100);
mediaRecorder.setAudioEncodingBitRate(256000);

this code will set your recorder to m4a files with AAC, 44,1kHz sampling rate and around 256kbps

Upvotes: 1

Related Questions