Reputation: 47659
I want to capture 5 seconds of audio and save it using android.media.MediaRecorder
. One approach would be to call start()
and schedule stop()
to be called with a android.os.Handler
, but I'm not sure that would be very precise.
MediaRecorder
has a setMaxDuration
method which looks hopeful. It will send a message to the android.media.MediaRecorder.OnInfoListener
once the timer is up, but the docs say:
Stopping happens asynchronously, there is no guarantee that the recorder will have stopped by the time the listener is notified.
I believe I need to call release()
on the MediaRecorder
when I'm done, so I need to know when it's safe to do so.
So:
stop()
?release()
after if I'm not reusing the MediaRecorder
object?release()
as part of the OnInfoListener
because of the asynchrony?Upvotes: 2
Views: 2103
Reputation: 5336
As you mentioned, the setMaxDuration
method looks promising, although the fact that stopping capture occurs asynchronously leaves some speculation as to the actual performance. It might be worthwhile to test this method out and see how much the desired capture time differs from the actual capture time. As a side note, it should not be necessary to call stop()
when using this method. Also, since setMaxDuration
is essentially just a scheduled call to stop()
, I think it is safe to assume that it will also handle the flushing/finalizing.
If you discover that this method is too inaccurate to be useful then you could use a simple CountDownTimer
to schedule your recording interval. This class is nice because the tick is synchronized, which means that your timing intervals will be accurate to within a few milliseconds; much more accurate than trying to schedule a Handler
. You could try something like the following:
new CountDownTimer(5000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
mediaRecorder.stop();
mediaRecorder.release();
}
}
.start();
The above example schedules a 5s CountDownTimer
with 1s ticks. When the 5 seconds has elapsed, stop()
and release()
will be called, respectively. If you wanted to make it even more accurate you could add a simple counter inside of the onTick()
method and then place all of your MediaRecorder
calls in there. For example, if you were to set the CountDownTimer
to 7 seconds, still with 1 second ticks, then on the first tick you would call start()
, assuming you have already prepared the recording; then, five ticks later you would call stop()
and release()
. This would be quite accurate since, according to the CountDownTimer
API:
the calls to
onTick(long)
are synchronized to this object
In regards to calling release()
, it is recommended to call this method even if you do not plan on reusing the object. Per the API documentation, failing to release the MediaRecorder
instance could cause a resource/battery drain:
In addition to unnecessary resources (such as memory and instances of codecs) being held, failure to call this method immediately if a MediaRecorder object is no longer needed may also lead to continuous battery consumption for mobile devices, and recording failure for other applications if no multiple instances of the same codec are supported on a device.
Upvotes: 3