Forum Xamarin.Android

Announcement:

The Xamarin Forums have officially moved to the new Microsoft Q&A experience. Microsoft Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

To create new threads and ask questions head over to Microsoft Q&A for .NET and get involved today.

Preview and record video

marlonfalmarlonfal Member ✭✭
edited August 2020 in Xamarin.Android

Good morning.

Does anyone have an example of how to record a video using this code .

Thank you.

I've tried using Media Recorder, it doesn't fail at start recording but fails when I stop recording.

The error only says: Java.Lang.RuntimeException: stop failed.

The code I Added in CameraDroid.cs

public MediaRecorder mediaRecorder;
public EventHandler<File> Video;
public Size videoSize;
private bool isRecordingVideo;

// this method is already on the example
public void OpenCamera(int width, int height)
{
    if (_context == null || OpeningCamera)
    {
        return;
    }

    OpeningCamera = true;

    SetUpCameraOutputs(width, height);

    // I added this lines
    CameraCharacteristics characteristics = _manager.GetCameraCharacteristics(_cameraId);
    StreamConfigurationMap map = (StreamConfigurationMap)characteristics.Get(CameraCharacteristics.ScalerStreamConfigurationMap);
    videoSize = ChooseVideoSize(map.GetOutputSizes(Class.FromType(typeof(MediaRecorder))));
    mediaRecorder = new MediaRecorder();
    _manager.OpenCamera(_cameraId, _cameraStateListener, null);
}

private void SetUpMediaRecorder()
{
    mediaRecorder.SetAudioSource(AudioSource.Mic);
    mediaRecorder.SetVideoSource(VideoSource.Surface);
    mediaRecorder.SetOutputFormat(OutputFormat.Default);

    //mediaRecorder.SetMaxDuration(15000);
    mediaRecorder.SetOutputFile(GetOutputMediaFilePath());

    //mediaRecorder.SetVideoEncodingBitRate(10000000);
    //mediaRecorder.SetVideoFrameRate(30);
    mediaRecorder.SetVideoSize(videoSize.Width, videoSize.Height);
    mediaRecorder.SetVideoEncoder(VideoEncoder.Default);
    mediaRecorder.SetAudioEncoder(AudioEncoder.Default);
    //mediaRecorder.SetOrientationHint(180);
}
private Size ChooseVideoSize(Size[] choices)
{
    foreach (Size size in choices)
    {
        if (size.Width == size.Height * 4 / 3 && size.Width <= 1000)
            return size;
    }
    Log.Error("Video cámera", "Couldn't find any suitable video size");
    return choices[^1];
}

public void StartStopRecording()
{
    if (isRecordingVideo)
        StopRecordingVideo();
    else
    {
        StartRecordingVideo();
    }
}

public void StartRecordingVideo()
{
    try
    {
        SetUpMediaRecorder();
        mediaRecorder.Prepare();
        //Start recording
        mediaRecorder.Start();
        isRecordingVideo = true;
    }
    catch (System.Exception ex)
    {

    }
}

public void StopRecordingVideo()
{
    try
    {
        isRecordingVideo = false;
        mediaRecorder.Stop();
        //Video.Invoke(this, videoFile);
    }
    catch (System.Exception ex)
    {

    }
}

private static string GetOutputMediaFilePath()
{
    var mediaStorageDir = new File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures), "SampleCameraApp");
    if (!mediaStorageDir.Exists())
    {
        if (!mediaStorageDir.Mkdirs()) return null;
    }
    return System.IO.Path.Combine(mediaStorageDir.Path, System.String.Format("VID_{0}.mp4", Guid.NewGuid()));
}

Answers

  • jezhjezh Member, Xamarin Team Xamurai

    For this ,you can check the Microsoft's sample : Xamarin.Android - Camera2Video which demonstrates how record video on Android L through the use of the Android.Hardware.Camera2 namespace.

    The main code is as follows:
    PreviewCaptureStateCallback.cs

    public class PreviewCaptureStateCallback: CameraCaptureSession.StateCallback
    {
        Camera2VideoFragment fragment;
        public PreviewCaptureStateCallback(Camera2VideoFragment frag)
        {
            fragment = frag;
        }
        public override void OnConfigured (CameraCaptureSession session)
        {
            fragment.previewSession = session;
            fragment.updatePreview ();
    
        }
    
        public override void OnConfigureFailed (CameraCaptureSession session)
        {
            if (null != fragment.Activity) 
                Toast.MakeText (fragment.Activity, "Failed", ToastLength.Short).Show ();
        }
    }
    

    MySurfaceTextureListener.cs

    public class MySurfaceTextureListener: Java.Lang.Object,TextureView.ISurfaceTextureListener
    {
        Camera2VideoFragment fragment;
        public MySurfaceTextureListener(Camera2VideoFragment frag)
        {
            fragment = frag;
        }
    
        public void OnSurfaceTextureAvailable(SurfaceTexture surface_texture,int width, int height)
        {
            fragment.openCamera (width,height);
        }
    
        public void OnSurfaceTextureSizeChanged(SurfaceTexture surface_texture, int width, int height)
        {
            fragment.configureTransform (width, height);
        }
    
        public bool OnSurfaceTextureDestroyed(SurfaceTexture surface_texture)
        {
            return true;
        }
    
        public void OnSurfaceTextureUpdated(SurfaceTexture surface_texture)
        {
        }
    }
    

    MyCameraStateCallback .cs

    public class MyCameraStateCallback : CameraDevice.StateCallback
    {
        Camera2VideoFragment fragment;
        public MyCameraStateCallback(Camera2VideoFragment frag)
        {
            fragment = frag;
        }
        public override void OnOpened (CameraDevice camera)
        {
            fragment.cameraDevice = camera;
            fragment.startPreview ();
            fragment.cameraOpenCloseLock.Release ();
            if (null != fragment.textureView) 
                fragment.configureTransform (fragment.textureView.Width, fragment.textureView.Height);
        }
    
        public override void OnDisconnected (CameraDevice camera)
        {
            fragment.cameraOpenCloseLock.Release ();
            camera.Close ();
            fragment.cameraDevice = null;
        }
    
        public override void OnError (CameraDevice camera, CameraError error)
        {
            fragment.cameraOpenCloseLock.Release ();
            camera.Close ();
            fragment.cameraDevice = null;
            if (null != fragment.Activity) 
                fragment.Activity.Finish ();
        }
    }
    

    Notes
    This sample is known to crash on various device and Lollipop version combinations. See https://github.com/googlesamples/android-Camera2Video/issues/2 for more info.

  • marlonfalmarlonfal Member ✭✭

    Good morning, Jezh.

    I saw that example, but it is using Xamarin.Android, I need one that uses Xamarin.Forms, that's why I linked that example.

    Thank you.

  • jezhjezh Member, Xamarin Team Xamurai

    I need one that uses Xamarin.Forms

    For this, you can check : https://github.com/jamesmontemagno/MediaPlugin,

    which is a simple cross platform plugin to take photos and video or pick them from a gallery from shared code.

  • marlonfalmarlonfal Member ✭✭

    Is there a way to achieve something like this using MediaPlugin?

    I already use this example to take pictures, that's why I want to know how do I record video using that example.

Sign In or Register to comment.