2015-04-24 8 views
1

Я хочу захватить 5 секунд аудио и сохранить его, используя android.media.MediaRecorder. Один из подходов состоял бы в том, чтобы позвонить start() и запланировать stop() для вызова с android.os.Handler, но я не уверен, что это было бы очень точно.Как я могу безопасно использовать MediaRecorder для записи определенной продолжительности медиа?

MediaRecorder имеет setMaxDuration способ, который выглядит надежно. Он будет посылать сообщение в android.media.MediaRecorder.OnInfoListener раз таймер, но документы говорят:

Останов происходит асинхронно, нет никакой гарантии, что рекордер будет остановлен во время слушатель уведомлена.

Я считаю, что нужно вызвать release() на MediaRecorder, когда я сделал, так что мне нужно знать, когда это безопасно сделать так.

Итак:

  • максимальная продолжительность не упоминается в state transition diagram. Нужно ли звонить stop()?
  • Я правильно понял, что рекордер сохранит звук и сбросит файл, когда максимальная продолжительность будет достигнута? Промывка/завершение работы файла не упоминается в документах.
  • действительно ли нужно позвонить release() после того, как я не буду повторно использовать объект MediaRecorder?
  • Должен ли я предположить, что небезопасно звонить release() как часть OnInfoListener из-за асинхронности?
  • если да, то как мне это сделать? Установите еще один таймер?

ответ

2

Как вы упомянули, метод setMaxDuration выглядит многообещающим, хотя факт, что остановка захвата происходит асинхронно, оставляет некоторые предположения относительно фактической производительности. Возможно, стоит проверить этот метод и посмотреть, сколько желаемого времени захвата отличается от фактического времени захвата. В качестве побочного примечания при использовании этого метода не следует звонить stop(). Кроме того, поскольку setMaxDuration по существу является только запланированным звонком до stop(), я думаю, что можно с уверенностью предположить, что он также будет обрабатывать промывку/завершение.

Если вы обнаружите, что этот метод слишком неточен, чтобы быть полезным, вы можете использовать простой CountDownTimer, чтобы запланировать интервал записи. Этот класс хорош, потому что тик синхронизирован, что означает, что ваши интервалы времени будут точными в течение нескольких миллисекунд; гораздо точнее, чем пытаться запланировать Handler. Вы можете попробовать что-то вроде следующего:

new CountDownTimer(5000, 1000) { 
    public void onTick(long millisUntilFinished) { 
    } 

    public void onFinish() { 
     mediaRecorder.stop(); 
     mediaRecorder.release(); 
    } 
} 
.start(); 

В приведенном выше примере в расписание 5s CountDownTimer с 1s клещей. По истечении 5 секунд будут вызываться stop() и release(). Если вы хотите сделать его еще более точным, вы можете добавить простой счетчик внутри метода onTick(), а затем поместить все свои звонки MediaRecorder. Например, если вы должны были установить CountDownTimer в 7 секунд, все еще с 1 секундой, то при первом тике вы должны позвонить start(), предположив, что вы уже подготовили запись; затем, пять тиков позже, вы могли бы позвонить stop() и release().Это было бы весьма точным, так как в соответствии с CountDownTimer API:

звонки в onTick(long) синхронизированы с этим объектом

В относительно вызова release(), рекомендуется вызвать этот метод, даже если вы не планируйте повторное использование объекта. За документации API, в противном случай, чтобы освободить экземпляр MediaRecorder может привести к утечке ресурсов/батарей:

В дополнении к ненужным ресурсам (например, памяти и экземпляры кодеков), который держат, отказ вызвать этот метод немедленно, если a Объект MediaRecorder больше не нужен, также может привести к непрерывному расходу батареи для мобильных устройств и сбою записи для других приложений, если не существует нескольких экземпляров одного и того же кодека , поддерживаемых на устройстве.

+0

Большое спасибо! Я попробую. Любые идеи о безопасности выпуска на асинхронный обратный вызов? – Joe

+0

Хотя это асинхронно, я считаю, что до тех пор, пока вы не вызываете 'stop()', прежде чем вы вызовете 'release()', вы должны быть в порядке. – Willis

+0

Но разве не весь вопрос об асинхронном событии, который он называет 'stop()' сам, и я не знаю, случится ли это до обратного вызова? – Joe