MediaRecorder реализует setOnInfoListener -max длительность

Я использую mediarecorder для записи звука через микрофон. Я установил максимальную продолжительность на 20 секунд. Запись останавливается автоматически и не останавливается в моей точке останова внутри setOnInfoListener.

**UPDATE: Changed my code according to suggestion but still doesnt stop at the breakpoint inside the listener.**

mRecorder.reset();
mRecorder.setOnInfoListener(new OnInfoListener() {
    @Override
    public void onInfo(MediaRecorder mr, int what, int extra) {                     
        if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
            mRecorder.stop();

        }          
    }
});
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setAudioSamplingRate(8000);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOutputFile(fileName);
mRecorder.setMaxDuration(20000);
try {
    mRecorder.prepare();
} catch(IOException exception) {
    mRecorder.reset();
    mRecorder.release();
    mRecorder = null;
    return;
}
mRecorder.start();

Может кто-нибудь сказать мне, почему код не попадает в мой метод onInfo внутри слушателя, а молча останавливает запись.

Спасибо


person jsp    schedule 24.08.2011    source источник
comment
Большинство вызовов mRecorder должны быть размещены до prepare(), но после setOutputFormat(). Если вы посмотрите на диаграмму состояний для mediarecorder, вы поймете, о чем я говорю.   -  person JParrish88    schedule 06.02.2016


Ответы (4)


Когда вы устанавливаете выходной формат, попробуйте использовать THREE_GPP вместо RAW_AMR.

mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

Согласно документации для setOutputFormat():

It is recommended to always use 3GP format when using the
H.263 video encoder and AMR audio encoder. Using an MPEG-4
container format may confuse some desktop players.
person theisenp    schedule 25.08.2011
comment
Какое отношение это имеет к вопросу? - person Joe; 25.04.2015

Попробуйте переместить вызов на setOnInfoListener() перед звонком на prepare().

В моем собственном коде захвата видео я вызываю setOnInfoListener() сразу после создания объекта MediaRecorder. В вашем примере кода хорошее место может быть сразу после reset() и перед setAudioSource().

В противном случае тело вашего класса OnInfoListener выглядит правильно.

Я добавил код установки MediaRecorder из своего приложения, которое работает правильно.

try {
    mCamera.unlock();

    mMediaRecorder = new MediaRecorder();
    mMediaRecorder.setOnErrorListener( new VideoRecorderErrorListener() );
    mMediaRecorder.setOnInfoListener( new VideoRecorderInfoListener() );

    // As per Android API docs, the ordering of the following initialization
    // calls is important.
    mMediaRecorder.setCamera(mCamera);
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

    mMediaRecorder.setOutputFile( mOutputFilePath );

    mMediaRecorder.setMaxFileSize(VIDEO_MAX_FILE_SIZE);
    mMediaRecorder.setAudioChannels(AUDIO_CHANNELS);
    mMediaRecorder.setAudioSamplingRate(AUDIO_SAMPLING_RATE);
    mMediaRecorder.setAudioEncodingBitRate(AUDIO_ENCODING_BIT_RATE);
    mMediaRecorder.setMaxDuration(VIDEO_MAX_DURATION);
    mMediaRecorder.setVideoFrameRate(mPictureFPS);
    mMediaRecorder.setVideoEncodingBitRate(VIDEO_ENCODING_BIT_RATE);
    mMediaRecorder.setVideoSize(mPreviewWidth, mPreviewHeight);

    mMediaRecorder.setPreviewDisplay(mHolder.getSurface());

    mMediaRecorder.prepare();

    mMediaRecorder.start();
} catch (IllegalStateException e) {
person mportuesisf    schedule 24.08.2011
comment
это не имело никакого значения. я вызываю приведенный выше код в событии нажатия кнопки... должна ли логика быть частью потока или чего-то еще?? - person jsp; 25.08.2011
comment
Нет, я не использую поток для установки MediaRecorder, и у меня он работает нормально. Два отличия между вашим и моим: 1) Записываю видео+аудио. 2) Я определил слушателя как внутренний класс, а не как анонимный класс. Я не думаю, что любой из них будет иметь значение, хотя. Если у меня появится другая идея, я обязательно дам вам знать. - person mportuesisf; 25.08.2011
comment
Тем временем я добавил свой код установки MediaRecorder. Может быть, вы можете получить что-то из этого. Я знаю, что порядок, в котором вы делаете установочные вызовы MediaRecorder, ОЧЕНЬ, ОЧЕНЬ важен. - person mportuesisf; 25.08.2011
comment
См. приложения developer.android.com/reference/android/media/. необходимы для создания объектов MediaRecorder в потоках с запущенным Looper, без которого вы не можете получать информационные события - person LCoelho; 07.05.2014

как только он достигнет максимальной продолжительности, он вызовет (настраиваемый метод) stopRecording(): где мы можем обработать всю остановку записи и освобождение камеры проигрывателя и предварительный просмотр.

 myRecorder = new MediaRecorder();
 myRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
            @Override
            public void onInfo(MediaRecorder mr, int what, int extra) {
                if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
                    stopRecording();
                }
            }
        });
person Arpan Saini    schedule 06.02.2021

вы передали объект MediaRecorder mr в свой метод, но не использовали его. Попробуйте mr.stop();

person Ken Computers    schedule 26.09.2020
comment
Привет, @Ken, это не сайт для общения. Пожалуйста, будьте более внимательны к языку и форматированию ваших ответов. Красивое форматирование ответов облегчает чтение и увеличивает шансы быть полезными. - person Ashu; 26.09.2020