Использование android MediaRecorder

Ниже приведена структура моего рабочего кода для записи видео и аудио:

Вопросы: 1) Почему нужен CamcorderProfile? setProfile(...), как представляется, устанавливает размеры независимо от QUALITY_HIGH, но позже я устанавливаю размеры, которые я хочу, с помощью setVideoSize(...), который переопределяет это. Однако, когда я удаляю две строки CamcorderProfile, приложение падает с setVideoSize(...) с помощью LogCat E/MediaRecorder(19526): setVideoSize called in an invalid state: 2.

2) Как мне не записывать аудио? В документации указано, что если setAudioSource(...) не вызывается, звуковой дорожки не будет. Однако, когда я удаляю эту строку, приложение падает с setProfile(...) с помощью LogCat E/MediaRecorder(19946): try to set the audio encoder without setting the audio source first.

3) Если я удалю как строки CamcorderProfile, так и строку setAudioSource(...), он сработает, как в 1).

4) Я также попытался добавить строку

recorder.setOutputFormat(OutputFormat.DEFAULT);

вместо строк CamcorderProfile. Но теперь он падает с perpare(). Если setAudioSource(...) вызывается, то LogCat: E/MediaRecorder(20737): audio source is set, but audio encoder is not set, если он не называется LogCat: E/MediaRecorder(20544): video source is set, but video encoder is not set

Я просмотрел весь интернет, и я не могу найти хороший пример правильного способа настройки MediaRecorder. Здесь подразумевается, что после API 8 вы должны использовать класс CamcorderProfile, но мне кажется, что он вызывает проблемы.

Любая помощь будет замечательной! Спасибо!

Код (который работает, когда он выполняется ниже):

recorder = new MediaRecorder();
recorder.setCamera(<<camera>>);
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);

CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
recorder.setProfile(profile);

recorder.setOutputFile(<<Path String>>);
recorder.setVideoSize(<<Width>>, <<Height>>);

recorder.setPreviewDisplay(<<Surface>>);

recorder.setOrientationHint(0); 
recorder.setMaxDuration(10000);
recorder.setOnInfoListener(this);

try
{
    recorder.prepare();
    recorder.start();
} catch ...

Ответ 1

У меня нет большого опыта работы с MediaRecorder, но я читал некоторые связанные темы, и я постараюсь ответить на ваши вопросы:

1, 3 и 4) CamcorderProfile устанавливает не только разрешение, но и устанавливает формат вывода и кодировщики (как для аудио, так и для видео). Вы получаете ошибку, потому что вам, вероятно, нужно использовать setOutputFormat перед вызовом setVideoSize, и вам придется вызывать setVideoEncoder и setAudioEncoder после этого, если вы не хотите использовать CamcorderProfile. [В соответствии с этим answer]

2) Опять же, CamcorderProfile также устанавливает свойства звука (такие как Codec, BitRate, SampleRate,...), поэтому вам нужно установить источник звука перед его вызовом, поэтому приложение разбилось. Если вы не хотите записывать аудио, попробуйте следующий код: (я не тестировал его, поэтому я действительно не знаю, работает ли он, но я уверен, что он это делает)

recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setVideoSize(WIDTH, HEIGHT);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
recorder.setOutputFile(PATH);
recorder.setPreviewDisplay(SURFACE);

recorder.prepare();
recorder.start();

Также имейте в виду, что если вы не хотите использовать CamcorderProfile (это означает, что вы хотите записывать только аудио или видео), вам может потребоваться установить дополнительные параметры, чтобы убедиться, что у вас есть качество, которое вы хотите. Взгляните на следующий пример кода:

recorder = new MediaRecorder();
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);

// Following code does the same as getting a CamcorderProfile (but customizable)
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
// Video Settings 
recorder.setVideoSize(WIDTH, HEIGHT);
recorder.setVideoFrameRate(FRAME_RATE);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
recorder.setVideoEncodingBitRate(VIDEO_BITRATE);
// Audio Settings
recorder.setAudioChannels(AUDIO_CHANNELS);
recorder.setAudioSamplingRate(SAMPLE_RATE);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); 
recorder.setAudioEncodingBitRate(AUDIO_BITRATE);

// Customizable Settings such as:
//   recorder.setOutputFile(PATH);
//   recorder.setPreviewDisplay(SURFACE);
//   etc...

// Prepare and use the MediaRecorder
recorder.prepare();
recorder.start();
...
recorder.stop();
recorder.reset();
recorder.release();

Надеюсь, это поможет вам.