0

So, I want to be able to switch between the front and rear camera while the video is being recorded, and without any interruption in the video stream. I notice that even the iOS built-in camera app doesn't do this, but I've heard that some third-party apps do. Below is the sample code in xamarin.ios.

AVCaptureMovieFileOutput movieFileOutput;
AVCaptureDevice CurrentCamera { get; set; }
AVCaptureDevice BackCamera { get; set; }
AVCaptureDevice FrontCamera { get; set; }
AVCaptureDevice Mic { get; set; }
bool HasBackCamera { get { return BackCamera != null; } }
bool HasFrontCamera { get { return FrontCamera != null; } }
bool HasMic { get { return Mic != null; } }
void SetDeviceProperties()
{
//Set up the devices
foreach(var device in AVCaptureDevice.DevicesWithMediaType(AVMediaType.Video))
{
if(device.Position == AVCaptureDevicePosition.Back)
{
BackCamera = device;
}
else
{
FrontCamera = device;
}
}
Mic = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Audio);
}

public bool SwapCameras()
{
if(HasBackCamera && HasFrontCamera)
{
var nextCamera = CurrentCamera == BackCamera ? FrontCamera : BackCamera;
NSError error = null;
var newInput = new AVCaptureDeviceInput(nextCamera, out error);
if(error != null)
{
throw new Exception(error.ToString());
}
session.BeginConfiguration();
//Remove current video input
foreach(AVCaptureDeviceInput input in session.Inputs)
{
if(input.Device.HasMediaType(AVMediaType.Video))
{
session.RemoveInput(input);
}
}
if(session.CanAddInput(newInput))
{
session.AddInput(newInput);
}
session.CommitConfiguration();
CurrentCamera = nextCamera;
CameraConfigured(this, new TArgs<AVCaptureDevice>(CurrentCamera));
}
return CurrentCamera == FrontCamera;
}

Below is the configuration of the output of the video

var layer = new AVCaptureVideoPreviewLayer (session);
layer.VideoGravity = AVLayerVideoGravity.ResizeAspectFill;
var cameraView = new UIView ();
cameraView.Layer.AddSublayer (layer);
var filePath = Path.Combine (Path.GetTempPath (), "temporary.mov");
var fileUrl = NSUrl.FromFilename (filePath);
var movieFileOutput = new AVCaptureMovieFileOutput ();
var recordingDelegate = new MyRecordingDelegate ();
session.AddOutput (movieFileOutput);
movieFileOutput.StartRecordingToOutputFile (fileUrl, recordingDelegate);

Delegate that is called when the recording is stopped(from the removeInput of the first session):

public class MyRecordingDelegate : AVCaptureFileOutputRecordingDelegate
{
    public override void FinishedRecording (AVCaptureFileOutput captureOutput, NSUrl outputFileUrl, NSObject [] connections, NSError error)
    {
        if (UIVideo.IsCompatibleWithSavedPhotosAlbum (outputFileUrl.Path))
        {
            var library = new ALAssetsLibrary ();
            library.WriteVideoToSavedPhotosAlbum (outputFileUrl, (path, e2) =>
            {
                if (e2 != null)
                {
                    new UIAlertView ("Error", e2.ToString (), null, "OK", null).Show ();
                }
                else
                {
                    new UIAlertView ("Saved", "Saved to Photos", null, "OK", null).Show ();
                    File.Delete (outputFileUrl.Path);
                }
            });
        }
        else
        {
            new UIAlertView ("Incompatible", "Incompatible", null, "OK", null).Show ();
        }
}

}

So is this really possible and If so, how would I change the code above to not stop the recording while I switch the camera?

rambo
  • 21
  • 1
  • 7
  • Multi-cam recording was intro'd in iOS 13, only on "newer" hardware models and this includes some restrictions on certain camera combinations. It uses additions made to the AVFoundation framework, so your code while fine and still recommended (by Apple) for single cam use, would need to a lot of changes. I would recommend viewing the WWDC video first: https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/avmulticampip_capturing_from_multiple_cameras and then looking the docs and sample apps second: https://developer.apple.com/videos/play/wwdc2019/249/ – SushiHangover Sep 26 '20 at 21:05

1 Answers1

0

Once recording starts however, the swap camera icon disappears. There is no way to switch between cameras while video recording is in progress.

The video must be stopped, then the camera can be switched before restarting a new recording.

As a workaround , you could merge two video into single video file with audio . Here is a similar issue with native iOS , you could have a refer and convert the code to C# .

Lucas Zhang
  • 18,630
  • 3
  • 12
  • 22
  • Thanks for your answer, the url you sent was to merge a video with an audio but not one video with another(video from front camera and video from rear camera). I have tried a lot to find a solution about that but i cant find anything that can be done in xamarin ... – rambo Sep 27 '20 at 09:46
  • You need to pick them from photo library firstly . – Lucas Zhang Sep 29 '20 at 06:35