Reputation: 42205
I'm trying to modify the sample code linked to here, which will record video with Xamarin: http://developer.xamarin.com/recipes/android/media/video/record_video/
Specifically, I'm trying to set the video size, so I've modified the StartRecorder
method to specify a supported video size:
private void StartRecorder()
{
try
{
_video.StopPlayback();
recorder = new MediaRecorder();
recorder.SetVideoSource(VideoSource.Camera);
recorder.SetAudioSource(AudioSource.Mic);
recorder.SetOutputFormat(OutputFormat.Default);
// get suppored video sizes
var camera = Android.Hardware.Camera.Open();
var cameraParameters = camera.GetParameters();
var supportedSizes = cameraParameters.SupportedVideoSizes;
// set video size to a suppored size
// comment this out and it works
recorder.SetVideoSize(supportedSizes[0].Width, supportedSizes[0].Height);
recorder.SetVideoEncoder(VideoEncoder.Default);
recorder.SetAudioEncoder(AudioEncoder.Default);
recorder.SetOutputFile(_path);
recorder.SetPreviewDisplay(_video.Holder.Surface);
recorder.Prepare();
recorder.Start(); // fails with IllegalStateException
}
catch (Exception ex)
{
// IllegalStateException thrown
// error message is "start failed"
}
}
According to the API specification I think I'm using it correctly, but I can't see why I'm unable to set the video size.
Am I doing this wrong? Is there anything I'm missing? Should I be doing this differently?
Upvotes: 1
Views: 921
Reputation: 21
In addition to the fact that you missed "recorder.SetCamera(camera);"
From the explanation in CameraParameters.h
setVideoSize must not be called if getSupportedVideoSizes() returns empty vector of Size.
Even though getSupportedVideoSizes() retrieves a Vector of supported video size, it can return an empty vector when the camera only has a single output size.
So, you should check it first whether supportedPreviewSizes is empty or not and if it is empty, you must not call SetVideoSize().
Upvotes: 0
Reputation: 26
The following code works on my device (galaxy S5):
var camera = Android.Hardware.Camera.Open();
var cameraParameters = camera.GetParameters();
var supportedSizes = cameraParameters.SupportedVideoSizes;
var supportedPreviewSizes = cameraParameters.SupportedPreviewSizes;
camera.SetPreviewDisplay(video.Holder);
camera.StartPreview();
camera.Unlock();
recorder = new MediaRecorder();
recorder.SetCamera(camera);
recorder.SetVideoSource(VideoSource.Camera);
recorder.SetAudioSource(AudioSource.Camcorder);
recorder.SetOutputFormat(OutputFormat.Mpeg4);
recorder.SetVideoSize(supportedSizes[0].Width, supportedSizes[0].Height);
recorder.SetVideoEncoder(VideoEncoder.Mpeg4Sp);
recorder.SetAudioEncoder(AudioEncoder.AmrNb);
recorder.SetPreviewDisplay(video.Holder.Surface);
recorder.SetOutputFile(path);
recorder.Prepare();
recorder.Start();
There's some information on the call order here: http://developer.android.com/guide/topics/media/camera.html#capture-video
It does say that Unlock is not longer require on Android 4, so i'm not sure if all calls in this sample are actually required. It is important to call SetVideoSize before SetVideoEncoder, it is not explicitly mentioned on the API documentation page you linked though - your sample code already does that anyway :).
I guess the most notable line that is missing from your code is:
recorder.SetCamera(camera);
Upvotes: 1